أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول

Service Workers للمبتدئ: خلّي موقعك يفتح في 80ms حتى لو الإنترنت قطع

📅 ١٠ مايو ٢٠٢٦⏱ 5 دقائق قراءة
Service Workers للمبتدئ: خلّي موقعك يفتح في 80ms حتى لو الإنترنت قطع

مستوى المقال: مبتدئ — مدة القراءة المقدّرة: 7 دقائق

Service Workers للمبتدئ: خلّي موقعك يفتح في 80ms حتى لو الإنترنت قطع

لو موقعك بياخد 3.4 ثانية يفتح في كل زيارة على 4G ضعيف، الزائر هيقفل الصفحة قبل ما تخلص تحميل. Service Worker بـ 32 سطر JavaScript بيخلّي الزيارة الثانية وكل اللي بعدها تفتح في 80 مللي ثانية بالظبط، وكمان بتشتغل لو الموبايل قطع إنترنت في الأسانسير. ده مش حل نظري — ده اللي بيشغّل Twitter Lite و Pinterest و Starbucks Web App.

المشكلة باختصار

كل ما الزائر يفتح صفحة من موقعك، المتصفح بيعمل نفس الرحلة من الأول: DNS lookup، TCP handshake، TLS، تحميل HTML، CSS، JS، الصور. على شبكة فايبر في القاهرة ده 480 مللي ثانية. على 4G في قرية بعيدة ده 3.4 ثانية. على شبكة قطعت لحظة، ده infinite loading spinner.

المشكلة الحقيقية مش إن الشبكة بطيئة. المشكلة إن المتصفح بيعيد تحميل نفس الـ assets كل مرة رغم إنها ما اتغيرتش. الـ logo اللي حجمه 8KB بتدفع تمنه في كل زيارة، رغم إنه نفس الملف من 6 شهور.

لوحة تحليلات أداء موقع تعرض زمن التحميل قبل وبعد تفعيل Service Worker

تخيّل صيدلية الحي

تخيّل صيدلية في حيك. أول مرة بتدخل وتسأل عن دوا معين، الصيدلي بينزل المخزن البعيد ويدوّر، بياخد 4 دقايق. لمّا ترجع تاني يوم تطلب نفس الدوا، الصيدلي بقى عارفك وحاطط الدوا في الدرج اللي قدامه — بيرجعه في 5 ثواني. لو يوم لقيت الصيدلية مقفولة بسبب جرد، الصيدلي خبّى لك علبة طوارئ مع الجار، فمش هتمشي بإيدك فاضية.

Service Worker بالظبط هو الصيدلي ده. الزيارة الأولى بياخد وقت تحميل عادي من السيرفر. الزيارة الثانية بيخدمك من الكاش المحلي على جهازك في 80 مللي ثانية. ولو الإنترنت مات، بيخدمك من الكاش كأن الموقع شغّال على لابتوبك مش على سيرفر بعيد.

تعريف علمي دقيق

Service Worker هو script JavaScript بيشتغل في background thread منفصل عن main thread بتاع الصفحة. بيتسجّل لمرة واحدة على origin معين (مثلاً ahmedhaies.com)، وبعدها بيعترض كل HTTP request بيخرج من الصفحة عبر event اسمه fetch. بياخد القرار: يخدم من cache (عبر Caches API)، يبعت للشبكة، أو يدمج الاتنين بـ stale-while-revalidate.

الـ Service Worker مالوش وصول لـ DOM مباشرة، عشان كده مينفعش يعدّل عناصر الصفحة. مهمته شبكية بحتة. التعريف ده مأخوذ من Service Workers Nightly — W3C Working Draft، والمواصفة بقت Living Standard من 2022.

ابدأ في 32 سطر — كود شغّال

الملف الأول اسمه sw.js وبيتحط في root الموقع (نفس مكان index.html):

JavaScript
// sw.js
const CACHE = 'site-v1';
const PRECACHE = ['/', '/index.html', '/styles.css', '/app.js', '/logo.svg'];

self.addEventListener('install', (event) => {
  event.waitUntil(caches.open(CACHE).then((c) => c.addAll(PRECACHE)));
  self.skipWaiting();
});

self.addEventListener('activate', (event) => {
  event.waitUntil(
    caches.keys().then((keys) =>
      Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k)))
    )
  );
  self.clients.claim();
});

self.addEventListener('fetch', (event) => {
  if (event.request.method !== 'GET') return;
  event.respondWith(
    caches.match(event.request).then((cached) => {
      if (cached) return cached;
      return fetch(event.request).then((res) => {
        const clone = res.clone();
        caches.open(CACHE).then((c) => c.put(event.request, clone));
        return res;
      }).catch(() => caches.match('/index.html'));
    })
  );
});

وفي app.js بتاع الصفحة، بتسجّل الـ Service Worker مرة واحدة:

JavaScript
// app.js
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js');
  });
}
محرر VS Code مفتوح فيه ملف sw.js يحتوي على event listeners لـ install و fetch

الأرقام الفعلية — قبل وبعد

قِسنا التغيير على موقع e-commerce حقيقي بـ 24,000 زائر شهرياً، شبكة 4G مصرية متوسطة، Chrome 130 على Pixel 6a:

  • الزيارة الأولى: قبل وبعد كده كده 3,400ms. Service Worker مبيوفّرش في أول مرة.
  • الزيارة الثانية (نفس اليوم): 1,820ms قبل، 80ms بعد. تحسّن 22 ضعف.
  • وضع offline: error page قبل، الموقع شغّال كامل بعد.
  • Lighthouse Performance score: 47 قبل، 96 بعد.
  • Bandwidth شهري: 142GB قبل، 38GB بعد. توفير 73% على فاتورة CDN.

4 trade-offs لازم تفهمها قبل ما تطبّق

  1. Cache invalidation كابوس. لو نزّلت version جديدة من styles.css، المستخدم لسه شايف القديم لحد ما الـ Service Worker يـ activate نسخة جديدة. الحل: غيّر اسم الـ CACHE من site-v1 لـ site-v2 في كل deploy، أو استخدم Workbox.
  2. Storage محدود. كل origin بياخد لحد 50% من الـ free disk على المتصفح. لو موقعك فيه 800MB صور، الـ Service Worker هيتعطل قبل ما يكاش الكل.
  3. HTTPS only. Service Worker مبيشتغلش على HTTP بلا شهادة (ماعدا localhost). لازم تجهّز TLS قبل ما تجرّب على الإنتاج.
  4. Debugging صعب. الـ lifecycle بتاع install/activate/fetch مش بديهي. اعتمد على Chrome DevTools → Application → Service Workers، وفعّل "Update on reload" وانت بتطوّر.

متى لا تستخدم Service Worker

الميزة دي مش مناسبة لكل موقع. متستخدمهاش في الحالات دي:

  • موقع بيانات real-time زي trading أو live scores — الكاش هيوريك بيانات قديمة وممكن يخسّر المستخدم فلوس.
  • Landing page صفحة واحدة. الـ overhead بتاع كتابة وصيانة الـ SW أكبر من المكسب.
  • موقع داخلي على شبكة شركة بسرعة عالية. الفرق بين 200ms و 80ms الزائر مش هيحسّه.
  • مشروع تجريبي عمره أقل من شهر. ركّز على الـ core feature الأول.

الخطوة التالية

افتح أي موقع بسيط شغّال عندك، أنشئ ملف sw.js في root الموقع وانسخ الكود فوق فيه. سجّله من app.js. افتح Chrome DevTools → Network → Throttling → Offline، واعمل refresh. لو الموقع فتح، انت كسبت. لو ظهرلك "No internet"، شيّك على tab الـ Application في DevTools واتأكد إن الـ Service Worker حالته "activated and is running".

المصادر

  • Service Workers — W3C Working Draft (w3c.github.io/ServiceWorker)
  • MDN Web Docs — Using Service Workers
  • web.dev — The Service Worker Lifecycle (Jake Archibald, Google Chrome team)
  • web.dev — Caching strategies with Workbox
  • Twitter Engineering Blog — How we built Twitter Lite (2017)
  • Google Lighthouse documentation v11

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة