Sommige middelen in uw webapplicatie worden mogelijk niet vaak gebruikt, zijn erg groot of variëren afhankelijk van het apparaat van de gebruiker (zoals responsieve afbeeldingen) of de taal. Dit zijn gevallen waarin precaching een anti-patroon kan zijn en u in plaats daarvan moet vertrouwen op runtime-caching.
In Workbox kunt u runtime-caching voor assets afhandelen met behulp van de workbox-routing
module om routes af te stemmen, en caching-strategieën daarvoor afhandelen met de workbox-strategies
module .
Caching-strategieën
U kunt de meeste routes voor assets afhandelen met een van de ingebouwde cachingstrategieën. Ze worden eerder in deze documentatie gedetailleerd besproken , maar hier zijn er een paar die de moeite waard zijn om samen te vatten:
- Stale While Revalidate gebruikt een in de cache opgeslagen antwoord voor een verzoek als dit beschikbaar is en werkt de cache op de achtergrond bij met een antwoord van het netwerk. Als de asset niet in de cache is opgeslagen, wacht deze daarom op de reactie van het netwerk en gebruikt deze. Het is een redelijk veilige strategie, omdat het regelmatig cache-items bijwerkt die ervan afhankelijk zijn. Het nadeel is dat het altijd op de achtergrond een asset van het netwerk opvraagt.
- Network First probeert eerst een reactie van het netwerk te krijgen. Als er een antwoord wordt ontvangen, wordt dat antwoord doorgegeven aan de browser en opgeslagen in een cache. Als het netwerkverzoek mislukt, wordt het laatste in de cache opgeslagen antwoord gebruikt, waardoor offline toegang tot de asset mogelijk wordt.
- Cache First controleert eerst de cache op een antwoord en gebruikt dit indien beschikbaar. Als het verzoek niet in de cache staat, wordt het netwerk gebruikt en wordt elk geldig antwoord aan de cache toegevoegd voordat het aan de browser wordt doorgegeven.
- Alleen Netwerk dwingt het antwoord van het netwerk te komen.
- Alleen Cache dwingt het antwoord uit de cache te komen.
U kunt deze strategieën toepassen om aanvragen te selecteren met behulp van methoden die worden aangeboden door workbox-routing
.
Cachingstrategieën toepassen met routematching
workbox-routing
stelt een registerRoute
methode beschikbaar om routes te matchen en deze af te handelen met een caching-strategie. registerRoute
accepteert een Route
object dat op zijn beurt twee argumenten accepteert:
- Een tekenreeks, reguliere expressie of een match-callback om route-matchingscriteria op te geven.
- Een handler voor de route, meestal een strategie die wordt geboden door
workbox-strategies
.
Match-callbacks hebben de voorkeur boven match-routes, omdat ze een contextobject bieden dat het Request
object , de request-URL-tekenreeks, de fetch-gebeurtenis en een boolean bevat die aangeeft of het verzoek een verzoek van dezelfde oorsprong is.
De handler handelt vervolgens de overeenkomende route af. In het volgende voorbeeld wordt een nieuwe route gemaakt die overeenkomt met binnenkomende afbeeldingsverzoeken van dezelfde oorsprong, waarbij eerst de cache wordt toegepast en terugvalt op de netwerkstrategie .
// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
// A new route that matches same-origin image requests and handles
// them with the cache-first, falling back to network strategy:
const imageRoute = new Route(({ request, sameOrigin }) => {
return sameOrigin && request.destination === 'image'
}, new CacheFirst());
// Register the new route
registerRoute(imageRoute);
Meerdere caches gebruiken
Met Workbox kunt u in de cache opgeslagen antwoorden in afzonderlijke Cache
instanties plaatsen met behulp van de cacheName
optie die beschikbaar is in de gebundelde strategieën.
In het volgende voorbeeld gebruiken afbeeldingen een verouderde-terwijl-revalidate-strategie, terwijl CSS- en JavaScript-items een cache-first gebruiken die terugvalt op de netwerkstrategie. De route voor elke asset plaatst antwoorden in afzonderlijke caches, door de eigenschap cacheName
toe te voegen.
// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst, StaleWhileRevalidate } from 'workbox-strategies';
// Handle images:
const imageRoute = new Route(({ request }) => {
return request.destination === 'image'
}, new StaleWhileRevalidate({
cacheName: 'images'
}));
// Handle scripts:
const scriptsRoute = new Route(({ request }) => {
return request.destination === 'script';
}, new CacheFirst({
cacheName: 'scripts'
}));
// Handle styles:
const stylesRoute = new Route(({ request }) => {
return request.destination === 'style';
}, new CacheFirst({
cacheName: 'styles'
}));
// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);
registerRoute(stylesRoute);
Een vervaldatum instellen voor cache-items
Houd rekening met opslagquota bij het beheren van cache(s) voor servicemedewerkers. ExpirationPlugin
vereenvoudigt het cache-onderhoud en wordt zichtbaar door workbox-expiration
. Om het te gebruiken, specificeert u het in de configuratie voor een cachingstrategie:
// sw.js
import { registerRoute, Route } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';
// Evict image cache entries older thirty days:
const imageRoute = new Route(({ request }) => {
return request.destination === 'image';
}, new CacheFirst({
cacheName: 'images',
plugins: [
new ExpirationPlugin({
maxAgeSeconds: 60 * 60 * 24 * 30,
})
]
}));
// Evict the least-used script cache entries when
// the cache has more than 50 entries:
const scriptsRoute = new Route(({ request }) => {
return request.destination === 'script';
}, new CacheFirst({
cacheName: 'scripts',
plugins: [
new ExpirationPlugin({
maxEntries: 50,
})
]
}));
// Register routes
registerRoute(imageRoute);
registerRoute(scriptsRoute);
Het voldoen aan opslagquota kan ingewikkeld zijn. Het is een goede gewoonte om rekening te houden met gebruikers die mogelijk opslagdruk ervaren of hun opslag zo efficiënt mogelijk willen gebruiken. ExpirationPlugin
paren van Workbox kunnen helpen bij het bereiken van dat doel.
Cross-oorsprongoverwegingen
De interactie tussen uw servicemedewerker en cross-originele activa is aanzienlijk anders dan bij activa van dezelfde oorsprong. Cross-Origin Resource Sharing (CORS) is ingewikkeld, en die complexiteit strekt zich uit tot de manier waarop u omgaat met cross-origine bronnen in een servicemedewerker.
Ondoorzichtige reacties
Wanneer u een cross-origin-verzoek doet in no-cors
modus , kan het antwoord worden opgeslagen in de cache van een servicemedewerker en zelfs rechtstreeks door de browser worden gebruikt. De antwoordtekst zelf kan echter niet via JavaScript worden gelezen. Dit staat bekend als een ondoorzichtige reactie .
Ondoorzichtige reacties zijn een beveiligingsmaatregel die bedoeld is om de inspectie van een cross-origin asset te voorkomen. U kunt nog steeds verzoeken indienen voor cross-origin assets en deze zelfs in de cache opslaan, u kunt alleen de antwoordtekst niet lezen of zelfs de statuscode ervan lezen!
Vergeet niet om u aan te melden voor de CORS-modus
Zelfs als u cross-origin-items laadt die wel toegestane CORS-headers instellen waarmee u reacties kunt lezen, kan de hoofdtekst van de cross-origin-reactie nog steeds ondoorzichtig zijn. De volgende HTML activeert bijvoorbeeld no-cors
verzoeken die tot ondoorzichtige reacties leiden, ongeacht welke CORS-headers zijn ingesteld:
<link rel="stylesheet" href="https://example.com/path/to/style.css">
<img src="https://example.com/path/to/image.png">
Om expliciet een cors
verzoek te activeren dat een niet-ondoorzichtig antwoord oplevert, moet u zich expliciet aanmelden voor de CORS-modus door het crossorigin
attribuut aan uw HTML toe te voegen:
<link crossorigin="anonymous" rel="stylesheet" href="https://example.com/path/to/style.css">
<img crossorigin="anonymous" src="https://example.com/path/to/image.png">
Dit is belangrijk om te onthouden wanneer routes in de cache van uw service worker-subbronnen tijdens runtime worden geladen.
Workbox mag ondoorzichtige antwoorden niet in de cache opslaan
Standaard hanteert Workbox een voorzichtige benadering bij het cachen van ondoorzichtige reacties. Omdat het onmogelijk is om de responscode te onderzoeken op ondoorzichtige antwoorden, kan het in de cache opslaan van een foutreactie resulteren in een aanhoudend verstoorde ervaring als er een strategie voor eerst cache of alleen cache wordt gebruikt.
Als u een ondoorzichtig antwoord in Workbox in de cache moet opslaan, moet u een netwerk-eerst- of verouderde-terwijl-valideren-strategie gebruiken om dit af te handelen. Ja, dit betekent dat de asset nog steeds elke keer bij het netwerk wordt opgevraagd, maar het zorgt ervoor dat mislukte reacties niet blijven bestaan en uiteindelijk worden vervangen door bruikbare reacties.
Als u een andere cachingstrategie gebruikt en er een ondoorzichtig antwoord wordt geretourneerd, waarschuwt Workbox u dat het antwoord niet in de cache is opgeslagen in de ontwikkelingsmodus .
Forceer caching van ondoorzichtige reacties
Als u er absoluut zeker van bent dat u een ondoorzichtig antwoord in de cache wilt opslaan met behulp van een cache-first- of cache-only-strategie, kunt u Workbox dwingen dit te doen met de workbox-cacheable-response
module :
import {Route, registerRoute} from 'workbox-routing';
import {NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';
const cdnRoute = new Route(({url}) => {
return url === 'https://cdn.google.com/example-script.min.js';
}, new CacheFirst({
plugins: [
new CacheableResponsePlugin({
statuses: [0, 200]
})
]
}))
registerRoute(cdnRoute);
Ondoorzichtige reacties en de navigator.storage
API
Om het lekken van informatie over meerdere domeinen te voorkomen, is er aanzienlijke opvulling toegevoegd aan de grootte van een ondoorzichtig antwoord dat wordt gebruikt voor het berekenen van opslagquotumlimieten. Dit heeft invloed op de manier waarop de navigator.storage
API opslagquota rapporteert.
Deze opvulling verschilt per browser, maar voor Chrome is de minimale grootte die een enkele in de cache opgeslagen ondoorzichtige reactie bijdraagt aan de totale gebruikte opslagruimte ongeveer 7 megabytes . U moet hier rekening mee houden wanneer u bepaalt hoeveel ondoorzichtige reacties u in de cache wilt opslaan, omdat u de opslagquota gemakkelijk veel eerder kunt overschrijden dan u anders zou verwachten.