التسجيل
الصفحة هي اللي بتقول للمتصفح “في Service Worker هنا”:
main.js
if ("serviceWorker" in navigator) { navigator.serviceWorker.register("/sw.js", { scope: "/" });}الـ scope هو المسارات اللي الـ SW هيمسكها. ملف في /app/sw.js مش هيقدر يمسك / إلا لو السيرفر سمح بـ header خاص، فالأسهل تحطه في جذر المسار اللي عايزه.
المراحل
- register() ← install: أول مرة أو ملف اتغير
- install ← waiting: لسه في تابات قديمة
- waiting ← activate: قفلت كل التابات
- install ← activate: skipWaiting()
- activate ← fetch: clients.claim()
📥 install
بيحصل مرة واحدة لكل نسخة. مكان مناسب تحفظ فيه الملفات اللي لازم تبقى موجودة، زي صفحة الـ offline.
🧹 activate
النسخة دي بقت المسؤولة. مكان مناسب تمسح فيه الكاش بتاع النسخ القديمة.
sw.js
const SHELL = "shell-v2";self.addEventListener("install", (event) => { // waitUntil: متعتبرش الـ install خلص غير لما الـ promise يخلص event.waitUntil(caches.open(SHELL).then((c) => c.addAll(["/offline.html"])));});self.addEventListener("activate", (event) => { event.waitUntil( caches.keys().then((keys) => Promise.all(keys.filter((k) => k.startsWith("shell-") && k !== SHELL).map((k) => caches.delete(k))), ), );});self.addEventListener("fetch", (event) => { // هنا بنقرر نرد منين (الفصل الجاي)});ليه في مرحلة waiting؟
لو عندك تابة مفتوحة شغالة بالـ SW القديم، والنسخة الجديدة مسكت فجأة، ممكن الصفحة القديمة تطلب ملف مبقاش موجود في الكاش الجديد. عشان كده المتصفح بيخلّي الجديد مستني لحد ما كل التابات القديمة تتقفل.
المتصفح بيعرف إن في نسخة جديدة إزاي؟
لما تفتح صفحة في الـ scope، المتصفح بيجيب sw.js من السيرفر ويقارنه بايت ببايت باللي عنده. أي فرق، حتى حرف في تعليق، يبدأ install للنسخة الجديدة.
- فتحت الصفحة ← sw.js على السيرفر: هات sw.js
- sw.js على السيرفر ← زي ما هو: نفس البايتات
- sw.js على السيرفر ← اتغير: مختلف
خلّصت الفصل لما
🧠 اختبر نفسك
١) غيّرت ملف CSS بس، والـ sw.js زي ما هو. هيحصل install؟
لأ. الـ install بيحصل لما sw.js نفسه يتغير.
٢) نزّلت نسخة جديدة والمستخدم فاتح تابتين. الجديدة شغالة؟
لأ، مستنية في waiting لحد ما يقفلهم، إلا لو عملت skipWaiting.
٣) فين أمسح الكاش القديم؟
في activate، عشان النسخة القديمة متكونش لسه بتستخدمه.