جاوااسکریپت | JavaScript
519 subscribers
670 photos
144 videos
3 files
526 links
کانال @IR_javascript حاوی اطلاعات مفید در حوزه برنامه نویس فرانت که بصورت روزانه بروز می‌شود.
در این کانال شما به:
[1] مطالب تازه
[2] تحلیل‌های عمیق
[3] نکات آموزشی
[4] چالش
[5] ابزار و راهنمایی‌های کاربردی
دسترسی خواهید داشت.

🆔@IR_javascript
Download Telegram
بیایید با یک ویژگی جالب در CSS آشنا شویم: content-visibility 🤨

---

### content-visibility چیست؟

ویژگی content-visibility در CSS به مرورگر اعلام می‌کند که آیا محتوای یک عنصر باید در هنگام بارگذاری اولیه صفحه رندر شود یا خیر. به این ترتیب، زمانی که مرورگر در حال بارگذاری محتوا و نمایش آن بر روی صفحه است، این ویژگی به ما امکان می‌دهد مشخص کنیم که محتوای یک عنصر تنها در صورت نیاز بارگذاری شود. می‌توانید آن را مشابه بارگذاری تنبل (lazy loading) تصور کنید؛ به این معنا که محتوای فرزندان یک عنصر خارج از محدوده دید کاربر، تا زمانی که وارد ناحیه دید (viewport) نشوند، رندر نخواهند شد.

---

###چگونه کار می‌کند؟

وقتی یک عنصر مقدار content-visibility: auto داشته باشد، تا زمانی که وارد ناحیهٔ دید کاربر نشود رندر نمی‌شود. این کار باعث می‌شود مرورگر منابع را برای عناصر نامرئی هدر ندهد.

.element {
content-visibility: auto | hidden | visible;
}


‏hidden: عنصر محتوای خود را نادیده می‌گیرد (مشابه اعمال display: none; روی محتوا).
‏visible: بدون اثر خاص، و عنصر به‌طور معمول رندر می‌شود.
‏auto: عنصر شامل containment در لایه‌بندی، سبک (style) و رنگ‌آمیزی است. مرورگر تصمیم می‌گیرد که آیا این محتوا برای کاربر ضروری است یا نه؛ و در صورتی که ضروری نباشد، آن را نادیده می‌گیرد. با این حال، عنصر همچنان قابل فوکوس، انتخاب و دسترسی از طریق ابزارهایی مانند جابه‌جایی با کلید Tab یا جست‌وجو در صفحه خواهد بود.


اما تفاوت اینجاست که در content-visibility: hidden;، مرورگر وضعیت رندرشده عنصر را کش می‌کند. بنابراین زمانی که این قانون حذف شود، مرورگر نیازی به رندر مجدد از ابتدا ندارد. این ویژگی برای عناصری مناسب است که به‌طور پیش‌فرض پنهان هستند، اما احتمال بالایی وجود دارد که در طول چرخه حیات صفحه نمایش داده شوند (مانند یک مودال پرکاربرد). در این حالت، هنگام نمایش، عنصر بسیار سریع‌تر بارگذاری می‌شود.

در content-visibility: auto می‌توانید این مقدار را مشابه بارگذاری تنبل برای بخش‌های کامل DOM تصور کنید.
اگر عنصری خارج از دید کاربر (زیر خط fold) باشد و مقدار auto داشته باشد، مرورگر هیچ‌یک از محتوای آن را در نظر نمی‌گیرد و رندر آن را به تعویق می‌اندازد. هنگامی که کاربر به آن اسکرول کند، مرورگر محتوا را نقاشی می‌کند. زمان دقیق رندر به تصمیم مرورگر بستگی دارد.
---

### ارتباط با contain-intrinsic-size

این ویژگی معمولاً همراه با contain-intrinsic-size استفاده می‌شود.

🔹 مشکل: وقتی از content-visibility استفاده می‌کنیم، مرورگر ممکن است اندازهٔ دقیق عناصر پنهان را نداند و این می‌تواند موجب به‌هم‌ریختگی چیدمان شود.

🔹 راه‌حل: استفاده از contain-intrinsic-size که یک اندازهٔ حداقلی برای عنصر تعیین می‌کند؛ حتی اگر عنصر دیده نشود. این کار به مرورگر کمک می‌کند تا جای مناسب برای عنصر در چیدمان صفحه از پیش در نظر بگیرد.

مثال:

.image-gallery img {
content-visibility: auto;
contain-intrinsic-size: 200px; /* تعیین اندازهٔ حداقلی */
}


---

### مزایا

بارگذاری صفحه سریع‌تر انجام می‌شود.
فشار کمتری بر پردازنده و حافظه وارد می‌شود.
هنگام دیده شدن عناصر، رندر آن‌ها سریع‌تر انجام می‌شود، بدون اینکه قبلاً منابع برای عناصر نامرئی مصرف شده باشد.

---

### موارد استفاده

🔘 صفحات بلند با محتوای زیاد (مانند فیدهای خبری یا کاتالوگ محصولات).
🔘 محتوای پویا که در حین پیمایش ظاهر می‌شود.

---

### جمع‌بندی

استفاده از content-visibility روشی ساده برای سرعت بخشیدن به رندر صفحه است. همچنین اگر همراه با contain-intrinsic-size به‌کار رود، می‌توان از مشکلات چیدمان در هنگام پنهان بودن عناصر جلوگیری کرد. 👍


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍5
یک سرور HTTP نمی‌تواند به صورت خودکار یک اتصال به مرورگر برقرار کند؛ بنابراین همیشه مرورگر آغازگر ارتباط است. حالا برای دریافت به‌روزرسانی‌های لحظه‌ای از سرور HTTP چه باید کرد؟

دو رویکرد اصلی وجود دارد:

🔹 مرورگر بار اصلی را بر دوش می‌کشد:

* Polling کوتاه‌مدت (Short Polling): مرورگر به‌طور مکرر درخواست می‌فرستد تا زمانی که داده‌ی جدید را دریافت کند.
* Polling بلندمدت (Long Polling): سرور درخواست را باز نگه می‌دارد و تنها زمانی پاسخ می‌دهد که داده‌ی تازه آماده شود.

🔹 همکاری مرورگر و سرور:

* WebSocket: یک اتصال دائمی و دوسویه برقرار می‌شود. پس از آن، سرور می‌تواند هر زمان داده‌ی جدید را ارسال کند و مرورگر نیز می‌تواند درخواست‌های تازه بفرستد.
* SSE (Server-Sent Events): یک اتصال یک‌طرفه ایجاد می‌شود که در آن فقط سرور می‌تواند داده‌های جدید را برای مرورگر ارسال کند. مرورگر نمی‌تواند درخواست تازه‌ای از همان کانال به سرور بفرستد.

👉 در نتیجه، انتخاب میان این روش‌ها بستگی به نیاز برنامه دارد: اگر ارتباط دوطرفه نیاز باشد، WebSocket بهترین گزینه است؛ اگر کافی است فقط سرور داده‌ها را به‌طور خودکار به مرورگر بفرستد، SSE ساده‌تر و سبک‌تر است.




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
🔹 مقایسه toString() و String() 🤨

یکی از نیازهای رایج در برنامه‌نویسی، تبدیل داده‌ها به رشته است. برای این کار دو رویکرد اصلی وجود دارد: toString() و String(). هرچند عملکرد آن‌ها شبیه به هم است، اما یک تفاوت کلیدی میانشان وجود دارد. بیایید بررسی کنیم! 😁

---

### ۱️⃣ toString() — متد شیء

این متد یک شیء را به رشته تبدیل می‌کند، اما:

✔️ برای انواع اولیه (مانند عدد یا رشته) نمایش متنی آن‌ها را برمی‌گرداند؛
✔️ برای اشیاء (مثل آرایه یا تابع) خروجی به نوع آن وابسته است؛
✔️ در صورت فراخوانی روی null یا undefined خطا تولید می‌کند.

const num = 42;
console.log(num.toString()); // "42"

const arr = [1, 2, 3];
console.log(arr.toString()); // "1,2,3"

// خطا در null یا undefined
null.toString(); // TypeError


---

### ۲️⃣ String() — تابع سراسری

این یک تابع عمومی برای تبدیل هر نوع داده به رشته است:

✔️ با تمام مقادیر (حتی null و undefined) کار می‌کند؛
✔️ به جای خطا، عبارت "null" یا "undefined" برمی‌گرداند.

console.log(String(42));        // "42"
console.log(String([1, 2])); // "1,2"
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"


---

### چند نکته تکمیلی

✔️ برای اشیاء و آرایه‌هایی که متد toString را بازنویسی نکرده‌اند، خروجی پیش‌فرض خواهد بود (مانند "[object Object]" یا "1,2,3"). برای نمایش متفاوت باید متد toString بازنویسی شود؛
✔️ اگر نیاز به سریال‌سازی شیء به JSON دارید، از JSON.stringify() استفاده کنید؛
✔️ در بیشتر مواقع، متد toString() اندکی سریع‌تر از String() است، چون بررسی‌های اضافه ندارد. با این حال، این تفاوت معمولاً ناچیز است و در عملکرد روزمره کد تأثیر محسوسی ندارد.

---

به‌طور معمول، من از toString() استفاده می‌کنم چون ساده و مستقیم است. اما اگر نیاز باشد مقدار null یا undefined را هم پردازش کنم، سراغ String() می‌روم، زیرا بدون ایجاد خطا، به‌خوبی از عهده این کار برمی‌آید. 👍


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍2
تفاوت Imperative و Declarative در جاوااسکریپت

---

### کد دستوری (Imperative)

در کدنویسی دستوری، شما به کامپیوتر دقیقاً می‌گویید که در هر مرحله چه کاری انجام دهد و جزئیات را مرحله‌به‌مرحله مشخص می‌کنید.

برای نمونه:

فرض کنید تابعی به نام filteredArray داریم که وظیفه‌اش فیلتر کردن یک آرایه است. در حالت دستوری ما با یک حلقه روی آرایه پیمایش می‌کنیم، سپس بررسی می‌کنیم که آیا عدد کمتر از ده است یا نه. اگر کمتر از ده بود، آن را به آرایه‌ای خالی (به نام regularArray) اضافه می‌کنیم.

نمونه کد دستوری:

function filteredArray(arr) {
let regularArray = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] < 10) {
regularArray.push(arr[i]);
}
}
return regularArray;
}

console.log(filteredArray([1, 2, 7, 15, 20])); // [1, 2, 7]


در اینجا ما دقیقاً توضیح داده‌ایم که در هر مرحله چه اتفاقی رخ می‌دهد. همین موضوع باعث می‌شود این کدنویسی Imperative (دستوری) باشد.

---

### کد اعلامی (Declarative)

در کدنویسی اعلامی، شما به جای توضیح دادن جزئیات، فقط می‌گویید چه نتیجه‌ای می‌خواهید.

همان مثال بالا را در نظر بگیرید. این بار ما همچنان می‌خواهیم اعداد کمتر از ده را فیلتر کنیم، اما به جای نوشتن مراحل، از متد داخلی filter استفاده می‌کنیم:

نمونه کد اعلامی:

function filteredArray(arr) {
return arr.filter(item => item < 10);
}

console.log(filteredArray([1, 2, 7, 15, 20])); // [1, 2, 7]


در اینجا ما فقط گفتیم: «می‌خواهم آرایه‌ای داشته باشم که عناصرش کمتر از ده باشند». بدون آنکه مرحله‌به‌مرحله توضیح دهیم.

---

جمع‌بندی:

* در Imperative شما «چگونگی انجام کار» را با جزئیات بیان می‌کنید.
* در Declarative شما فقط «آنچه می‌خواهید» را بیان می‌کنید و جزئیات را به زبان یا ابزار می‌سپارید.



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
چگونه مرورگر <script> را هنگام ساخت درخت DOM پردازش می‌کند؟ 🧐

هنگامی که مرورگر HTML را تجزیه می‌کند، تگ‌های <script> می‌توانند ساخت DOM را متوقف کنند و این موضوع روی کارایی صفحه تأثیر می‌گذارد. نحوه‌ی کار به شرح زیر است:

1️⃣ اسکریپت‌های هم‌زمان (synchronous) (`<script>` بدون async یا defer)
این اسکریپت‌ها ساخت DOM را تا زمان بارگذاری و اجرای خود متوقف می‌کنند. نتیجه، کند شدن رندر صفحه است.

2️⃣ اسکریپت‌های غیرهم‌زمان (async)
این اسکریپت‌ها هم‌زمان با HTML بارگذاری می‌شوند**، اما **به محض بارگذاری فایل اجرا می‌شوند. ترتیب اجرای آن‌ها پیش‌بینی‌ناپذیر است و ممکن است رندر صفحه را قطع کند.

3️⃣ اسکریپت‌های defer
این اسکریپت‌ها به صورت هم‌زمان بارگذاری می‌شوند اما پس از تجزیه کامل HTML اجرا می‌شوند و ترتیب اجرای آن‌ها همان ترتیب قرارگیری در سند است.

4️⃣ اسکریپت‌های ماژولی (`type="module"`)
این اسکریپت‌ها مانند defer بارگذاری می‌شوند**، اما **در حالت strict اجرا می‌شوند و از import/export پشتیبانی می‌کنند. اجرای آن‌ها پس از بارگذاری HTML انجام می‌شود و از top-level await پشتیبانی می‌کند.

5️⃣ اسکریپت‌های داینامیک (با `document.createElement('script')`)
به طور پیش‌فرض مانند async رفتار می‌کنند.

👩‍🎓 چند توصیه:

✔️ برای اکثر اسکریپت‌ها از defer استفاده کنید تا رندر صفحه مسدود نشود**؛
✔️ برای اسکریپت‌های مستقل (مثلاً اسکریپت‌های تحلیلی) از **async
استفاده کنید؛
✔️ تعداد اسکریپت‌های هم‌زمان در <head> را کمینه کنید — این موضوع بارگذاری صفحه را کند می‌کند.

به یاد داشته باشید، اسکریپت‌ها نه تنها می‌توانند DOM را مسدود کنند**، بلکه روی **رندر صفحه نیز تأثیر می‌گذارند و سرعت بارگذاری و تجربه کاربری را کاهش می‌دهند. استفاده درست از async و defer باعث سرعت بالاتر بارگذاری و رندر بهتر می‌شود. 👍




#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
می‌دانستید که nth-child در CSS از چند سال پیش به صورت استاندارد قابل استفاده شده است؟

منظورم این است: قبلاً انتخاب شما محدود بود؛ می‌توانستی از nth-child برای شماره‌گذاری گره‌ها (تگ‌ها) به‌طور عمومی استفاده کنی یا nth-of-type برای شماره‌گذاری نوع خاصی از گره‌ها (div، p، section).

چطور می‌توانستم دومین عنصر با کلاس .star را انتخاب کنم؟

و چیزی که من نمی‌دانستم این است که nth-child اکنون می‌تواند یک سلکتور به شکل آرگومان of بگیرد!

#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
👍1
This media is not supported in your browser
VIEW IN TELEGRAM
فرض کنید یک گالری عکس یا یک لیست آیتم دارید و وقتی اسکرول می‌کنید، هر تصویر یا آیتم به‌صورت دقیق و منظم جلوی چشم شما قرار می‌گیرد، نه اینکه نیمه‌ای از آن نمایش داده شود.

‌‏Scroll Snap دقیقاً همین کار را انجام می‌دهد: وقتی کاربر اسکرول می‌کند، مرورگر به‌صورت خودکار موقعیت صفحه را روی نقاط مشخص (Snap Points) قفل می‌کند. مثل اینکه یک مغناطیس نامرئی روی هر آیتم گذاشته‌ایم که وقتی نزدیک می‌شود، صفحه آن را درست در وسط یا بالای دید شما قرار می‌دهد.
ویژگی scroll-snap-type یک خصوصیت الزامی برای هر کانتینر قابل اسکرول است که می‌خواهید روی آن scroll snapping فعال شود. این ویژگی به سه سؤال برای کانتینر پاسخ می‌دهد:

1-آیا این کانتینر از scroll snapping استفاده می‌کند؟
2-روی کدام محور — افقی (x)، عمودی (y)، بلوک (block) یا خطی (inline) — scroll snapping اعمال شود؟
3-رفتار scroll snapping چگونه باشد؟ آیا همیشه اجباری (mandatory) است، یا فقط زمانی که کاربر به موقعیت اسنپ نزدیک شود فعال می‌شود؟

#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
👍3🔥1
دربارهٔ مشکل مرکزچینی عمودی محتوا در CSS می‌توان افسانه‌ها نوشت

خیلی هم غم‌انگیز است که این داستان‌ها کم‌کم به پایان می‌رسند، زیرا حالا ما نه تنها Flex و Grid را داریم، بلکه یک ویژگی ساده و قابل‌فهم به نام align-content هم در دسترس است

بله، این ویژگی از دیرباز پایه‌ای برای مدل‌های Flex و Grid بوده است، اما از نسخه‌های جدید مرورگرها — Chrome 123**، **Firefox 125 و Safari 17.4 — پشتیبانی می‌شود و اکنون در مدل بلوکی (Block Layout) هم قابل استفاده است! 🎉

مثال ساده:

.container {
align-content: center;
}




#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
👍4
در مرورگر سافاری روی سیستم‌عامل آی‌اواس یک قابلیت جالب وجود دارد: وقتی انگشتتان را روی یک عنصر، مثلاً یک پیوند، نگه دارید، پنجره‌ای شناور باز می‌شود که پیش‌نمایش آن را نمایش می‌دهد. اما گاهی این ویژگی اصلاً کاربردی نیست و لازم است راهی برای غیرفعال کردن آن پیدا شود.

طبق معمول، این روش چندان هم استاندارد نیست
سپاس از اپل، همیشه همین‌طور خاص!

#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
👍2
می‌دونید اگه توی فایرفاکس داخل یه فیلد <input type="number"> به‌جای عدد، چیزی مثل lol بنویسید چی می‌شه؟

هیچی! قبول می‌کنه 😐

یعنی همون «lol» رو جلوی چشم‌تون نشون می‌ده، انگار که یه عدد درسته. ولی وقتی مقدارش رو توی DOM بخونید، خالیه. یعنی مرورگر می‌گه: «باشه بهت نشونش دادم، ولی اصلاً حسابش نمی‌کنم.» شاهکاره واقعاً!

این یه باگه که از سال ۲۰۱۷ توی Bugzilla بازه و هنوزم وصله نشده:
[Bugzilla #1398528](https://bugzilla.mozilla.org/show_bug.cgi?id=1398528)

طبق استاندارد WHATWG**، ورودی از نوع number فقط باید رشته‌های عددی رو قبول کنه. ولی فایرفاکس هرچی رو قبول می‌کنه — حروف، ایموجی، هرچی بخوای. فقط پشت‌صحنه مقدارش خالی می‌شه. یعنی می‌بینی چی تایپ کردی، ولی مرورگر اون رو معتبر نمی‌دونه. نتیجه؟ تجربه کاربری افتضاح.

حالا چرا درستش نمی‌کنن؟
جواب همیشگی: «خب اگه کاربر با اعداد عربی یا دوناگاری کار کنه چی؟ تازه فرق بین نقطه و ویرگول رو هم باید مشخص کنیم.» خلاصه ترجیح می‌دن همه‌چی رو آزاد بذارن تا اینکه واقعا مشکل رو حل کنن.

بریم سراغ کروم:
کروم بعضی وقتا اجازه می‌ده توی فیلد number حرف **e
رو بنویسید، چون ممکنه بخواید عددی مثل 1e10 (فرمت علمی) رو وارد کنید. اما اگه فقط «e» رو بنویسید… فیلد معتبر می‌شه! 😆

جالب‌تر اینکه 1e- رو هم معتبر می‌دونه، ولی 1ee نه.

از اون طرف اگه توی لوکالی باشید که جداکننده اعشار نقطه است، نوشتن 1,5 (با ویرگول) یا قبول می‌شه یا نمی‌شه — بستگی داره به نسخه‌ی مرورگر، وضعیت ماه و احتمالاً میزان قهوه‌ای که برنامه‌نویس کروم خورده!

نتیجه نهایی:

* فایرفاکس: هرچی بنویسی (حتی «سلام») نشون می‌ده، ولی زیرش خالیه.
* کروم: یه فیلتر داره، ولی اونم نصفه‌نیمه و پر از تناقض.

پس چی کار کنیم؟ خودمون کد بزنیم برای اعتبارسنجی، چون امیدی به مرورگرها نیست.

الان این باگ وارد سال هشتم شده، همچنان با برچسب «NEW» خوابیده و با توجه به بحث‌ها، به این زودی هم درست نمی‌شه.

پ.ن. فایرفاکس اخیراً توی نسخه انگلیسیش، خطای اعتبارسنجی رو به زبان فنلاندی نشون داده! 🤦‍♂️

پ.ن.۲. تازه جدای اینا، اصلاً خیلی‌ها معتقدن که <input type="number"> به‌خودش هیچ فایده‌ای نداره و حتی مضر هم هست

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1🔥1
### fetchpriority در HTML

مرورگر برای نمایش صفحه نیاز دارد منابع لازم مثل CSS، JS، تصاویر و ویدیو را دانلود کند. اول HTML دریافت و تحلیل می‌شود و همزمان اسکنر پیش‌بارگذاری منابع را پیدا و دانلود می‌کند. همه منابع براساس اولویت در شبکه بارگذاری می‌شوند.

ویژگی fetchpriority به شما اجازه می‌دهد اولویت بارگذاری منابع را مشخص کنید:

* high → اولویت بالا
* low → اولویت پایین
* auto → رفتار پیش‌فرض مرورگر

می‌توان از این ویژگی در عناصر زیر استفاده کرد: <link>`، <script>، <img> و <iframe>`.

<img src="lcp-image.jpg" fetchpriority="high">

---

### کاربردهای متداول

* بارگذاری تصاویر مهم صفحه (مثلاً تصاویر LCP) با اولویت بالا
* کاهش اولویت تصاویر غیرضروری (مثل تصاویر کاروسل)
* پیش‌بارگذاری منابع کم‌اهمیت با اولویت پایین
* افزایش یا کاهش اولویت اسکریپت‌ها بسته به نیاز

همچنین می‌توان اولویت را هنگام فراخوانی fetch() مشخص کرد:

const response = await fetch('/resource', { priority: 'low' });


---

### نکته مهم

‏`fetchpriority` ابزار جدیدی است برای کنترل هوشمندانه بارگذاری منابع و مکمل روش‌های قدیمی مثل:

* loading در <img> و <iframe>
* preload در <video> و <link>
* defer و async در <script>

برای جزئیات بیشتر می‌توانید مقاله کامل را در web.dev بخوانید:
[https://web.dev/articles/fetch-priority](https://web.dev/articles/fetch-priority)


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
ویدیو دوبله شده در مورد الگو های طراحی در اپلیکیشن های تحت وب [+لینک]
در این دوره، با الگوهای طراحی برای پروژه‌های فرانت‌اند با استفاده از جاوا اسکریپت آشنا خواهید شد. مزایا و چالش‌های الگوهای طراحی را درک خواهید کرد و نحوه پیاده‌سازی الگوهای مختلف برای ارتقای خوانایی، قابلیت استفاده مجدد، مدولار بودن و مقیاس‌پذیری پروژه‌های جاوا اسکریپت ساده خود را خواهید آموخت.

🔗https://www.aparat.com/v/phnxki9?playlist=20513366
#️⃣#tip #dub
👥@IR_javascript_group
🆔@IR_javascript
👍1
سیگنال: جادوی واکنش‌گرایی در برنامه‌نویسی

باور دارم که درک چگونگی کارکرد یک پدیده، لذت بیشتری به زندگی شما می‌بخشد؛ زیرا باعث می‌شود در آنچه انجام می‌دهید توانمندتر باشید.
بسیاری از چارچوب‌های دیگر همچون Angular، Solid، Vue و Qwik نیز چنین رویکردی دارند. حتی پیشنهادی برای افزودن سیگنال‌ها به خود زبان جاوااسکریپت هم ارائه شده است.

🔹 اجزای اصلی سیگنال
۱. مقدار (value): همان داده‌ای که نگه‌داری می‌شود.
۲. مشترکان (subscribers): توابعی که باید در صورت تغییر مقدار اجرا شوند.
۳. اثرها (effects): توابعی که به تغییر سیگنال واکنش نشان می‌دهند.

سیگنال در اصل ظرفی است که یک مقدار و مجموعه‌ای از مشترکان را نگه می‌دارد و هنگام تغییر مقدار، آن‌ها را آگاه می‌سازد. بنابراین، سیگنال به‌تنهایی کاری انجام نمی‌دهد:
function state(value) {
const signal = { value, subscribers: new Set() }
return signal
}


برای واکنش به تغییرات سیگنال، به «اثرها» نیاز داریم. اثرها همان توابعی هستند که هنگام تغییر سیگنال اجرا می‌شوند.

let activeEffect = null

function effect(fn) {
// تنظیم اثر فعال
activeEffect = fn
// اجرای اثر
fn()
}


جادو زمانی رخ می‌دهد که درون یک اثر، سیگنالی خوانده شود. هنگام خواندن مقدار، اثر فعال به فهرست مشترکان افزوده می‌شود:

let activeEffect = fn

function get(signal) {
// افزودن اثر به مشترکان
signal.subscribers.add(activeEffect)
// بازگرداندن مقدار
return signal.value
}


سپس، هنگامی که مقداری در سیگنال نوشته می‌شود، مشترکان آگاه می‌شوند

function set(signal, value) {
// به‌روزرسانی مقدار
signal.value = value
// آگاه‌سازی مشترکان
signal.subscribers.forEach(effect => effect())
}


از این پس تنها کافی است حالت (state) را به‌روزرسانی کنید؛ رابط کاربری در هر نقطه‌ای که از آن استفاده شده باشد تغییر خواهد کرد. اگر با الگوی «ناظر» (observer) آشنا باشید، سیگنال‌ها نوعی نسخه‌ی پیشرفته‌تر از observable هستند و چارچوب‌هایی مانند Svelte کارهای پیچیده‌ی بسیاری در پشت صحنه انجام می‌دهند تا عملکرد آن‌ها بهینه باشد.

به‌عنوان نمونه، یک شمارنده با پیاده‌سازی ساده‌ی سیگنال‌ها در یک فایل HTML معمولی:

<script type="module">
import { state, set, get, effect } from './signals.js'

// ایجاد سیگنال
const count = state(0)

// اتصال به عناصر DOM
const btn = document.querySelector('button')
btn.onclick = () => set(count, get(count) + 1)

// ایجاد اثر برای قالب
effect(() => btn.textContent = get(count))
</script>

<button>0</button>



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👎1
شما اچ‌تی‌ام‌ال را نمی‌شناسید: انواع اسکریپت‌ها

برای افزودن اسکریپت‌ها به صفحه از عنصر <script> استفاده می‌شود. اسکریپت‌ها انواع مختلفی دارند که بر رفتار و شیوه‌ی بارگذاری آن‌ها تأثیر می‌گذارد.

## 🔹 اسکریپت کلاسیک

اسکریپت‌های معمولی جاوااسکریپت که وقتی مرورگر بهشون می‌رسه، همون‌جا اجرا می‌شن و پردازش صفحه رو نگه می‌دارن.

<script>
console.log("Hello from classic script!");
</script>


---

## 🔹 اسکریپت داده (type="not-javascript")

وقتی نوع اسکریپت رو چیزی غیر از جاوااسکریپت بذاریم، مرورگر اون رو اجرا نمی‌کنه. میشه برای نگهداری داده یا تنظیمات استفاده کرد.

<script type="not-javascript">
{
"user": "Ali",
"role": "admin"
}
</script>


---

## 🔹 اسکریپت خارجی کلاسیک

به‌جای نوشتن کد داخل اچ‌تی‌ام‌ال، فایل بیرونی رو بارگذاری می‌کنیم. در زمان بارگذاری، پردازش صفحه متوقف میشه.

<script src="/script.js"></script>


📄 در فایل script.js می‌نویسیم:

console.log("Loaded from external file!");


---

## 🔹 اسکریپت خارجی با async

وقتی async بذاریم، فایل هم‌زمان با پردازش صفحه بارگذاری میشه. ولی به محض اینکه کامل دانلود بشه، اجرا میشه و پردازش صفحه رو همون لحظه متوقف می‌کنه.

<script src="/script.js" async></script>


---

## 🔹 اسکریپت خارجی با defer

اینجا فایل بارگذاری میشه، اما اجرای اون تا وقتی کل DOM آماده نشه عقب میفته. به همین خاطر همیشه مطمئنی به ترتیب ظاهر شدنش در HTML اجرا میشه.

<script src="/script.js" defer></script>


---

## 🔹 اسکریپت با async defer

اگه هر دو ویژگی رو با هم بذاریم، در عمل مثل async رفتار می‌کنه و defer نادیده گرفته میشه.

<script src="/script.js" async defer></script>


---

## 🔹 اسکریپت ماژول (type="module")

اینجا میشه از import و export استفاده کرد. ماژول‌ها مثل defer هستن: در زمان بارگذاری پارسر رو متوقف نمی‌کنن و بعد از آماده شدن DOM اجرا می‌شن.

<script type="module">
import { sayHello } from "./utils.js";
sayHello("Ali");
</script>


📄 در فایل utils.js:

export function sayHello(name) {
console.log("Hello, " + name);
}


---

## 🔹 ماژول با async

همه‌ی وابستگی‌های ماژول به صورت موازی بارگذاری میشن. وقتی آخرینش آماده شد، ماژول اجرا میشه.

<script type="module" src="/main.js" async></script>


---

## 🔹 اسکریپت با nomodule

این ویژگی برای مرورگرهای قدیمی هست. اگه مرورگر از ماژول پشتیبانی کنه، این اسکریپت اجرا نمی‌شه.

<script src="/fallback.js" nomodule></script>


---

## 🔹 نقشه‌ی واردات (type="importmap")

به مرورگر می‌گه چطور اسم‌های مستعار ماژول‌ها رو به مسیر واقعی فایل‌ها وصل کنه.

<script type="importmap">
{
"imports": {
"lib": "/js/library-v1.js"
}
}
</script>

<script type="module">
import { doSomething } from "lib";
doSomething();
</script>


---

## 🔹 قوانین بارگذاری پیش‌دستانه (type="speculationrules")

به مرورگر می‌گه بعضی صفحات یا منابع رو از قبل بارگذاری کنه تا وقتی کاربر روشون کلیک کرد، سریع باز بشن.

<script type="speculationrules">
{
"prefetch": [
{ "source": "document", "urls": ["/next-page.html"] }
]
}
</script>





#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
## تفاوت بین Number.isFinite و isFinite چیست؟ 🤨

در JavaScript دو تابع برای بررسی این که آیا یک مقدار یک عدد محدود (Finite) است یا نه وجود دارد: Number.isFinite و تابع سراسری isFinite. بیایید با هم تفاوت آن‌ها را بررسی کنیم!

---

### ✔️ Number.isFinite

این تابع بررسی می‌کند که آیا مقدار داده‌شده یک عدد محدود واقعی است یا خیر.

تفاوت اصلی: این تابع تبدیل نوع داده‌ای انجام نمی‌دهد.

console.log(Number.isFinite(10));        // true
console.log(Number.isFinite('10')); // false
console.log(Number.isFinite(Infinity)); // false


---

### ✔️ isFinite

این تابع بررسی می‌کند که آیا مقدار داده‌شده قابل تبدیل به عدد است و پس از تبدیل، یک عدد محدود می‌باشد یا خیر.

console.log(isFinite(10));        // true
console.log(isFinite('10')); // true، رشته به عدد تبدیل می‌شود
console.log(isFinite('abc')); // false
console.log(isFinite(true)); // true، true به 1 تبدیل می‌شود


---

### 🔹 جمع‌بندی

* 🧩 Number.isFinite: وقتی نیاز به بررسی دقیق و بدون تبدیل نوع عدد محدود دارید.
* 🧩 isFinite: وقتی می‌خواهید بررسی کنید که مقدار قابل تبدیل به عدد محدود است یا نه. 👍



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1
بررسی آزاردهنده‌ترین عنصر در میان تمام ویجت‌های استاندارد HTML

#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
👍3
اگر زمانی که موتور خودرو را روشن می‌کنیم، موتور سرد باشد، Cold Start رخ می‌دهد. در این حالت، دور موتور بیش از حد نرمال افزایش می‌یابد تا زمانی که موتور به دمای محیطی که در آن قرار دارد برسد. این کار باعث می‌شود موتور سریع‌تر به شرایط عملکردی مناسب خود برسد.

در دنیای نرم‌افزار، هوش مصنوعی و سرویس‌های ابری نیز مفهوم مشابهی وجود دارد. «شروع سرد» (Cold Start) به وضعیتی گفته می‌شود که وقتی یک سرویس، مدل یا برنامه برای اولین بار اجرا می‌شود، باید همه چیز را از صفر بارگذاری کند. به همین دلیل، معمولاً در این مرحله زمان پاسخ‌دهی طولانی‌تر از حالت عادی است.

در سرویس‌های ابری (Cloud Services):
وقتی یک تابع یا کانتینر برای اولین بار اجرا می‌شود، سیستم باید محیط آن را آماده کند، کتابخانه‌ها و وابستگی‌ها را بارگذاری کند و سپس کد را اجرا کند. این زمان اولیه همان Cold Start است.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
1
### مقادیر دوگانه در ویژگی display در CSS 🤔

ویژگی display در CSS تعیین می‌کند که عناصر چگونه در صفحه نمایش داده شوند. هنگامی که از مقادیر دوگانه استفاده می‌کنیم، می‌توانیم دو نوع رفتار نمایش را برای یک عنصر ترکیب کنیم و در نتیجه انعطاف‌پذیری بیشتری به دست آوریم.

#### مقادیر دوگانه چیست؟

🧩 مقدار نخست، رفتار اصلی عنصر را مشخص می‌کند (مانند *block*، *inline* یا *flex*).
🧩 مقدار دوم، این رفتار را تکمیل و اصلاح می‌کند.

به‌عنوان نمونه، در حالت inline-block**، عنصر مانند یک عنصر درون‌خطی رفتار می‌کند، اما در عین حال می‌توان برای آن ابعاد مشخص کرد، درست مانند یک عنصر بلوکی. 👍

```html
<div style="display: inline-block; width: 100px; height: 50px; background-color: lightblue;">بلوک</div>
```

#### نمونه‌های دیگر:

✔️ **inline-block
:
⏺️ *inline* — عنصر در همان خط باقی می‌ماند.
⏺️ *block* — امکان تعریف اندازه‌ها فراهم است.

✔️ inline-flex:
⏺️ *inline* — ظرف (container) موجب شکستن خط نمی‌شود.
⏺️ *flex* — عناصر درون ظرف بر اساس قوانین فِلِکس‌باکس چیده می‌شوند.

---

### نتیجه‌گیری

مقادیر دوگانه در CSS باعث ساده‌تر شدن ساختار صفحه می‌شوند و امکان طراحی صفحات منعطف‌تر و واکنش‌گرا را با حداقل میزان کدنویسی فراهم می‌آورند. 💗



#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
👍1
### ویژگی decoding در تگ <img> واقعاً چه کاری انجام می‌دهد؟

(منبع: [TuneTheWeb](https://www.tunetheweb.com/blog/what-does-the-image-decoding-attribute-actually-do/))

این موضوع کمی پیچیده است و در مقاله اصلی حتی سخت‌تر توضیح داده شده، اما این دانش روزی به‌کار شما خواهد آمد.

احتمالاً دیده‌اید که بعضی تصاویر با ویژگی decoding="async" اضافه می‌شوند. شاید خودتان هم طبق توصیه‌های مقالات بهینه‌سازی عملکرد چنین ویژگی‌ای را استفاده کرده‌اید. اگر از کامپوننت Image در NextJS استفاده می‌کنید، به‌صورت پیش‌فرض این ویژگی روی تصاویر فعال است. اما آیا واقعاً مهم است؟

بارری پولارد این سوال را مطرح کرد و با صحبت با توسعه‌دهندگان مرورگرها به نکات جالبی رسید.

---

### مقادیر ویژگی decoding

طبق مشخصات، این ویژگی سه مقدار دارد:

* sync → درخواست رمزگشایی همزمان تصویر
* async → درخواست رمزگشایی ناهمزمان تصویر
* auto → مرورگر خودش تصمیم می‌گیرد

---

### روند کار تصویر در مرورگر

تصاویر مراحل زیر را طی می‌کنند:

1. مرورگر <img src="..."> را می‌بیند و ابتدا تصویر را از شبکه یا کش دریافت می‌کند.
2. سپس یک فرآیند کمکی تصویر را رمزگشایی می‌کند (تبدیل بایت‌ها به داده‌های قابل رندر).
3. در نهایت تصویر در صفحه نمایش داده می‌شود.

نکته جالب این است که در صفحات استاتیک، این ویژگی تقریباً تأثیری ندارد، زیرا مرورگرها هوشمندانه تغییرات را جمع‌آوری کرده و به شکل chunks رندر می‌کنند و تصاویر در جریان اصلی رندر بلوکه نمی‌شوند.

* در Firefox به‌صورت پیش‌فرض async است.
* در Chrome پیش‌فرض sync است.
* در WebKit بیشتر مواقع sync است اما در بعضی استثناها async است.

بنابراین مرورگرها هنوز روی یک رفتار پیش‌فرض توافق ندارند.

---

### تفاوت واقعی هنگام استفاده از JavaScript

در SPAها (برنامه‌های تک‌صفحه‌ای) وقتی تصاویر توسط JS اضافه می‌شوند، تفاوت محسوس می‌شود:

* اگر داخل JS یک div با پس‌زمینه قرمز بسازید و بعد یک تصویر بزرگ داخل آن اضافه کنید:

* با sync → صفحه ممکن است کمی گیر کند زیرا مرورگر منتظر رمزگشایی تصویر می‌ماند.
* با async → ابتدا پس‌زمینه قرمز نمایش داده می‌شود و بعد تصویر رندر می‌شود، اما ممکن است موقعیت چشمک زدن ایجاد شود.

* مرورگرهای مدرن تصاویر خارج از viewport را تا زمانی که به آن‌ها اسکرول نشود، رمزگشایی نمی‌کنند تا حافظه اضافی مصرف نشود. اما اگر صفحه پر از تصویر باشد و کاربر کلید End را بزند، ممکن است صفحه کمی گیر کند.

---

### توصیه‌ها

* اگر تصاویر را با JS بارگذاری می‌کنید، بهتر است از async استفاده کنید. این روش هم ناهمزمان است و هم قبل از رندر، تصویر آماده است.
* async مناسب زمانی است که متن صفحه مهم‌تر از تصاویر است. در این حالت دو مرحله رندر داریم ولی متن سریع‌تر نمایش داده می‌شود.
* برای بهینه‌سازی Core Web Vitals، به ویژه LCP**، بهتر است مقادیر مختلف را امتحان کنید. هرچند intuitively به نظر می‌رسد `sync` بهتر باشد، اما مرورگرها هوشمند هستند و باید تست و مقایسه کنید.
* اگر روی بهینه‌سازی رمزگشایی تصاویر کار می‌کنید، یا سایتتان از قبل عالی است، یا بهتر است روی مسائل مفیدتری مثل **بارگذاری تنبل تصاویر
و بهینه‌سازی خود تصاویر تمرکز کنید.

---

منبع اصلی: [TuneTheWeb](https://www.tunetheweb.com/blog/what-does-the-image-decoding-attribute-actually-do/)


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript