رقصنده با کد
782 subscribers
1.69K photos
850 videos
207 files
666 links
Here are some interesting things I've come across during my learning process. That's it. Admin ID:
@alithecodeguy
Download Telegram
📜 قابلیت Web Worker در مرورگر چیست و چرا باید از آن استفاده کنیم؟

قابلیت Web Worker به شما اجازه می‌دهد که کدهای JavaScript را در یک thread جداگانه اجرا کنید، مستقل از thread اصلی مرورگر. این یعنی می‌توانید عملیات‌های سنگین را بدون تأثیر روی UI انجام دهید و رابط کاربری روان باقی بماند.

🔰 مزایای استفاده از Web Worker

• جلوگیری از هنگ کردن رابط کاربری در زمان انجام محاسبات سنگین
• اجرای عملیات پردازشی سنگین خارج از thread اصلی
• افزایش کارایی در اپلیکیشن‌هایی مانند:
- پردازش تصویر یا ویدیو
- تجزیه فایل‌های JSON حجیم
- مرتب‌سازی یا فیلتر داده‌ها
- انجام محاسبات بلادرنگ (Real-time)
- سینک شدن اطلاعات در پس‌زمینه

🌀 انواع Web Worker

1️⃣ نوع Dedicated Worker: مخصوص یک صفحه یا اسکریپت خاص است و فقط همان صفحه می‌تواند با آن ارتباط داشته باشد. مناسب برای پردازش تصویر و عملیات سنگین تک‌صفحه‌ای است.

- این نوع Worker برای اجرای عملیات پردازشی سنگین که نباید رابط کاربری (UI) را مختل کند، بسیار مناسب است.

- مثل یک نخ (thread) مجزاست که در پس‌زمینه اجرا می‌شود و از طریق ارسال و دریافت پیام با thread اصلی در ارتباط است.

ویژگی‌های اصلی Dedicated Worker

- فقط توسط اسکریپتی که آن را ساخته قابل دسترسی است
- در background اجرا می‌شود
- به DOM دسترسی ندارد
- با postMessage و onmessage داده رد و بدل می‌کند
- می‌توان از importScripts() برای بارگذاری اسکریپت‌های دیگر درون آن استفاده کرد
- هنگام اتمام کار می‌توان با terminate() آن را متوقف کرد
- باید از مسیر مجزا (URL) بارگذاری شود؛ نمی‌توان inline نوشت مگر با Blob
- می‌توان چند Worker همزمان ساخت
- می‌توان از structuredClone برای ارسال داده‌های پیچیده استفاده کرد

کاربردهای متداول Dedicated Worker

- پردازش سنگین ریاضی (محاسبه، شبیه‌سازی، الگوریتم‌ها)
- فیلتر کردن داده‌ها (مثلاً لیست‌های بزرگ)
- رمزنگاری یا هش کردن
- پردازش تصویر (فیلتر، بلور، resize)
- پارس کردن JSON یا فایل‌های بزرگ

‍main.js

const worker = new Worker("worker.js");

worker.postMessage("Hello Worker!");

worker.onmessage = function (e) {
console.log("Received from worker:", e.data);
};

worker.js

onmessage = function (e) {
console.log("Received from main:", e.data);
postMessage("Hi Main!");
};


2️⃣ نوع Shared Worker: چندین صفحه یا تب می‌توانند به یک Shared Worker دسترسی داشته باشند. مناسب برای چت‌های همزمان بین چند تب یا مدیریت داده‌های مشترک است.

می‌تونه بین چند تب، iframe یا حتی چند اسکریپت در یک صفحه مشترک استفاده بشه.

برخلاف Dedicated Worker که فقط یک ارتباط بین یک صفحه و یک Worker برقرار می‌کنه، Shared Worker می‌تونه بین چند بخش مختلف از برنامه ارتباط مشترک ایجاد کنه.

ویژگی‌های اصلی Shared Worker

- قابلیت اشتراک‌گذاری بین چند تب یا iframe
- مدیریت داده‌ی مشترک بین چند بخش از یک یا چند صفحه
- ارتباط از طریق پورت (port) انجام می‌شه
- فقط یک نمونه در مرورگر ساخته می‌شه و همه‌ی تب‌ها از همون استفاده می‌کنن
- به DOM دسترسی نداره
- به‌درد اپلیکیشن‌های real-time یا multi-tab خیلی می‌خوره
- می‌تونی آرایه‌ای از portها رو درون Worker نگه داری و پیام‌ها رو به همه broadcast کنی
- از BroadcastChannel API هم می‌شه به‌صورت ترکیبی استفاده کرد
- فقط اولین بار که تب باز می‌شه Worker جدید ساخته می‌شه، بقیه تب‌ها به همون متصل می‌شن
- در برخی نسخه‌های قدیمی Safari و IE پشتیبانی نمی‌شه
ارتباط کمی پیچیده‌تر از Dedicated Worker داره چون از port استفاده می‌کنه
- باید حواست باشه که Worker ممکنه از قبل در حال اجرا باشه (shared lifecycle)

کاربردهای واقعی Shared Worker

- چت real-time بین تب‌ها
- هماهنگ‌سازی لاگین یا لاگ‌اوت بین تب‌ها
- نگهداری وضعیت session به‌صورت مرکزی
- اشتراک‌گذاری connection به WebSocket بین تب‌ها (صرفه‌جویی در منابع)
- اعمال throttle یا debouncing روی درخواست‌های همزمان از چند تب

shared-worker.js

onconnect = function (e) {
const port = e.ports[0];
port.onmessage = function (e) {
port.postMessage("Shared: " + e.data);
};
};

main.js

const worker = new SharedWorker("shared-worker.js");
worker.port.start();
worker.port.postMessage("Hi Shared Worker");

worker.port.onmessage = (e) => {
console.log(e.data);
};

#worker @danceswithcode

ادامه در پست بعد
رقصنده با کد
📜 قابلیت Web Worker در مرورگر چیست و چرا باید از آن استفاده کنیم؟ قابلیت Web Worker به شما اجازه می‌دهد که کدهای JavaScript را در یک thread جداگانه اجرا کنید، مستقل از thread اصلی مرورگر. این یعنی می‌توانید عملیات‌های سنگین را بدون تأثیر روی UI انجام دهید…
3️⃣ نوع Service Worker: مثل یک پروکسی بین مرورگر و شبکه عمل می‌کند. کاربرد آن بیشتر در PWAها، کش کردن منابع، و پشتیبانی از حالت آفلاین است.

ویژگی‌های کلیدی Service Worker

- در پس‌زمینه اجرا می‌شود
- مستقل از تب‌ها و صفحات است
- فقط از طریق HTTPS یا localhost کار می‌کند
- رویدادمحور (event-driven) است
- به DOM دسترسی ندارد
- می‌تواند حتی وقتی تب بسته است هم کار کند (مثلاً Push Notification)

Lifecycle (چرخه‌ی عمر)

۱. Install
برای اولین بار که Service Worker ثبت می‌شود، فایل آن نصب می‌شود. در این مرحله می‌توان منابع لازم را cache کرد.

۲. Activate
بعد از نصب موفق، فعال می‌شود. این مرحله برای پاک‌سازی cacheهای قدیمی هم کاربرد دارد.

۳. Fetch
هر بار که مرورگر درخواستی (مثلاً fetch یا load) ارسال می‌کند، Service Worker آن را رهگیری می‌کند و می‌تواند پاسخ را از cache یا شبکه بدهد.

استراتژی‌های caching مهم

۱. Cache First: اول از cache بخون، اگر نبود برو سراغ شبکه
۲. Network First: اول از شبکه بیار، اگر قطع بود از cache استفاده کن
۳. Stale-While-Revalidate: از cache نشون بده، در پس‌زمینه یک نسخه جدید بگیر
۴. Cache Only: فقط از cache استفاده کن
۵. Network Only: فقط از شبکه استفاده کن

معرفی ابزار حرفه‌ای: Workbox

ابزار Workbox کتابخانه‌ای از گوگل هست که ساخت و مدیریت Service Workerها را خیلی راحت‌تر و حرفه‌ای‌تر می‌کنه.

مزایا:
- سادگی استفاده
- پشتیبانی از استراتژی‌های caching مختلف
- تولید اتوماتیک فایل cache در زمان build
- عالی برای پروژه‌های React، Vue، Next.js و …

قابلیت‌های ویژه Service Worker

- Push Notification
دریافت پیام از سرور حتی وقتی تب بسته‌ست
- Background Sync
ارسال داده به سرور زمانی که اینترنت وصل می‌شود
- App Shell Model
مناسب برای PWAها؛ صفحات سریع و آفلاین
- Offline fallback
وقتی اینترنت قطع بود، صفحه‌ای مخصوص نشون بده

محدودیت‌ها و نکات امنیتی

- فقط در HTTPS یا localhost کار می‌کند
- به DOM دسترسی ندارد
- باید در root domain ثبت شود (مثلاً /sw.js نه /pages/sw.js)
- نسخه‌های قدیمی باید مدیریت شوند و cacheها پاک شوند
- زمان‌بندی دقیقی برای اجرای آن نیست (مرورگر تصمیم می‌گیرد)

کاربردهای واقعی Service Worker

- ساخت اپلیکیشن آفلاین (مانند Google Docs)
- ارسال اعلان بدون باز بودن تب
- کاهش مصرف داده با cache هوشمند
- نمایش fallback page هنگام قطعی اینترنت
- پشتیبانی از background sync برای فرم‌های آفلاین



Register it:

if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(() => console.log("SW Registered"));
}

sw.js

self.addEventListener('install', (event) => {
console.log("Service Worker installing.");
});

self.addEventListener('fetch', (event) => {
console.log("Intercepting fetch:", event.request.url);
});


#worker @danceswithcode

ادامه در پست بعد
رقصنده با کد
3️⃣ نوع Service Worker: مثل یک پروکسی بین مرورگر و شبکه عمل می‌کند. کاربرد آن بیشتر در PWAها، کش کردن منابع، و پشتیبانی از حالت آفلاین است. ویژگی‌های کلیدی Service Worker - در پس‌زمینه اجرا می‌شود - مستقل از تب‌ها و صفحات است - فقط از طریق HTTPS یا localhost…
4️⃣ نوع Module Worker: نوع جدیدی از Web Worker است که با type: "module" ساخته می‌شود و اجازه می‌دهد از import/export استفاده کنی. برای برنامه‌نویسی ماژولار در Web Worker بسیار مفید است.

- امکان استفاده از import/export در Worker
- سازگاری با معماری ماژولار (modular) و قابل نگهداری
- بدون نیاز به importScripts (که مخصوص اسکریپت‌های کلاسیکه)
- قابل استفاده در پروژه‌های مدرن با ابزارهایی مثل Vite، Webpack، Rollup و ESBuild
- پشتیبانی کامل در مرورگرهای مدرن (Chrome, Edge, Firefox, Safari)

math-worker.js


mport { heavySum } from './utils.js';

self.onmessage = (event) => {
const n = event.data;
const result = heavySum(n);
self.postMessage(result);
};


utils.js


export function heavySum(n) {
let sum = 0;
for (let i = 1; i <= n; i++) {
sum += i;
}
return sum;
}


main.js


const worker = new Worker('./math-worker.js', { type: 'module' });

worker.postMessage(1000000);

worker.onmessage = (e) => {
console.log(" پاسخ از Module Worker:", e.data);
};


توجه: اگر type: "module" رو ننویسی، مرورگر فایل رو به‌صورت classic script تفسیر می‌کنه و استفاده از import/export باعث ارور syntax می‌شه.

- مسیر فایل باید نسبی یا مطلق صحیح باشه (./worker.js یا /js/worker.js)
- فایل‌ها باید از روی سرور (یا localhost) اجرا بشن — اجرا از فایل سیستمی (file://) معمولا خطا می‌ده
- اگر از ابزارهایی مثل Webpack یا Vite استفاده می‌کنی، باید loader مخصوص Web Worker یا plugin استفاده کنی
- نمی‌تونی از CDN (مثل unpkg) مستقیم توی Worker import کنی مگر اینکه CORS اجازه بده


const worker = new Worker("module-worker.js", { type: "module" });

module-worker.js

import { helper } from './helper.js';
onmessage = e => {
postMessage(helper(e.data));
};


5️⃣ نوع Worklet: اسکریپت‌های بسیار سبک و کوچک که برای کارهایی مثل افکت‌های بصری (CSS Houdini) یا پردازش صدا (Web Audio API) به کار می‌روند. سریع و کم‌هزینه هستند ولی محدودتر از سایر Workerها.
مثل:
- 🎨 ‌CSS Houdini (Paint Worklet)
- 🔊 Web Audio API (Audio Worklet)
- 📐 Layout Worklet (درحال توسعه)

- نه thread جداگانه داره و نه access به اغلب APIهای معمول مرورگر
- در محیطی ultra-sandboxed اجرا می‌شه
- حتی خیلی از APIهای پایه (مثل fetch, setTimeout, console.log) هم در اون‌ها وجود نداره

مثال: Paint Worklet (CSS Houdini)

paint.js

registerPaint('circle', class {
paint(ctx, geom, properties) {
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(geom.width / 2, geom.height / 2, 40, 0, 2 * Math.PI);
ctx.fill();
}
});


Register in main.js:

if ('paintWorklet' in CSS) {
CSS.paintWorklet.addModule('paint.js');
}

css

.my-box {
width: 100px;
height: 100px;
background: paint(circle);
}


مرورگر در لحظه‌ی رندر paint(circle)، تابع paint() رو از فایل paint.js اجرا می‌کنه.

مثال: Audio Worklet

processor.js

class WhiteNoiseProcessor extends AudioWorkletProcessor {
process(inputs, outputs, parameters) {
const output = outputs[0];
output.forEach(channel => {
for (let i = 0; i < channel.length; i++) {
channel[i] = Math.random() * 2 - 1;
}
});
return true;
}
}

registerProcessor('white-noise', WhiteNoiseProcessor);

main.js

const audioContext = new AudioContext();
await audioContext.audioWorklet.addModule('processor.js');
const node = new AudioWorkletNode(audioContext, 'white-noise');
node.connect(audioContext.destination);

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

#worker @danceswithcode

این مطلب در قالب سه پست ، تکمیل شد