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

🆔@IR_javascript
Download Telegram
ابزاری تعاملی برای نمایش و کنترل داده‌ها در محور زمان است؛ دقیقاً مشابه نمونه‌ای که در تصویر دیده می‌شود. این کتابخانه برای مصورسازی تاریخ‌ها


🔗https://visjs.github.io/vis-timeline/examples/timeline/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
استفاده از ARIA برای هوش مصنوعی

یک ماه پیش، OpenAI مرورگر اختصاصی خود با نام ChatGPT Atlas را معرفی کرد (https://openai.com/index/introducing-chatgpt-atlas/
). این مرورگر بر پایهٔ پلتفرم Chromium ساخته شده و دارای ChatGPT داخلی و یک عامل (Agent) است که می‌تواند در وب‌سایت‌ها پیمایش کند و کارهای کاربران را در آن‌ها انجام دهد.
اوپن‌اِی‌آی پیشنهاد کرده است که توسعه‌دهندگان برای بهبود عملکرد عامل Atlas در تعامل با وب‌سایت‌ها، «تگ‌های ARIA» اضافه کنند. از این بگذریم که آن‌ها به جای «attributes» از واژهٔ «tags» استفاده کرده‌اند که می‌تواند نشانه‌ای از ناآشنایی با استاندارد ARIA باشد.
در حال حاضر سهم Atlas در بازار بسیار ناچیز است و بعید است به این زودی‌ها سهم بزرگی به خود بگیرد. بنابراین احتمال ایجاد موج توجه و هجوم توسعه‌دهندگان برای افزودن ARIA «به‌خاطر هوش مصنوعی» چندان زیاد نیست.

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

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
اگر بخواهید HTML را به تصویر تبدیل کنید، معمولاً مجبور می‌شوید از ابزارهای مختلف و نه چندان خوش‌ساخت استفاده کنید — چرا که باید DOM را شبیه‌سازی کنند. تا پیش از این، هیچ راه‌حل پایدار و قابل اطمینانی وجود نداشت (شاید فقط Playwright با اسکرین‌شات قابل قبول بود).

حالا کم‌کم چیزی معقول ظاهر می‌شود.

‏WICG ایده‌ای با نام HTML-in-Canvas ارائه کرده است: در این روش، یک <canvas> آموزش می‌بیند که عناصر معمولی HTML را رسم کند.
یعنی دقیقاً همان‌طور که مرورگر عناصر را در DOM رسم می‌کند — با استایل‌ها، اندازه‌ها، متن و تو در تو بودن. فقط به جای نمایش روی صفحه، عنصر را به تصویر داخل <canvas> تبدیل می‌کند.

در واقع، خروجی بسیار جالب است. نمونه‌ای از تصویرسازی:
<canvas id="canvas" width="638" height="318" layoutsubtree="true">
<div id="drawElement" style="width: 550px;">
Hello from <a href="https://github.com/WICG/html-in-canvas">html-in-canvas</a>!
<br>I'm multi-line, <b>formatted</b>,
rotated text with emoji (&#128512;), RTL text
<span dir=rtl>من فارسی صحبت میکنم</span>,
vertical text,
<p style="writing-mode: vertical-rl;">
这是垂直文本
</p>
an inline image (<img width="150" src="wolf.jpg">), and
<svg width="50" height="50">
<circle cx="25" cy="25" r="20" fill="green" />
<text x="25" y="30" font-size="15" text-anchor="middle" fill="#fff">
SVG
</text>
</svg>!
</div>
</canvas>



در حال حاضر، فقط در Chrome Canary نسخهٔ ۱۳۸ به بالا کار می‌کند و باید یک فلگ جداگانه فعال شود. همچنین محدودیت‌هایی وجود دارد: فقط عناصری که داخل خود <canvas> هستند رندر می‌شوند و برخی موارد به‌صورت عمدی توسط مرورگر مسدود می‌شوند — مثل iframeهای خارجی یا SVGهای عجیب. اما در مجموع، کار می‌کند.

فلگ مورد نیاز:

--enable-blink-features=CanvasDrawElement


این قدم اول واقعی است تا دیگر با رسم دستی متن و HTML داخل کانواس دردسر نکشیم. اگر این قابلیت به مرورگرهای عادی هم برسد، می‌توان بالاخره با خیال راحت نفس کشید.

🔗https://github.com/WICG/html-in-canvas
#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1👎1
Media is too big
VIEW IN TELEGRAM
ویدیو دوبله شده در مورد مدیریت حافظه در مرورگر

#️⃣#tip #dub
👥@IR_javascript_group
🆔@IR_javascript
2
This media is not supported in your browser
VIEW IN TELEGRAM
افکت Ambilight
می‌توان همین ایده را برای نورپردازی لبه‌های کارت‌ها هم به‌کار برد!

کمی جاوااسکریپت برای ارسال مختصات نشانگر ماوس به CSS، کمی فیلترهای SVG برای محوکردن نسخهٔ تکرارشدهٔ محتوا — و تمام! نتیجه کاملاً چشمگیر خواهد بود.

🔗https://codepen.io/jh3y/pen/WbwZaNa
#️⃣#code
👥@IR_javascript_group
🆔@IR_javascript
‏**Proxy و Reflect: چطور کار با آبجکت‌ها راحت‌تر می‌شود**

در JavaScript ابزارهای قدرتمندی وجود دارند که گاهی کمتر به چشم می‌آیند. Proxy و Reflect دقیقاً از همین دست ابزارها هستند که اغلب پشت صحنه باقی می‌مانند. اما اگر بدانید چطور از آن‌ها درست استفاده کنید، می‌توانند توسعه را بسیار ساده‌تر کنند. بیایید چند مثال واقعی را ببینیم که در آن‌ها Proxy و Reflect مفید هستند.

💬 لاگ‌گیری و دیباگ

فرض کنید می‌خواهید ردیابی کنید چه کسی و چه زمانی به یک آبجکت دسترسی پیدا می‌کند. به جای اینکه کد را پر از console.log کنید، می‌توانید از Proxy استفاده کنید تا همه دسترسی‌ها را رهگیری کنید. این روش مخصوصاً وقتی با استیت‌های بزرگ مثل Vue یا MobX کار می‌کنید، فوق‌العاده کاربردی است.

const user = { name: "Alex", age: 25 };

const loggedUser = new Proxy(user, {
get(target, prop) {
console.log(`GET ${prop}`);
return Reflect.get(target, prop);
},
set(target, prop, value) {
console.log(`SET ${prop} = ${value}`);
return Reflect.set(target, prop, value);
}
});

loggedUser.name; // GET name
loggedUser.age = 26; // SET age = 26


💬 اعتبارسنجی داده‌ها

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

const product = new Proxy({}, {
set(target, prop, value) {
if (prop === 'price' && value < 0) {
throw new Error("قیمت نمی‌تواند منفی باشد");
}
return Reflect.set(target, prop, value);
}
});


💬 Reflect: دسترسی ایمن

Reflect مجموعه‌ای از متدها برای کار ایمن با آبجکت‌هاست. این متدها عملیات استاندارد را انجام می‌دهند، اما جلوی خطاهای غیرمنتظره را می‌گیرند و رفتار قابل پیش‌بینی ایجاد می‌کنند.

Reflect.get(obj, 'key'); // به جای obj.key  
Reflect.set(obj, 'key', 'value'); // true/false برمی‌گرداند، خطا نمی‌دهد


وقتی با Proxy ترکیب شود:

const safe = new Proxy(obj, {
get: (t, p) => Reflect.get(t, p),
set: (t, p, v) => Reflect.set(t, p, v)
});


📌 بسیاری از سیستم‌های واکنش‌گرایی مثل Vue 3 و MobX هم بر اساس Proxy ساخته شده‌اند. این ابزار به شما اجازه می‌دهد به تغییر داده‌ها «مشترک شوید» و UI را به‌طور خودکار بروزرسانی کنید، بدون اینکه ساختار داده را تغییر دهید.

Proxy و Reflect ابزارهای قدرتمندی هستند؛ اگر درست استفاده شوند، می‌توانند لایه‌های مؤثر لاگ‌گیری، اعتبارسنجی و واکنش‌گرایی را بدون کد اضافی یا ترفندهای پیچیده بسازند.



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
‏URLPattern: روشی ساده برای کار با نشانی‌های اینترنتی بدون دردسر 🧐

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

متد exec()
اطلاعاتی دقیق دربارهٔ تطبیق بازمی‌گرداند یا اگر تطبیقی وجود نداشته باشد مقدار null را برمی‌گرداند.
نتیجه شامل ویژگی‌هایی برای هر بخش از نشانی اینترنتی است (protocol، hostname، pathname، search، hash و مانند آن).
هر بخش معمولاً دارای فیلدی به نام input (رشتهٔ واقعی) و groups است که شیئی شامل مقادیر نام‌گذاری‌شدهٔ استخراج‌شده است.

const pattern = new URLPattern({
protocol: 'https',
hostname: 'example.com',
pathname: '/posts/:year/:slug',
search: 'page=:page',
hash: ':section'
});

const url =
'https://example.com/posts/سال دوهزار و بیست و پنج/urlpattern-guide?page=دو#intro';

const result = pattern.exec(url);

// pathname
console.log(result.pathname.input);
// "/posts/سال دوهزار و بیست و پنج/urlpattern-guide"

console.log(result.pathname.groups.year);
// "سال دوهزار و بیست و پنج"

console.log(result.pathname.groups.slug);
// "urlpattern-guide"

// search
console.log(result.search.input);
// "?page=دو"

console.log(result.search.groups.page);
// "دو"

// hostname و protocol
console.log(result.hostname.input);
// "example.com"

console.log(result.protocol.input);
// "https"


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
This media is not supported in your browser
VIEW IN TELEGRAM
می‌توان ظاهر رابط کاربری را با کاهش یا حذف نوارهای اسکرول از طریق ویژگی scrollbar-width تمیزتر کرد.

نمونهٔ اسکرول‌بار باریک:

ul {
scrollbar-width: thin;
}


نمونهٔ اسکرول‌بار مخفی (ناحیه همچنان قابل اسکرول است):

.cards-container {
scrollbar-width: none;
}


این روش برای سایدبارها، جدول‌های داده، پنل‌های چت، داشبوردهایی با اسکرول‌های متعدد، کاروسل‌ها و رابط‌های لمسی مناسب است.

در نهایت، اسکرول همچنان کار می‌کند، اما ظاهر رابط کاربری مرتب‌تر و چشم‌نوازتر می‌شود. 🥺


#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
👍3
This media is not supported in your browser
VIEW IN TELEGRAM
حذف پس‌زمینه در مرورگر
حذف پس‌زمینه را مستقیماً در مرورگر خود انجام دهید؛ این ابزار با WebGPU کار می‌کند و از مدل «آر‌اِم‌بی‌جی نسخهٔ یک‌ممیز‌چهار» از هاجینگ فِیس استفاده می‌کند.

🔗https://github.com/ducan-ne/remove-bg
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
1
غیرفعال کردن عملیاتی که با کلیک راست ماوس انجام می‌شود

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

و در واقع این روش بسیار ساده امکان می‌دهد که قابلیت کلیک راست ماوس را در یک صفحه غیرفعال کنید.

<body oncontextmenu="return false">
<div></div>
</body>



#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
ویدیو دوبله شده در مورد اسولت نسخهٔ پنج (The Complete Svelte 5 Course) [+لینک]

اسولت یک فریم‌ورک همراه با کامپایلر اختصاصی است که هدفش تولید کد کلاینتی فوق‌العاده سبک است؛ و البته فریم‌ورکی نسبتاً پرطرفدار نیز به شمار می‌آید.

«ماتیا از کرواسی» (امضایی که خودِ نویسنده استفاده می‌کند) دوره‌ای بسیار جامع گرد آورده که به شما امکان می‌دهد اسولت نسخهٔ پنج را از پایه بیاموزید. این دوره شامل بیست و هشت فصل، سه ساعت ویدئو و تعداد زیادی دمو است. دوره رایگان است،
کد ها در لینک زیر موحود است
https://joyofcode.xyz/learn-svelte

🔗https://www.aparat.com/v/dbp98sl
#️⃣#tip #dub
👥@IR_javascript_group
🆔@IR_javascript
👍1
This media is not supported in your browser
VIEW IN TELEGRAM
Draw DB

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


🔗https://www.drawdb.app
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
This media is not supported in your browser
VIEW IN TELEGRAM
گیم‌شِل — یک بازیِ آموزشیِ کنسولی است که از ماجراجویی‌های کلاسیک متنی الهام گرفته؛ جایی که تمام دنیا در قالب متن وجود دارد و اعمال شما همان فرمان‌ها هستند. تنها تفاوت این است که این‌جا فرمان‌ها واقعیِ یونیکس‌اند. بازی با مأموریت‌ها و وظایف، کار با ترمینال را آموزش می‌دهد و یادگیری را به یک کوئست تبدیل می‌کند.
است، روی لینوکس و مک‌او‌اِس اجرا می‌شود و یک ایمیج داکر نیز دارد. نصب آن حداقلی است: اسکریپت را دانلود می‌کنید، اجرا می‌کنید — و ی
این پروژه در اصل به‌عنوان یک کار دانشگاهی شکل گرفت: نویسنده گیم‌شِل را برای دانشجویانی ساخت که باید به‌سرعت فرمان‌های پایهٔ لینوکس را یاد می‌گرفتند. ایده کاملاً جواب داد — به‌جای شنیدن سخنرانی‌های خسته‌کننده، دانشجویان شروع کردند به انجام مأموریت‌های عملی با استفاده از ابزارهای واقعی خط فرمان.

گیم‌شِل کاملاً متن‌باز ک محیط تمرینی با امکان حفظ پیشرفت دریافت می‌کنید.

هر مأموریت یک «اتاق» متنی کوچک است، درست مانند بازی‌های ماجرایی قدیمی، اما با فرمان‌های واقعی.

کاملاً پیشنهاد می‌شود.

🔗https://github.com/phyver/GameShell/
#️⃣#tool
👥@IR_javascript_group
🆔@IR_javascript
👎1
اگر صفحهٔ خطا از حداقل اندازهٔ مشخصی کوتاه‌تر باشد (معمولاً پانصد و دوازده بایت)، مرورگر آن را پنهان می‌کند و صفحهٔ خطای پیش‌فرض خودش را نمایش می‌دهد؛ همان پیام معروف «این صفحه قابل نمایش نیست».
این مشکل حدود پانزده سال پیش هم مطرح شده است، بدون هیچ پیشرفتی
در واقع، این پُر کردن صفحه با کامنت‌ها را خودِ سرور اِن‌جین‌اِکس انجام می‌دهد.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
1
vue-wave-player

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

قابلیت‌ها:
— رندر مبتنی بر Canvas با پشتیبانی از رتینا
— جابه‌جایی روی موج + پشتیبانی از لمس
— طراحی واکنش‌گرا از سیصد پیکسل تا هر عرض دلخواه
— انیمیشن نرم برای ظاهر شدن موج
— مکث خودکار تمام پخش‌کننده‌های صفحه هنگام پخش یکی از آن‌ها
— امکان شخصی‌سازی رنگ‌ها، اندازه‌ها و شبکه

🔗https://vue-wave-player.vercel.app/
#️⃣#npm_module
👥@IR_javascript_group
🆔@IR_javascript
👍32
👏 <template> و <slot>

قهرمانان فراموش‌شدهٔ فرانت‌اند که شایستهٔ توجه هستند

همهٔ ما فریم‌ورک‌ها را می‌شناسیم و دوست داریم، اما باید قبول کنیم که مرورگرها می‌توانند کارهای بسیار بیشتری انجام دهند. دو عنصر که اغلب نادیده گرفته می‌شوند اما می‌توانند زندگی توسعه‌دهندگان را بسیار ساده‌تر کنند، <template> و <slot> هستند. این عناصر امکان ساخت «مینی‌کامپوننت‌ها» را مستقیماً در مرورگر فراهم می‌کنند، بدون نیاز به React، Vue یا Svelte.

❗️ <template>

عنصر <template> برای ذخیرهٔ بخش‌هایی از کد HTML استفاده می‌شود که تا زمانی که با جاوااسکریپت به صورت دستی درج نشوند، در صفحه نمایش داده نمی‌شوند. این ابزار ایده‌آل برای ایجاد بلوک‌های تکرارشوندهٔ HTML است.

<template id="card">
<div class="card">
<h3 class="title"></h3>
<p class="text"></p>
</div>
</template>

<script>
const tpl = document.querySelector('#card');
const clone = tpl.content.cloneNode(true);
clone.querySelector('.title').textContent = 'Hello';
document.body.appendChild(clone);
</script>


❗️ <slot>

عنصر <slot> درون کامپوننت‌های سفارشی برای درج HTML خارجی استفاده می‌شود، که اجازه می‌دهد کامپوننت‌های رابط کاربری کامل بدون فریم‌ورک‌های خارجی ایجاد شوند. این روش هم معنایی و دسترس‌پذیر است و هم سفارشی‌سازی کامپوننت‌ها را ساده می‌کند.

<my-button>
<span>Click me</span>
</my-button>

<script>
class MyButton extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<button class="btn">
<slot></slot>
</button>
`;
}
}
customElements.define('my-button', MyButton);
</script>


📌 مرورگرها اکنون آن‌قدر هوشمند شده‌اند که حتی فریم‌ورک‌های پیچیده هم لازم نیستند! همهٔ این‌ها به لطف Web Components، Islands، Partial Hydration و SSR امکان‌پذیر است. و استفاده از این دو عنصر <template> و <slot> باعث می‌شود بسیاری از مسائل که قبلاً تنها با فریم‌ورک‌های کوچک حل می‌شدند، حالا بدون بار اضافی و پیچیدگی قابل مدیریت باشند.

#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
2
ویژگی‌های منطقی در CSS — چگونه استایل‌ها را منعطف و جهانی کنیم

همیشه به حاشیه‌ها از بالا، راست، پایین و چپ فکر می‌کنیم. اما در دنیایی که جهت متن می‌تواند تغییر کند، این روش محدودکننده می‌شود. اینجا logical properties به کمک می‌آیند. آن‌ها اجازه می‌دهند حاشیه‌ها و اندازه‌ها را بر اساس جریان متن تعیین کنید، نه بر اساس سمت‌ها.

ℹ️ logical properties چیست و چه کاربردی دارند؟

inline جهت متن را مشخص می‌کند (مثلاً از چپ به راست یا راست به چپ)

block جهت بلوک‌ها را تعیین می‌کند، معمولاً از بالا به پایین، بسته به جریان سند

برای حاشیه‌های افقی از margin-inline-start و margin-inline-end استفاده می‌شود

برای حاشیه‌های عمودی از padding-block-start و padding-block-end

برای موقعیت و مرزها از border-inline و inset-block استفاده می‌شود

مزایا و کاربردها:

بین‌المللی‌سازی
در محصولاتی که چند زبان پشتیبانی می‌کنند، logical properties باعث صرفه‌جویی در زمان تنظیم استایل‌ها می‌شود.

طرح‌های قابل تغییر جهت
برای کامپوننت‌هایی که ممکن است «برگردانده» شوند (مثل آواتار سمت چپ/راست یا سایدبار)، logical properties نیاز به شرط‌نویسی در CSS را حذف می‌کند.

/* روش قدیمی */
.card {
padding-top: 12px;
padding-left: 16px;
}

/* با ویژگی‌های منطقی */
.card {
padding-block-start: 12px;
padding-inline-start: 16px;
}

/* خلاصهٔ کوتاه:
margin-inline — حاشیه‌های افقی
margin-block — حاشیه‌های عمودی
padding-inline — فاصله داخلی افقی
padding-block — فاصله داخلی عمودی
inset-inline — موقعیت افقی (چپ/راست)
inset-block — موقعیت عمودی (بالا/پایین) */




#️⃣#tip #css
👥@IR_javascript_group
🆔@IR_javascript
📸 ویژگی‌های loading`، `decoding و fetchpriority — چگونه با ویژگی‌های بومی، بارگذاری تصاویر را سریع‌تر کنیم

سه ویژگی ساده و بومی HTML وجود دارند که می‌توانند بارگذاری تصاویر را بسیار سریع‌تر کرده و رابط کاربری شما را پاسخگوتر کنند. اگرچه تمام مرورگرهای مدرن از آن‌ها پشتیبانی می‌کنند، اما در عمل به ندرت استفاده می‌شوند. در ادامه هر یک را بررسی می‌کنیم:

⬅️ `loading="lazy"` — بارگذاری تنبل

ویژگی loading="lazy" باعث می‌شود مرورگر بارگذاری تصاویر خارج از دید کاربر را به تعویق بیندازد. این کار ترافیک کاربر را کاهش می‌دهد، زمان تا تعامل کامل (TTI) را کم می‌کند و فشار روی دستگاه‌های ضعیف را کاهش می‌دهد. از این ویژگی برای تمام تصاویر زیر اولین صفحه، کارت‌ها، فهرست‌ها و گالری‌ها استفاده کنید.
⚠️ اما برای تصاویر مهم در بالای صفحه، مانند لوگو یا تصاویر Hero، از این ویژگی استفاده نکنید تا از تأخیر در بارگذاری جلوگیری شود.

⚡️ `decoding="async"` — رمزگشایی غیرهمزمان

ویژگی async به مرورگر اجازه می‌دهد تصاویر را به صورت غیرهمزمان رمزگشایی کند**، بدون اینکه رندر سایر عناصر را متوقف کند. این کار باعث کاهش تأخیرهای بصری و افزایش سرعت بارگذاری صفحات می‌شود. به‌ویژه برای تصاویر بزرگ و عناصر در فیدها یا لیست‌ها مفید است و تجربهٔ کاربری روان‌تر را فراهم می‌کند.

🔫
fetchpriority="high | low" — مدیریت اولویت بارگذاری**

این ویژگی تعیین می‌کند که تصویر با چه اولویتی بارگذاری شود: high برای بارگذاری فوری و low برای بارگذاری با تأخیر. استفاده از آن باعث کاهش رقابت منابع، افزایش سرعت LCP و کاهش تأخیرهای بصری در رندر صفحه می‌شود.

👀 نمونه‌ها و نحوهٔ استفادهٔ ترکیبی

<!-- بارگذاری تنبل -->
<img src="hero.png" loading="lazy" />

<!-- رمزگشایی غیرهمزمان -->
<img src="photo.jpg" decoding="async" />

<!-- مدیریت اولویت بارگذاری -->
<img src="hero.jpg" fetchpriority="high" />
<img src="avatar.jpg" loading="lazy" fetchpriority="low" />

<!-- ترکیب همه ویژگی‌ها -->
<img src="hero.jpg" decoding="async" fetchpriority="high" />
<img src="thumb.jpg" loading="lazy" decoding="async" fetchpriority="low" />


استفاده از این سه ویژگی به‌صورت هوشمندانه می‌تواند سرعت بارگذاری تصاویر و تجربهٔ کاربری سایت شما را به طور قابل توجهی بهبود دهد.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍2
📣 همگام‌سازی وضعیت بین تب‌ها: BroadcastChannel، SharedWorker و localStorage

وقتی کاربر چند تب از یک اپلیکیشن را باز می‌کند، اغلب مشکل همگام‌سازی وضعیت پیش می‌آید. مثلاً کاربر در یک تب از حساب کاربری خارج می‌شود، اما در تب‌های دیگر اپلیکیشن همچنان او را وارد شده فرض می‌کند. در سال ۲۰۲۵ چند ابزار برای حل این مسئله داریم: BroadcastChannel**، **SharedWorker و برای مرورگرهای قدیمی، localStorage.

---

BroadcastChannel — راه‌حل ساده برای همگام‌سازی پیام‌ها

این API امکان ارسال و دریافت پیام‌ها بین تب‌ها را به صورت همزمان فراهم می‌کند. مناسب برای:

* اطلاع‌رسانی ورود/خروج
* انتخاب تم
* به‌روزرسانی کش
* اطلاع از نسخهٔ جدید اپلیکیشن

مزایا: ساده، سریع، کار در پس‌زمینه
محدودیت‌ها: وضعیت مشترک پیچیده را پشتیبانی نمی‌کند

// BroadcastChannel
const channel = new BroadcastChannel("session");

channel.onmessage = (e) => {
console.log("message:", e.data);
};

channel.postMessage({ loggedOut: true });


---

SharedWorker — وقتی همه تب‌ها مثل یک اپلیکیشن عمل می‌کنند

ابزاری برای کار متمرکز بین تب‌ها که امکان همگام‌سازی وضعیت، کشینگ و مدیریت درخواست‌ها را فراهم می‌کند. مناسب برای اپلیکیشن‌هایی که نیاز به هماهنگی بین تب‌ها دارند.

مزایا: ذخیرهٔ مرکزی وضعیت، اشتراک منابع، کاهش درخواست‌های تکراری API
محدودیت‌ها: در Safari پشتیبانی نمی‌شود، دیباگ پیچیده و نیاز به معماری حساب‌شده دارد

// main.js
const worker = new SharedWorker("worker.js");
worker.port.postMessage({ type: "ping" });
worker.port.onmessage = (e) => console.log(e.data);

// worker.js
onconnect = (e) => {
const port = e.ports[0];
port.onmessage = () => port.postMessage("pong");
};


---

LocalStorage + storage event — روش قدیمی ولی کارآمد

یکی از ساده‌ترین روش‌های همگام‌سازی داده‌ها، مناسب برای:

* مرورگرهای قدیمی
* پروژه‌هایی بدون ServiceWorker یا SharedWorker
* سناریوهای سادهٔ همگام‌سازی تب‌ها

مزایا: پیاده‌سازی ساده، سازگاری بالا
محدودیت‌ها: فقط رشته‌ها ذخیره می‌شوند، رویداد storage در تب تغییر دهنده رخ نمی‌دهد و ممکن است کندتر از BroadcastChannel باشد

// LocalStorage + storage event
window.addEventListener("storage", (e) => {
if (e.key === "logout") {
// همگام‌سازی وضعیت
}
});


---

📌 جمع‌بندی:

* برای اعلان‌ها و رویدادهای ورود/خروج → BroadcastChannel
* برای اشتراک وضعیت در PWA و داشبوردها → SharedWorker
* برای مرورگرهای قدیمی → localStorage + storage event

هر ابزار ویژگی‌های خاص خود را دارد و انتخاب آن بستگی به پیچیدگی پروژه، مرورگرهای هدف و نوع داده‌ها دارد.


#️⃣#tip
👥@IR_javascript_group
🆔@IR_javascript
👍1