یکی از ویژگیهای CSS برای جدولها که اغلب نادیده گرفته میشود، اما میتواند بهطور چشمگیری کار شما را سادهتر کند:
##
این ویژگی تعیین میکند مرورگر چگونه ابعاد ستونها و سطرهای یک جدول را محاسبه کند.
###
با استفاده از این ویژگی، میتوان سرعت رندر جدول را افزایش داد و ظاهر آن را تحت کنترل قرار داد.
در حالت پیشفرض، مرورگر اندازهی ستونها را بر اساس محتوای درون آنها محاسبه میکند. این کار ممکن است مخصوصاً در جدولهای بزرگ، فرآیند رندر را کند کند.
اما با کمک
---
### مقادیر قابل استفاده برای
✔️
ابعاد ستونها بهصورت خودکار و بر اساس محتوای آنها تعیین میشود.
مناسب برای جدولهایی با محتوای پویا، اما ممکن است باعث کاهش سرعت رندر شود.
✔️
همهی ستونها دارای عرض ثابت خواهند بود، بدون توجه به محتوای داخلی آنها.
این گزینه رندر جدول را سریعتر کرده و کارایی را بهبود میبخشد، زیرا مرورگر از ابتدا از اندازههای تعیینشده استفاده میکند.
---
اگر جدول شما شامل دادههای زیادی است یا به ستونهایی با عرض یکسان نیاز دارید، استفاده از
🔗 [نمونه در CodePen](https://codepen.io/katrin_profrontend/pen/zxvKRPo)
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
##
table-layout
— کلیدی برای بهینهسازی جدولهااین ویژگی تعیین میکند مرورگر چگونه ابعاد ستونها و سطرهای یک جدول را محاسبه کند.
###
table-layout
دقیقاً چه میکند؟با استفاده از این ویژگی، میتوان سرعت رندر جدول را افزایش داد و ظاهر آن را تحت کنترل قرار داد.
در حالت پیشفرض، مرورگر اندازهی ستونها را بر اساس محتوای درون آنها محاسبه میکند. این کار ممکن است مخصوصاً در جدولهای بزرگ، فرآیند رندر را کند کند.
اما با کمک
table-layout
میتوان ابعاد ستونها را بهصورت ثابت تعیین کرد تا مرورگر دیگر نیازی به محاسبهی آنها نداشته باشد و از همان ابتدا، از اندازههای مشخصشده استفاده کند.---
### مقادیر قابل استفاده برای
table-layout
:✔️
auto
(مقدار پیشفرض):ابعاد ستونها بهصورت خودکار و بر اساس محتوای آنها تعیین میشود.
مناسب برای جدولهایی با محتوای پویا، اما ممکن است باعث کاهش سرعت رندر شود.
✔️
fixed
:همهی ستونها دارای عرض ثابت خواهند بود، بدون توجه به محتوای داخلی آنها.
این گزینه رندر جدول را سریعتر کرده و کارایی را بهبود میبخشد، زیرا مرورگر از ابتدا از اندازههای تعیینشده استفاده میکند.
---
اگر جدول شما شامل دادههای زیادی است یا به ستونهایی با عرض یکسان نیاز دارید، استفاده از
table-layout: fixed
بهترین انتخاب خواهد بود. 👍🔗 [نمونه در CodePen](https://codepen.io/katrin_profrontend/pen/zxvKRPo)
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
codepen.io
table-layout
...
❤3
### بهبود عملکرد رویدادهای پیمایش (Scroll) 👨🏫
بهتازگی با این هشدار مواجه شدم:
> "\[Violation] Added non-passive event listener to a scroll-blocking 'wheel' event. Consider marking event handler as 'passive' to make the page more responsive."
این پیام باعث شد رویکردم به مدیریت رویدادهای پیمایش را بازبینی کنم.
زمانی که با رویدادهایی مانند پیمایش با ماوس (
بهطور پیشفرض، مرورگرها میتوانند رفتار استاندارد (مانند پیمایش) را مسدود کنند، بهویژه اگر در تابع پردازشگر از
این مسأله ممکن است باعث تأخیر در واکنش رابط کاربری**، خصوصاً در دستگاههای همراه شود. 😔
---
### راهحل: استفاده از گزینهی `{ passive: true }` 🤨
با افزودن گزینهی `{ passive: true }` هنگام افزودن شنوندهی رویداد (Event Listener)، به مرورگر اطلاع میدهیم که قرار نیست رفتار پیشفرض را لغو کنیم.
در نتیجه، مرورگر میتواند بلافاصله اقدام به انجام رفتار استاندارد (مثل پیمایش) کند و منتظر اجرای کامل کد شما نماند.
```javascript
element.addEventListener('wheel', (event) => {
// کد مربوطه
}, { passive: true });
```
---
### چرا این موضوع اهمیت دارد؟
✔️ **افزایش سرعت واکنش رویدادها
مرورگر بلافاصله پیمایش را آغاز میکند و این باعث بهبود پاسخگویی رابط کاربری میشود — خصوصاً در تلفنهای هوشمند و تبلتها.
✔️ عدم انسداد رندر شدن صفحه
با استفاده از
---
### چند نکتهی مهم:
۱️⃣ مقدار پیشفرض `passive` برابر با false است
یعنی در حالت عادی میتوان از
اما مرورگرها در مورد برخی رویدادها مانند
۲️⃣ اگر شما `passive: true` را صراحتاً تعیین کنید و در تابع مربوطه از
---
### جمعبندی:
استفاده از گزینهی
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
بهتازگی با این هشدار مواجه شدم:
> "\[Violation] Added non-passive event listener to a scroll-blocking 'wheel' event. Consider marking event handler as 'passive' to make the page more responsive."
این پیام باعث شد رویکردم به مدیریت رویدادهای پیمایش را بازبینی کنم.
زمانی که با رویدادهایی مانند پیمایش با ماوس (
wheel
) یا حرکت لمسی (touchmove
) سروکار داریم، معمولاً چالشهایی در زمینهی عملکرد (Performance) به وجود میآید.بهطور پیشفرض، مرورگرها میتوانند رفتار استاندارد (مانند پیمایش) را مسدود کنند، بهویژه اگر در تابع پردازشگر از
event.preventDefault()
استفاده شود.این مسأله ممکن است باعث تأخیر در واکنش رابط کاربری**، خصوصاً در دستگاههای همراه شود. 😔
---
### راهحل: استفاده از گزینهی `{ passive: true }` 🤨
با افزودن گزینهی `{ passive: true }` هنگام افزودن شنوندهی رویداد (Event Listener)، به مرورگر اطلاع میدهیم که قرار نیست رفتار پیشفرض را لغو کنیم.
در نتیجه، مرورگر میتواند بلافاصله اقدام به انجام رفتار استاندارد (مثل پیمایش) کند و منتظر اجرای کامل کد شما نماند.
```javascript
element.addEventListener('wheel', (event) => {
// کد مربوطه
}, { passive: true });
```
---
### چرا این موضوع اهمیت دارد؟
✔️ **افزایش سرعت واکنش رویدادها
مرورگر بلافاصله پیمایش را آغاز میکند و این باعث بهبود پاسخگویی رابط کاربری میشود — خصوصاً در تلفنهای هوشمند و تبلتها.
✔️ عدم انسداد رندر شدن صفحه
با استفاده از
{ passive: true }
مرورگر دیگر منتظر اجرای کامل تابع پردازشگر نمیماند، که این موضوع باعث کاهش تأخیر و افزایش روانی حرکت صفحه میشود.---
### چند نکتهی مهم:
۱️⃣ مقدار پیشفرض `passive` برابر با false است
یعنی در حالت عادی میتوان از
event.preventDefault()
برای لغو رفتار پیشفرض استفاده کرد.اما مرورگرها در مورد برخی رویدادها مانند
wheel`، `touchmove
و touchstart
در سطوحی مثل window`، `document
و `document.body`، بهصورت خودکار passive را برابر با true قرار میدهند تا از ایجاد تاخیر جلوگیری شود.۲️⃣ اگر شما `passive: true` را صراحتاً تعیین کنید و در تابع مربوطه از
event.preventDefault()
استفاده نمایید، مرورگر این دستور را نادیده خواهد گرفت.---
### جمعبندی:
استفاده از گزینهی
{ passive: true }
یک تغییر ساده اما مؤثر برای بهبود روانی و واکنشپذیری اپلیکیشن است — بهویژه در سناریوهایی که با پیمایش و تعامل لمسی سروکار داریم. ✅#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
🔥1
استفاده از await در سطح بالای ماژولهای ES
نوشتن کدهای ناهمگام (asynchronous) در جاوااسکریپت تا چندی پیش یک محدودیت مهم داشت: کلیدواژهی await تنها درون یک تابع async قابل استفاده بود. این موضوع با معرفی ویژگی Top-Level Await در استاندارد ES2022 تغییر کرد؛ قابلیتی مدرن در ماژولهای ES که امکان اجرای الگوهای جدیدی از کد ناهمگام را در سطح ماژول فراهم میکند.
Top-Level Await چیست؟
بهطور سنتی، دستور await تنها درون توابع async معتبر بود:
اکنون با استفاده از Top-Level Await، میتوانید آن را در سطح بالای ماژول ES اجرا کنید:
در گذشته برای استفاده از await در سطح بالا، ناچار بودید آن را درون یک تابع ناهمگام خوداجرا (IIFE) بپیچید:
با Top-Level Await میتوانید با چنین کدهای زائد خداحافظی کنید و منطق ناهمگام خود را بهصورت مستقیم در بالاترین سطح ماژول بنویسید؛ کدی سادهتر، خواناتر و تمیزتر.
⚠️ نکته مهم
Top-Level Await فقط در ماژولهای جاوااسکریپت پشتیبانی میشود، نه در CommonJS (یعنی require) و نه در تگهای <script> سنتی که فاقد ویژگی type="module" هستند (زیرا این حالت در «مد کلاسیک» اجرا میشود). همچنین، فایلهای با پسوند .cjs در Node.js از آن پشتیبانی نمیکنند.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
نوشتن کدهای ناهمگام (asynchronous) در جاوااسکریپت تا چندی پیش یک محدودیت مهم داشت: کلیدواژهی await تنها درون یک تابع async قابل استفاده بود. این موضوع با معرفی ویژگی Top-Level Await در استاندارد ES2022 تغییر کرد؛ قابلیتی مدرن در ماژولهای ES که امکان اجرای الگوهای جدیدی از کد ناهمگام را در سطح ماژول فراهم میکند.
Top-Level Await چیست؟
بهطور سنتی، دستور await تنها درون توابع async معتبر بود:
// ❌ خطای نحوی (SyntaxError) در خارج از تابع async
const result = await fetchData();
اکنون با استفاده از Top-Level Await، میتوانید آن را در سطح بالای ماژول ES اجرا کنید:
// ✅ این کد در یک ماژول ES قابل اجرا است
const result = await fetchData();
در گذشته برای استفاده از await در سطح بالا، ناچار بودید آن را درون یک تابع ناهمگام خوداجرا (IIFE) بپیچید:
(async () => {
const result = await fetchData();
})();
با Top-Level Await میتوانید با چنین کدهای زائد خداحافظی کنید و منطق ناهمگام خود را بهصورت مستقیم در بالاترین سطح ماژول بنویسید؛ کدی سادهتر، خواناتر و تمیزتر.
⚠️ نکته مهم
Top-Level Await فقط در ماژولهای جاوااسکریپت پشتیبانی میشود، نه در CommonJS (یعنی require) و نه در تگهای <script> سنتی که فاقد ویژگی type="module" هستند (زیرا این حالت در «مد کلاسیک» اجرا میشود). همچنین، فایلهای با پسوند .cjs در Node.js از آن پشتیبانی نمیکنند.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
شکستن کلمات همراه با خط تیره 😉
موضوع ساده به نظر میرسد — وقتی یک کلمه طولانی در یک خط جا نمیشود، باید آن را با خط تیره به خط بعد منتقل کرد. اما چطور این کار را بهدرستی انجام دهیم تا هم ظاهر متن زیبا باشد و هم ساختار آن بههم نریزد؟
بیایید بررسی کنیم برای این کار در CSS چه نیاز داریم. ☺️
برای شکستن صحیح کلمات همراه با خط تیره، سه ویژگی اصلی مورد نیاز است:
✔️ overflow-wrap: break-word; — این ویژگی باعث میشود کلمات طولانی (مثل نشانیهای اینترنتی یا اصطلاحات پیچیده) در صورت کمبود فضا به خط بعد منتقل شوند.
✔️ word-break: break-word; — این ویژگی اجازه میدهد کلمات در نقاط مناسب نیز شکسته شوند، اگر در یک خط جا نشوند.
✔️ hyphens: auto; — مسئول اضافه کردن خودکار خط تیره هنگام شکستن کلمات است، بر اساس قواعد زبان مورد استفاده.
نمونه کد:
حالا همهچیز طبق قواعد زبان کار خواهد کرد: کلمات همراه با خط تیره شکسته میشوند و در عین حال متن، منظم و زیبا باقی میماند. 👍
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
موضوع ساده به نظر میرسد — وقتی یک کلمه طولانی در یک خط جا نمیشود، باید آن را با خط تیره به خط بعد منتقل کرد. اما چطور این کار را بهدرستی انجام دهیم تا هم ظاهر متن زیبا باشد و هم ساختار آن بههم نریزد؟
بیایید بررسی کنیم برای این کار در CSS چه نیاز داریم. ☺️
برای شکستن صحیح کلمات همراه با خط تیره، سه ویژگی اصلی مورد نیاز است:
✔️ overflow-wrap: break-word; — این ویژگی باعث میشود کلمات طولانی (مثل نشانیهای اینترنتی یا اصطلاحات پیچیده) در صورت کمبود فضا به خط بعد منتقل شوند.
✔️ word-break: break-word; — این ویژگی اجازه میدهد کلمات در نقاط مناسب نیز شکسته شوند، اگر در یک خط جا نشوند.
✔️ hyphens: auto; — مسئول اضافه کردن خودکار خط تیره هنگام شکستن کلمات است، بر اساس قواعد زبان مورد استفاده.
نمونه کد:
.text {
overflow-wrap: break-word; /* اجازه شکستن کلمات طولانی */
word-break: break-word; /* شکستن کلمات در نقاط مناسب */
hyphens: auto; /* افزودن خودکار خط تیره هنگام شکستن */
}
حالا همهچیز طبق قواعد زبان کار خواهد کرد: کلمات همراه با خط تیره شکسته میشوند و در عین حال متن، منظم و زیبا باقی میماند. 👍
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
یادآوری دربارهی `.setProperty()` و متغیرهای CSS 😉
همهی ما متد `.setProperty()` میشناسیم و معمولاً زمانی به یادش میافتیم که لازم باشد یک ویژگی CSS را مستقیماً از طریق JavaScript تغییر دهیم.
اما بهراحتی میتوان فراموش کرد که با همین متد میتوان متغیرهای CSS را نیز تغییر داد — و این در بسیاری موارد بسیار کارآمدتر است.
برای نمونه، یک متغیر سراسری در `:root`:
و در JavaScript:
اکنون تمام عناصری که مقدار
کجا استفاده از متغیرها از طریق `.setProperty()` بیشتر به چشم میآید؟
✔️ انیمیشنها — تنها با تغییر یک متغیر، تمام استایلهای مرتبط بهصورت روان و از طریق CSS transition بهروز میشوند.
✔️ استفاده در content — میتوان متن یا نمادی را در یک متغیر ذخیره کرد و آن را بهصورت پویا تغییر داد.
در نتیجه، `.setProperty()` تنها برای تغییر ویژگیها نیست، بلکه ابزاری قدرتمند برای مدیریت متغیرهای CSS نیز بهشمار میرود ⚡️
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
همهی ما متد `.setProperty()` میشناسیم و معمولاً زمانی به یادش میافتیم که لازم باشد یک ویژگی CSS را مستقیماً از طریق JavaScript تغییر دهیم.
اما بهراحتی میتوان فراموش کرد که با همین متد میتوان متغیرهای CSS را نیز تغییر داد — و این در بسیاری موارد بسیار کارآمدتر است.
برای نمونه، یک متغیر سراسری در `:root`:
:root {
--main-color: #333;
}
و در JavaScript:
// تغییر خود متغیر، نه ویژگی مستقیم
document.documentElement.style.setProperty('--main-color', '#ff6600');
اکنون تمام عناصری که مقدار
color: var(--main-color)
دارند، بهطور خودکار مقدار جدید را دریافت میکنند. 👍کجا استفاده از متغیرها از طریق `.setProperty()` بیشتر به چشم میآید؟
✔️ انیمیشنها — تنها با تغییر یک متغیر، تمام استایلهای مرتبط بهصورت روان و از طریق CSS transition بهروز میشوند.
✔️ استفاده در content — میتوان متن یا نمادی را در یک متغیر ذخیره کرد و آن را بهصورت پویا تغییر داد.
.btn::after {
content: var(--btn-label);
}
btn.style.setProperty('--btn-label', '"✓"');
در نتیجه، `.setProperty()` تنها برای تغییر ویژگیها نیست، بلکه ابزاری قدرتمند برای مدیریت متغیرهای CSS نیز بهشمار میرود ⚡️
#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
👍1
من همیشه فکر میکردم توسعهی فرانتاند بهمراتب دشوارتر از بکاند است، اما توضیح این موضوع برای سایر توسعهدهندگان همیشه سخت بود. امروز خواستم نظر یک مدل زبانی (که بهنوعی نمایندهی «نظر کلی کارشناسان» است) را بررسی کنم.
نتیجه جالب بود:
توسعهی فرانتاند برای انسانها سختتر است، زیرا بکاند بیشتر ماهیتی ریاضی و مبتنی بر قواعد دارد و درک آن چندان دشوار نیست؛ همهچیز با فرمولها و الگوهای قابل پیشبینی پیش میرود.
اما فرانتاند؟ اینجا قیاس بینظیری مطرح شد: زیستشناسی!
🔹 مقیاسپذیری بکاند: شبیه ریاضیات؛ با افزودن نودهای بیشتر، شارد کردن پایگاه داده یا بهینهسازی کوئریها، سیستم طبق فرمولها و قوانین قابلپیشبینی رشد میکند.
🔹 تغییرات فرانتاند: شبیه زیستشناسی؛ جهشهای کوچک (مثل دستگاه جدید، ویژگی تازهی مرورگر یا نیاز متفاوت در تجربهی کاربری) رفتاری نوظهور، اغلب آشفته و موردی ایجاد میکنند که باید تکبهتک با آنها سازگار شد.
زیستشناسی بسیار پیچیدهتر از ریاضیات است — زیرا ریاضیات قانونمند و قطعی است، اما زیستشناسی پدیدهای نوظهور، پر از استثنا، وابسته به زمینه و همواره در حال تغییر.
به همین دلیل است که فرانتاند (شبیه زیستشناسی) برای انسانها بهمراتب شلوغتر و دشوارتر به نظر میرسد، حتی اگر بکاند (شبیه ریاضیات) از نظر انتزاعی ژرفتر باشد.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
نتیجه جالب بود:
توسعهی فرانتاند برای انسانها سختتر است، زیرا بکاند بیشتر ماهیتی ریاضی و مبتنی بر قواعد دارد و درک آن چندان دشوار نیست؛ همهچیز با فرمولها و الگوهای قابل پیشبینی پیش میرود.
اما فرانتاند؟ اینجا قیاس بینظیری مطرح شد: زیستشناسی!
🔹 مقیاسپذیری بکاند: شبیه ریاضیات؛ با افزودن نودهای بیشتر، شارد کردن پایگاه داده یا بهینهسازی کوئریها، سیستم طبق فرمولها و قوانین قابلپیشبینی رشد میکند.
🔹 تغییرات فرانتاند: شبیه زیستشناسی؛ جهشهای کوچک (مثل دستگاه جدید، ویژگی تازهی مرورگر یا نیاز متفاوت در تجربهی کاربری) رفتاری نوظهور، اغلب آشفته و موردی ایجاد میکنند که باید تکبهتک با آنها سازگار شد.
زیستشناسی بسیار پیچیدهتر از ریاضیات است — زیرا ریاضیات قانونمند و قطعی است، اما زیستشناسی پدیدهای نوظهور، پر از استثنا، وابسته به زمینه و همواره در حال تغییر.
به همین دلیل است که فرانتاند (شبیه زیستشناسی) برای انسانها بهمراتب شلوغتر و دشوارتر به نظر میرسد، حتی اگر بکاند (شبیه ریاضیات) از نظر انتزاعی ژرفتر باشد.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
🤔1
استفاده از `distinctUntilChanged` و `debounceTime`: بهینهسازی جستجو 👩💻
وقتی فرم ایجاد میکنیم، مهم است که از ارسال درخواستهای غیرضروری به سرور جلوگیری کنیم. دو اپراتور RxJS به نامهای `debounceTime` و `distinctUntilChanged` در این زمینه به ما کمک میکنند:
* ✔️
* ✔️
### مثال:
### عملکرد هر اپراتور:
⭐️
⭐️
---
✅ نتیجه: ترکیب این دو اپراتور به شما کمک میکند کنترل بهتری روی درخواستها در فرمهای جستجو داشته باشید، عملکرد را بهبود بخشید و بار روی سرور را کاهش دهید. 😉
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
وقتی فرم ایجاد میکنیم، مهم است که از ارسال درخواستهای غیرضروری به سرور جلوگیری کنیم. دو اپراتور RxJS به نامهای `debounceTime` و `distinctUntilChanged` در این زمینه به ما کمک میکنند:
* ✔️
debounceTime
اجرای عملیات را با تأخیر انجام میدهد.* ✔️
distinctUntilChanged
مقادیر تکراری را نادیده میگیرد.### مثال:
this.searchForm.controls.searchField.valueChanges
.pipe(
debounceTime(300), // صبر میکنیم ۳۰۰ میلیثانیه بعد از آخرین ورودی
distinctUntilChanged() // مقادیر تکراری را نادیده میگیریم
)
.subscribe(searchTerm => {
console.log('درخواست به سرور:', searchTerm);
this.searchData(searchTerm); // ارسال درخواست
});
### عملکرد هر اپراتور:
⭐️
debounceTime(300)
— ارسال درخواست را ۳۰۰ میلیثانیه بعد از آخرین ورودی به تأخیر میاندازد. این کار باعث میشود برای هر کاراکتر یک درخواست ارسال نشود، که مخصوصاً هنگام تایپ سریع بسیار مفید است.⭐️
distinctUntilChanged()
— تضمین میکند که درخواست تنها وقتی مقدار تغییر کند ارسال شود. اگر کاربر همان عبارت جستجو را دوباره وارد کند، درخواست تکراری ارسال نخواهد شد.---
✅ نتیجه: ترکیب این دو اپراتور به شما کمک میکند کنترل بهتری روی درخواستها در فرمهای جستجو داشته باشید، عملکرد را بهبود بخشید و بار روی سرور را کاهش دهید. 😉
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
نحوه تنظیم Autocomplete با گزینههای محدود، ولی با امکان وارد کردن مقادیر دلخواه در TypeScript ❓
اخیراً با یک چالش جالب مواجه شدم: میخواستم یک نوع (Type) بسازم که هم بتواند هر رشتهای را بپذیرد، و هم برای چند مقدار از پیش تعریفشده رفتاری خاص داشته باشد.
معمولاً این کار با
### راهکار: استفاده از
این تکنیک اجازه میدهد نوعی تعریف کنیم که انعطافپذیر باشد و همزمان در Autocomplete گزینههای مشخص را پیشنهاد دهد.
#### مثال:
### توضیح:
*
* با این حال، Autocomplete تنها
* دلیلش این است که ترکیب
---
✅ نتیجه: این روش برای مواقعی مناسب است که میخواهید انعطاف نوع را حفظ کنید و همزمان به راحتی بتوانید گزینههای از پیش تعریفشده را در Autocomplete نمایش دهید. 👍
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
اخیراً با یک چالش جالب مواجه شدم: میخواستم یک نوع (Type) بسازم که هم بتواند هر رشتهای را بپذیرد، و هم برای چند مقدار از پیش تعریفشده رفتاری خاص داشته باشد.
معمولاً این کار با
enum
یا اشیاء حل میشد، اما یک روش شیکتر هم وجود دارد! ❔### راهکار: استفاده از
string & {}
در انتهای Unionاین تکنیک اجازه میدهد نوعی تعریف کنیم که انعطافپذیر باشد و همزمان در Autocomplete گزینههای مشخص را پیشنهاد دهد.
#### مثال:
type MyType = 'Option1' | 'Option2' | string & {};
### توضیح:
*
MyType
میتواند هر رشتهای را بپذیرد.* با این حال، Autocomplete تنها
'Option1'
و 'Option2'
را پیشنهاد میدهد.* دلیلش این است که ترکیب
string & {}
امکان استفاده از رشتهها را حفظ میکند ولی پیشنهادها محدود به مقادیر مشخص شده در Union میماند.---
✅ نتیجه: این روش برای مواقعی مناسب است که میخواهید انعطاف نوع را حفظ کنید و همزمان به راحتی بتوانید گزینههای از پیش تعریفشده را در Autocomplete نمایش دهید. 👍
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
اختصارات منطقی در انتسابها در JavaScript 🤔
ECMAScript ۲۰۲۱ سه اپراتور مفید را اضافه کرده است:
✔️ انتساب
✔️ انتساب
✔️ انتساب
‼️ نکته مهم: چرا
به طور خلاصه: اپراتورهای اختصاری مقدار سمت چپ انتساب (LHS) را فقط یک بار محاسبه میکنند، در حالی که حالت
👩💻 مثال کمینه و قابل بازتولید:
➡️ در عبارت
نتیجه:
اپراتورهای
پیشنهاد استفاده:
⏺️
⏺️
⏺️
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
ECMAScript ۲۰۲۱ سه اپراتور مفید را اضافه کرده است:
✔️ انتساب
x ||= y
— اگر x
مقدار «فالس» داشته باشد → `x = y`؛✔️ انتساب
x ??= y
— اگر x
مقدار null
یا undefined
داشته باشد → x = y
(صفر، رشته خالی و false
حفظ میشوند)؛✔️ انتساب
x &&= y
— اگر x
مقدار «ترو» داشته باشد → x = y
.‼️ نکته مهم: چرا
x ||= y
و x = x || y
همیشه معادل هم نیستندبه طور خلاصه: اپراتورهای اختصاری مقدار سمت چپ انتساب (LHS) را فقط یک بار محاسبه میکنند، در حالی که حالت
x = x || y
ممکن است LHS را دو بار محاسبه کند. این مسئله زمانی مشکلساز میشود که LHS فقط یک متغیر ساده نباشد، بلکه یک عبارت شامل فراخوانیها، getterها یا کلیدهای محاسبهشده باشد.👩💻 مثال کمینه و قابل بازتولید:
let i = 0;
function getKey() { console.log('getKey'); return 'k' + (++i); }
const a = {};
a[getKey()] ||= 1; // getKey یک بار فراخوانی میشود — ایمن
i = 0;
const b = {};
b[getKey()] = b[getKey()] || 1; // getKey دو بار فراخوانی میشود — اثر جانبی!
➡️ در عبارت
b[...] = b[...] || 1`، `getKey()
ممکن است در فراخوانیهای مختلف کلیدهای متفاوت تولید کند یا اثرات جانبی دیگری داشته باشد — در نتیجه منطق برنامه خراب میشود. اما ||=
چنین خطری ندارد، چون ارجاع به b[getKey()]
فقط یک بار گرفته میشود.نتیجه:
اپراتورهای
||=
, ??=
و &&=
تنها «شیرینی سینتکسی» نیستند؛ بلکه روشی برای جلوگیری از باگهای پنهان هستند، به خصوص زمانی که LHS شامل عبارات با اثر جانبی است.پیشنهاد استفاده:
⏺️
??=
برای مقداردهی پیشفرض واقعی،⏺️
||=
برای زمانی که هر مقدار فالس مدنظر است،⏺️
&&=
برای بهروزرسانی شرطی. 👍#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
آشنایی با ویژگی rel در تگ <link> و تأثیر مقادیر آن بر رندر صفحه 🤨
تگ <link> برای اتصال منابع خارجی به سند HTML استفاده میشود.
ویژگی کلیدی این تگ، rel است که نوع ارتباط با منبع را مشخص میکند: این منابع میتوانند شامل استایلها، فونتها، آیکونها، مانیفستها و موارد دیگر باشند. نحوه پردازش این منابع توسط مرورگر کاملاً وابسته به مقدار این ویژگی است و همین موضوع به طور مستقیم بر رندر صفحه، سرعت بارگذاری و دسترسیپذیری آن تأثیر میگذارد. 👨🏫
در تصاویر بالا، من به تفصیل مقادیر اصلی ویژگی rel و تأثیر آنها بر عملکرد صفحه را بررسی کردهام. ⬆️
توصیههای کاربردی:
✔️ فونت و CSS های حیاتی را فوراً بارگذاری کنید (با stylesheet یا preload)؛
✔️ برای منابع از دامنههای دیگر از preconnect یا dns-prefetch استفاده کنید؛
✔️ منابع کماهمیتتر را میتوان به صورت غیرهمزمان بارگذاری کرد (prefetch).
نتیجهگیری:
استفاده از این تکنیکها به کاهش تاخیرها، کاهش اثر «پرش صفحه» (FOUC) و بهبود تجربه کاربری کمک میکند، بهویژه در دستگاههای موبایل.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
تگ <link> برای اتصال منابع خارجی به سند HTML استفاده میشود.
ویژگی کلیدی این تگ، rel است که نوع ارتباط با منبع را مشخص میکند: این منابع میتوانند شامل استایلها، فونتها، آیکونها، مانیفستها و موارد دیگر باشند. نحوه پردازش این منابع توسط مرورگر کاملاً وابسته به مقدار این ویژگی است و همین موضوع به طور مستقیم بر رندر صفحه، سرعت بارگذاری و دسترسیپذیری آن تأثیر میگذارد. 👨🏫
در تصاویر بالا، من به تفصیل مقادیر اصلی ویژگی rel و تأثیر آنها بر عملکرد صفحه را بررسی کردهام. ⬆️
توصیههای کاربردی:
✔️ فونت و CSS های حیاتی را فوراً بارگذاری کنید (با stylesheet یا preload)؛
✔️ برای منابع از دامنههای دیگر از preconnect یا dns-prefetch استفاده کنید؛
✔️ منابع کماهمیتتر را میتوان به صورت غیرهمزمان بارگذاری کرد (prefetch).
نتیجهگیری:
استفاده از این تکنیکها به کاهش تاخیرها، کاهش اثر «پرش صفحه» (FOUC) و بهبود تجربه کاربری کمک میکند، بهویژه در دستگاههای موبایل.
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript