Table of Contents
הבנה ושימוש בעובדי שירות ב- JavaScript עבור Offline Capabilities
משתמשי אינטרנט מודרניים מצפים לחוויות מיידיות, אמינות גם כאשר תנאי הרשת הם עניים או לא קיימים.עובדי שירות הם אבן הפינה של הציפייה הזאת, המאפשרים פרוגרסיבי Web Apps (PWAs) לעבוד לא מקוון, לטעון במהירות על חיבורים מרופפים, ולספק הודעות דחיפה.בניגוד לטכניקות מסורתיות, עובד שירות פועל כטקטורת הפעלה בתכניעה בתכניעה, העומדת בין הדפדפן לבין הרשת.
עובדי שירות אינם טכנולוגיה חדשה – הם נתמכת בדפדפנים מרכזיים במשך שנים רבות – אך הם נשארים תחת חסותם של קבוצות פיתוח רבות.כאשר נבנו נכון, הם משנים אפליקציית אינטרנט סטטית לחוויה חווייתית, דמוית אפליקציה.
מה זה עובד שירות?
שירות עבודה הוא קובץ JavaScript שפועל בהיקף גלובלי נפרד מעמוד האינטרנט שלך, על חוט משלו.אין לו גישה DOM ומתקשר עם הדף שלך רק דרך תפקידה העיקרי הוא לפעול כמתווכים לבקשות רשת: הדפדפן יכול לשלוח כל בקשה מעמוד האינטרנט שלך לשירות, אשר מחליט כיצד להגיב - מהרשת, מטמון או תגובה אישית.
מכיוון שהוא פועל ברקע, עובד שירות יכול להמשיך לפעול גם לאחר שהמשתמש סוגר את הדף שרשום אותו.זה הופך אותו אידיאלי למשימות כמו:
- (ב) ,0) תמיכה רשמית ב-FLT:1 - שירת דפים מכווצים כאשר הרשת אינה זמינה.
- (ב) עיין:0) נתונים מסנכרנים את ה- 1:1 - פעולות queuing תוך אי-נוחות ושולחים אותם כאשר קישוריות חוזרת.
- (ב) ,0) ,Pushהודעות ⁇ FLT:1 - קבלת הודעות מהשרת ולהציג אותם למשתמש גם כאשר האפליקציה אינה פתוחה.
- (ב) [ה]ההפצה של ה-[[המאה ה-1]] – נכסים קריטיים לפני הסגידה, כך שהאפליקציית נטענת מיד על ביקורים חוזרים.
עובדי שירות מסתמכים על דרישה ביטחונית קפדנית: הם עובדים רק תחת HTTPS (או על 1:1 לפיתוח) זה מגן על משתמשים מפני התקפות של אדם-בקרב שיכול לטבול עם התסריט.
שירות העבודה Lifecycle
עובד שירות מתקדם דרך מחזור חיים מוגדר היטב: רישום, התקנה, הפעלה ולאחר מכן טיפול idle / fetch.הבנת מחזור חיים זה חיוני כי זה קובע כאשר המשאבים הצפופים שלך להיות זמין וכאשר כיבים ישנים לנקות.
1.רישום
לפני שכל לוגיקה של Worker של השירות יכולה לפעול, הדף שלך חייב לרשום את התסריט.זה נעשה מהקובץ הראשי של JavaScript (בדרך כלל נקודת הכניסה של הדף) הרישום מודיע לדפדפן המיקום וההיקף של השירות.ההיקף מגדיר מי כתובות ה-URL שהשירות יכול לשלוט; באמצעות ברירת מחדל זה מנהל התסריט.
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(function(registration) {
console.log('Service Worker registered with scope:', registration.scope);
})
.catch(function(error) {
console.log('Registration failed:', error);
});
}
אם התסריט כבר קיים, הדפדפן משווה את התוכן של te-for-byte עם הגרסה שהותקנה בעבר.אם הוא השתנה, גרסה חדשה מותקנת ברקע בעוד הגרסה הישנה ממשיכה לשלוט בדפים.
2.תקנה
אירוע ה-FLT:3 הוא האירוע הראשון שהשירות שלך מקבל.זהו הזמן המושלם לפני הקוקאין את הקבצים החיוניים שהאפליקציות שלך צריכות לעבוד לא מקוון: הפגז, ה-CSS הליבה, JavaScript וכל דפי הנפילה.
const CACHE_NAME = 'my-cache-v1';
const urlsToCache = [
'/',
'/styles/main.css',
'/scripts/main.js',
'/offline.html'
];
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
אם כל הקבצים לא יהורידו במהלך FLT:5, שלב ההתקנה נכשל ומעבד השירות אינו נחשב מותקן.
3.פעולה
לאחר ההתקנה, הדפדפן ממתין עד שכל הדפים שנטעו עם עובד השירות הישן סגורים, ואז הוא יורה באירוע 6FLT.
self.addEventListener('activate', function(event) {
const cacheWhitelist = [CACHE_NAME];
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
if (cacheWhitelist.indexOf(cacheName) === -1) {
return caches.delete(cacheName);
}
})
);
})
);
});
(ב) ויקרא (ב) ב[[1924]], [[1924]]]], [[1924]]]], [[1924]]]], [[1924]]]], [[1924]]]]]]]], [[1924]]]]]]]], [[1924]]]]]]]]]]]]
4 אירועים
לאחר הפעלתו, עובד השירות מקשיב לאירועים 10.בכל פעם שהדפדפן יוזם בקשה מעמוד מבוקר, עובד השירות יכול ליירט אותו.בתוך מטפל האירוע שאתה מיישם את אסטרטגיית ההקצאה של בחירה.
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
// Cache hit - return response
if (response) {
return response;
}
return fetch(event.request);
}
)
);
});
אסטרטגיות ל Scenarios שונים
בחירת האסטרטגיה הנכונה של הגרד קובעת את האיזון בין טריות ומהירות.אין פתרון בגודל אחד לכל; משאבים שונים דורשים גישות שונות.
Cache-First (Cache ואחר כך Network)
הטוב ביותר עבור נכסים סטטיים שלעתים נדירות משתנים: תמונות, גופן, CSS.The Service Worker בודק את ה-Cache תחילה; אם נמצא, הוא חוזר מיד.אם לא, הוא מביא מרשת ומכאיב את התגובה.
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
return response || fetch(event.request).then(function(networkResponse) {
return caches.open(CACHE_NAME).then(function(cache) {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
});
})
);
});
רשת ראשית (רשת עם Cache Fallback)
אידיאלי עבור תוכן דינמי: נקודות קצה API, הזנות חדשות.נסה את הרשת קודם; אם היא נכשלת או מאוד איטי, לחזור לגרסה המצופה.זה מבטיח למשתמשים תמיד לראות את הנתונים האחרונים אלא אם הם לא במצב לא מקוון.
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch(event.request)
.then(function(networkResponse) {
return caches.open(CACHE_NAME).then(function(cache) {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
})
.catch(function() {
return caches.match(event.request);
})
);
});
סטלה-בזמן-Revalidate
הטוב ביותר עבור משאבים שאינם צריכים להיות טריים מיד: פרופיל avatars, RSS להאכיל.גיב מיד עם הגרסה המצופה, אבל גם להביא עדכון מהרשת ברקע.
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.open(CACHE_NAME).then(function(cache) {
return cache.match(event.request).then(function(cachedResponse) {
var fetchPromise = fetch(event.request).then(function(networkResponse) {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
return cachedResponse || fetchPromise;
});
})
);
});
רשת בלבד ו-Cache
(ב) למידע רגיש כגון פרטי בנקאות משתמשים, השתמש ב-FLT:0Network-ear OnlyFLT:1 (ללא גילוח) עבור תוכן סטטי לא מקוון טהור (למשל, ידני), FLT:2Cache-OnlyFLT 3).
תכונות Advanced Service Worker
מעבר ל-Chang, השירות פותח יכולות רקע חזקות.
רקע Sync
כאשר משתמש שולח טופס או שולח הודעה בזמן לא מקוון, אתה לא רוצה לאבד את הפעולה הזאת.
// In page script
navigator.serviceWorker.ready.then(function(registration) {
return registration.sync.register('sync-messages');
});
// In Service Worker
self.addEventListener('sync', function(event) {
if (event.tag === 'sync-messages') {
event.waitUntil(sendPendingMessages());
}
});
Sync רקע הוא אידיאלי עבור יישומי צ'אט, טופס הגשת, או כל תור נתונים הדורש עקביות בסופו של דבר.
« « « « « « ציות לדחוף
הודעות Push מגיעות לשרת ותעוררו את עובד השירות, אשר לאחר מכן מציג הודעה.זה עובד גם כאשר אפליקציית האינטרנט שלך סגורה, נותן PWAs תחושה Native.
self.addEventListener('push', function(event) {
const options = {
body: 'This notification was triggered by a push message.',
icon: '/icons/icon-192x192.png',
badge: '/icons/badge.png',
data: {
url: '/new-content'
}
};
event.waitUntil(
self.registration.showNotification('New Update', options)
);
});
לחיצה על ההודעה יכולה לפתוח כתובת URL מסוימת באמצעות אירוע 18FLT.
אבטחה וסקוט
עובדי שירות יכולים ליירט ולשנות בקשות, ולכן יש להגיש אותם על פני HTTPS כדי למנוע מתסריט זדוני להיות מוזרק.במהלך פיתוח מקומי, דפדפנים מאפשרים לעובדים בשירות ב-FLT:19 כ יוצא דופן.
(ה) ⁇ :0 ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
עובדים בשירות
הדפדפן Devtools חיוני לבדיקת התנהגות עובד השירות.ב-Chrome, פתח את ה-FLT:23 או ללכת ליישום - עובדי שירות.You יכול לראות את הסטטוס של כל עובד, להתחיל באופן ידני / לעצור אותם, ורישום ברור. Firefox מציע כלים דומים תחת: מחיקת.
טיפים נפוצים:
- (FLT:0)עדכון על שכפול מחדש של 1:1 - בChrome Devtools, לבדוק "עדכון על עומס" כך שמעבד שירות חדש מותקן בכל פעם שהדף מכווץ (שימושי במהלך הפיתוח).
- (ב) ,0) ע"י רשת (ב"ג) ,"התפרקו" (בתרגום חופשי: ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
- (ב) עיין במשאבים חצופים במחבת אחסון ה-Cache Storage כדי לאמת את אסטרטגיית הגילוח שלך.
- (ב) ,0) ⁇ (ב) , (במסגרת העבודה בשירות; הודעות מופיעות בקונסולת הרקע ב- Devtools.
תוצאות Implications
עובדי שירות יכולים לשפר באופן דרמטי את הביצועים הנתפסים, אך הם גם מציגים מורכבות.לעדיף משאבים רבים מדי במהלך ההתקנה יכול לעכב את "צעד ההתקנה" ולגרום להתקנה להיכשל אם מתרחשות בזמן.תרגול טוב הוא לטמון רק את הקליפה המינימלית ב-FLT:25 ו- lazily cache משאבים נוספים במהלך הבאת אירועים.
גודל ה-Cache מוגבל למקור (בדרך כלל כמה מאות מגה-בתים בדפדפנים ניידים) באופן חוזר קבצי מדיה גדולים יכולים למלא את המכסה הזו. השתמש ב- API (ראהFLT:26) כדי לפקח על השימוש.
מלכודת ביצועים נוספת: אם עובד השירות שלך מבצע חישוב כבד במשקל בתוך מטפל ה-FLT:27, הוא יכול לחסום או לעכב את התגובות ברשת.המשך להביא מטפלות קל משקל ולהשתמש בדפוסים סינכרוניים.
מלכודות נפוצות וכיצד להימנע מהם
- (ב) ,ב"ה', "ה', ויקרא י', ו"וְאֶת פְּאֶת עַמֶרְטַבְתָּבְתָּעָה" (בראשית כ"ד, כ"ד)
- (FLT:0) דף הנפילה בלתי-נכוד 1 (Uncached Fallback PageFLT:1), אם הדף הלא מקוון שלך אינו לפני הקפאה, משתמשים יראו דף שגיאה דפדפן.
- (ב) מבקשי השירות (בשורה הראשונה) להטמיע בקשות ל-Pod:0) ל-Broken POSTIR (FLT:1) – עובדי השירות יכולים ליירט בקשות POST, אך עליך להיזהר עם משיכתם.
- (ב) אם לא תתקשרו ל-[[1924]], [[1924]], [[1924]], [[1924]], [[1924]]]], [[1924]]]], [[1924]]]]]], [[1924]]]]]], [[1924]]]]]]]]
דוגמה אמיתית לעולם: A Simple Offline-Ready PWA
בואו ניצור את הכל ביחד, ניצור PWA קטן שמציק את הקליפה שלו ומספק קובץ לא מקוון של שירות שלם (ראהר' 34):
const CACHE_NAME = 'pwa-shell-v2';
const SHELL_URLS = [
'/',
'/index.html',
'/styles.css',
'/app.js',
'/offline.html'
];
// Install: pre‑cache shell
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
return cache.addAll(SHELL_URLS);
})
);
});
// Activate: clean old caches
self.addEventListener('activate', function(event) {
const cacheWhitelist = [CACHE_NAME];
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(name) {
if (!cacheWhitelist.includes(name)) {
return caches.delete(name);
}
})
);
}).then(function() {
return self.clients.claim();
})
);
});
// Fetch: network‑first for pages, cache‑first for static assets
self.addEventListener('fetch', function(event) {
if (event.request.mode === 'navigate') {
// Pages: try network, fall back to cache
event.respondWith(
fetch(event.request).then(function(networkResponse) {
// Update cache with fresh page
const responseClone = networkResponse.clone();
caches.open(CACHE_NAME).then(function(cache) {
cache.put(event.request, responseClone);
});
return networkResponse;
}).catch(function() {
return caches.match(event.request).then(function(cached) {
// If page not cached, show offline fallback
return cached || caches.match('/offline.html');
});
})
);
} else {
// Static assets: cache‑first
event.respondWith(
caches.match(event.request).then(function(cached) {
return cached || fetch(event.request).then(function(networkResponse) {
caches.open(CACHE_NAME).then(function(cache) {
cache.put(event.request, networkResponse.clone());
});
return networkResponse;
});
})
);
}
});
דוגמה זו משתמשת בגישה של רשת ראשונה לניווט (עמודי השבבים כאשר הם באינטרנט, ירידה לא מקוונת כאשר לא) ו- cache-First עבור כל הנכסים האחרים.הקוד מטפל בגרסת cacheing ביסודיות.
מסקנה
עובדי שירות הם עמוד השדרה של יישומי אינטרנט מודרניים שאינם ניתנים להשגה.הם מספקים שכבת רשת בת קיימא שעוברת הרבה מעבר ל-Cheching פשוטה: סינכרון רקע, דוחפים הודעות, ושליטה מלאה על האופן שבו המשאבים מוגשים. על ידי הבנת מחזור החיים, בחירת האסטרטגיה הנכונה של כל סוג משאבים, ולאחר שיטות אבטחה הטובות ביותר, אתה יכול לבנות חוויות אינטרנט שהן גמישות, מהירות, מרתקת.
(ב) לעיין במסמכים הרשמיים של ה-API:0 (MDNFelo) ו-FLT:2,Google Web Fundamentalssssert: For Advanced caching Patterns, the ההרחבה של ה-FLT:4Offline CookbookFLT:5 מאת ג'ייק ארכיב מציע מתכונים מפורטים עם רישום פשוט, בדיקה יסודית ב-Des, ו-Detchlss, עבור משתמשים.