لو dashboard بتاعك بيتجمّد 4 ثواني كل ما المستخدم يرفع ملف CSV حجمه 80MB، المشكلة مش في حجم الملف ولا في سرعة اللاب. JavaScript بيشتغل على thread واحد، وأي عملية parsing بتقفل الـ UI كله — مفيش scroll، مفيش click، حتى الـ animation بيقف.
Web Workers بـ 30 سطر بتنقل العملية الثقيلة دي لـ thread موازي، فالـ UI يفضل سلس 60fps والمستخدم يقدر يلغي العملية لو غيّر رأيه.
Web Workers: التوازي اللي JavaScript مكنش بيعرفه
المشكلة باختصار
JavaScript في المتصفح بيشتغل على main thread واحد. الـ thread ده مسؤول عن 4 حاجات في نفس الوقت: تنفيذ الكود، رسم الصفحة، الاستجابة للـ events (click, scroll, keyboard)، وتشغيل الـ animations.
لو دالة JavaScript بتاخد 800ms في الحساب، الـ 4 حاجات دي بتقف 800ms. المستخدم بيشوف الصفحة "متجمّدة"، وفي Chrome بيظهرله "Page Unresponsive" بعد 5 ثواني.
مثال للمبتدئ: مطعم الكاشير الواحد
تخيّل مطعم فيه كاشير واحد بيعمل كل حاجة: ياخد الطلب من العميل، يحضّر الأكل، يعمل الفاتورة، يستلم الفلوس، يرد الباقي. لو جه عميل عايز كباب — والكباب محتاج 12 دقيقة على الفحم — الكاشير هيقف 12 دقيقة قدام الفرن، والـ 18 عميل اللي ورا ميلاقوش حد يطلب منه. المطعم كله بيتجمّد لحد ما الكباب يخلص.
الحل المنطقي: تجيب طبّاخ في المطبخ. الكاشير يكتب الطلب على ورقة، يبعتها للمطبخ من الباب الجانبي، ويرجع يخدم العملاء. الطبّاخ يحضّر، وأول ما الأكل يبقى جاهز، يقول للكاشير "خد الطلب رقم 47". الكاشير ساعتها بس بيوقف ثانية يستلم.
الكاشير = main thread. الطبّاخ = Web Worker. ورقة الطلب = postMessage.
Web Worker علميًا
طبقًا لـ HTML Living Standard (قسم Web Workers)، الـ Web Worker هو script بيشتغل في خلفية المتصفح في execution context منفصل تمامًا عن الـ main thread. الفصل ده بمعنى الكلمة:
- مفيش shared memory افتراضيًا (إلا لو استخدمت SharedArrayBuffer صراحة).
- الـ Worker مش شايف الـ DOM ولا window ولا document.
- التواصل بين الـ main thread والـ Worker بيتم عبر
postMessage()اللي بيـ serialize البيانات (Structured Clone Algorithm).
الفصل ده هو السبب اللي بيخلّي Web Workers آمنة: مفيش race conditions على متغير مشترك زي ما بيحصل في threads بـ C++ أو Java.
5 خطوات لتشغيل Web Worker (بكود فعلي)
هنبني مثال واقعي: parsing لملف CSV 82MB فيه بيانات مبيعات (1.4 مليون صف).