Service Worker Caching Strategy - team-yaza/mozi-client GitHub Wiki
κ°μ
μλΉμ€ μ컀λ₯Ό ν¨κ³Όμ μΌλ‘ μ¬μ©νλ €λ©΄ μΊμ± μ λ΅μ μ μ ννλ κ²μ΄ μ€μνλ€. μΊμ± μ λ΅μ μΈμ°λ €λ©΄ Cache μΈν°νμ΄μ€μ λν μ΄ν΄κ° νμνλ€.
μΊμ± μ λ΅μ μλΉμ€ μ컀μ fetch
μ΄λ²€νΈμ Cache
μΈν°νμ΄μ€ κ°μ μνΈ μμ©μ΄λ€. μλ₯Ό λ€μ΄ μ μ μμμ λν μμ²μ λ¬Έμμ λ€λ₯΄κ² μ²λ¦¬νλ κ²μ΄ λ°λμ§ν μ μμΌλ©° μ΄λ μΊμ± μ λ΅μ΄ ꡬμ±λλ λ°©μμ μν₯μ λ―ΈμΉλ€.
Cache interface vs HTTP Cache
Cache μΈν°νμ΄μ€μ HTTP Cacheλ κ΄λ ¨μ΄ μλ€.
- The Cache interface is a caching mechanism entirely separate from the HTTP cache.
- Whatever Cache-Control configuration you use to influence the HTTP cache has no influence on what assets get stored in the Cache interface.
HTTP μΊμμ μν₯μ μ£ΌκΈ° μν΄ μ¬μ©λλ Cache-Control ꡬμ±μ Cache μΈν°νμ΄μ€μ μν₯μ λ―ΈμΉμ§ λͺ»νλ―λ‘, λΈλΌμ°μ μΊμλ₯Ό κ³μΈ΅νλ κ²μΌλ‘ μκ°ν μ μλ€.
HTTP μΊμλ HTTP ν€λμ ννλ μ§μλ¬Έκ³Ό ν¨κ» ν€-κ° μμ μν΄ κ΅¬λλλ μ μμ€ μΊμμ΄λ€. μ΄μ λμ‘°μ μΌλ‘ Cache μΈν°νμ΄μ€ JavaScript APIμ μν΄ κ΅¬λλλ κ³ κΈ μΊμμ΄λ€.
Cache μΈν°νμ΄μ€λ μλμ μΌλ‘ λ¨μν HTTP ν€-κ° μμ μ¬μ©ν λλ³΄λ€ λ λ§μ μ μ°μ±μ μ 곡νλ©° μΊμ± μ λ΅μ κ°λ₯νκ²ν©λλ€. μλΉμ€ μ컀 μΊμμ κ΄λ ¨λ λͺκ°μ§ μ€μν APIλ λ€μκ³Ό κ°μ΅λλ€.
- CacheStorage.open
- Cache.add & Cache.put
- Cache.match (to locate a cached response in a Cache instance)
- Cache.delete (to remove a cached response from a Cache instance)
fetch event
μλλ fetch eventμ Cache μΈν°νμ΄μ€μ μμ μ½λμ΄λ€.
// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';
self.addEventListener('install', (event) => {
event.waitUntil(caches.open(cacheName));
});
self.addEventListener('fetch', async (event) => {
// Is this a request for an image?
if (event.request.destination === 'image') {
// Open the cache
event.respondWith(caches.open(cacheName).then((cache) => {
// Respond with the image from the cache or from the network
return cache.match(event.request).then((cachedResponse) => {
return cachedResponse || fetch(event.request.url).then((fetchedResponse) => {
// Add the network response to the cache for future visits.
// Note: we need to make a copy of the response to save it in
// the cache and use the original as the request response.
cache.put(event.request, fetchedResponse.clone());
// Return the network response
return fetchedResponse;
});
});
}));
} else {
return;
}
});
- Inspect the request's destination property to see if this is an image request.
- If the image is in the service worker cache, serve it from there. If not, fetch the image from the network, store the response in the cache, and return the network response.
- All other requests are passed through the service worker with no interaction with the cache.
fetch μ΄λ²€νΈ κ°μ²΄λ κ° μμ²μ μ νμ μλ³νλλ° λμμ΄ λλ λͺκ°μ§ μ μ©ν μ λ³΄κ° μλ μμ² μμ±μ΄ ν¬ν¨λμ΄ μλ€.
url
: which is the URL for the network request currently being handled by the fetch event.method
: which is the request method (e.g, GET or POST)mode
: which describes the request's mode. A value of 'navigate' is often used to distinguish requests for HTML documents from other requests.destination
: which describes the type of content being requested in a way that avoids using the requested asset's file extension.
Caching Strategies
Cache Only
Cache Only
λ μλΉμ€ μμ»€κ° νμ΄μ§λ₯Ό μ μ΄ν λ μΌμΉνλ μμ²μ μΊμλ‘λ§ μ΄λν©λλ€.
μ¦, μ΄ ν¨ν΄μ΄ μλνλ €λ©΄ assetμ 미리 μΊμν΄μΌλλ©° μλΉμ€ μμ»€κ° μ
λ°μ΄νΈλ λκΉμ§ ν΄λΉ μμ°μ΄ μΊμμμ μ
λ°μ΄νΈλμ§ μμ΅λλ€.
// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';
// Assets to precache
const precachedAssets = [
'/possum1.jpg',
'/possum2.jpg',
'/possum3.jpg',
'/possum4.jpg'
];
self.addEventListener('install', (event) => {
// Precache assets on install
event.waitUntil(caches.open(cacheName).then((cache) => {
return cache.addAll(precachedAssets);
}));
});
self.addEventListener('fetch', (event) => {
// Is this one of our precached assets?
const url = new URL(event.request.url);
const isPrecachedRequest = precachedAssets.includes(url.pathname);
if (isPrecachedRequest) {
// Grab the precached asset from the cache
event.respondWith(caches.open(cacheName).then((cache) => {
return cache.match(event.request.url);
}));
} else {
// Go to the network
return;
}
});
μ μ½λμμ assetλ€μ install νμμ 미리 μΊμλλ€.
μλΉμ€μμ»€κ° fetch μ΄λ²€νΈλ₯Ό μ²λ¦¬ν λ μμ² URLμ΄ precached assetsμ μλμ§ νμΈνκ³ μλ€λ©΄ cacheλ₯Ό 리ν΄νλ€. λ€λ₯Έ 리μμ€λ networkλ‘ μμ²μ λ³΄λΌ κ²μ΄λ€.
Cache first, falling back to network
- The request hits the cache. If the asset is in the cache, serve it from there.
- If the request is not in the cache, go to the network.
- Once the network request finishes, add it to the cache, then return the response from the network.
// Establish a cache name
const cacheName = 'MyFancyCacheName_v1';
self.addEventListener('fetch', (event) => {
// Check if this is a request for an image
if (event.request.destination === 'image') {
event.respondWith(caches.open(cacheName).then((cache) => {
// Go to the cache first
return cache.match(event.request.url).then((cachedResponse) => {
// Return a cached response if we have one
if (cachedResponse) {
return cachedResponse;
}
// Otherwise, hit the network
return fetch(event.request).then((fetchedResponse) => {
// Add the network response to the cache for later visits
cache.put(event.request, fetchedResponse.clone());
// Return the network response
return fetchedResponse;
});
});
}));
} else {
return;
}
});
Network first, falling back to cache
Stale While Revalidate
stale-while-revalidate
λ κ°λ°μκ° μΊμλ μ½ν
μΈ λ₯Ό μ¦μ λ‘λνλ μ¦μμ±κ³Ό μΊμλ 컨ν
μΈ μ λν μ
λ°μ΄νΈκ° ν₯νμ μ¬μ©λλλ‘ λ³΄μ₯νλ μ΅μ μ± κ°μ κ· νμ μ μ§νλλ° λμμ΄λλ€. μ κΈ°μ μΌλ‘ μ
λ°μ΄νΈλλ μλνν° μΉ μλΉμ€ λλ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ μ§ κ΄λ¦¬νκ±°λ asset μλͺ
μ΄ μμ κ²½ν₯μ΄ μλ κ²½μ° stale-while-revalidate
κ° κΈ°μ‘΄ μΊμ± μ μ±
μ μ μ©ν μΆκ° κΈ°λ₯μ΄ λ μ μλ€.