Buforowanie zasobów podczas działania

Niektóre zasoby w Twojej aplikacji internetowej mogą być używane rzadko, bardzo duże lub różnią się w zależności od urządzenia użytkownika (np. elastyczne obrazy) lub języka. W takich przypadkach wstępne zapisywanie w pamięci podręcznej może działać antywzorcowo i zamiast tego lepiej korzystać z pamięci podręcznej w czasie działania.

W Workbox możesz obsługiwać buforowanie czasu działania zasobów za pomocą modułu workbox-routing do dopasowywania tras i obsługiwania dla nich strategii buforowania za pomocą modułu workbox-strategies.

Strategie buforowania

Możesz obsługiwać większość tras zasobów dzięki jednej z wbudowanych strategii buforowania. Zostały one szczegółowo omówione wcześniej w tej dokumentacji, ale warto podać tu kilka najważniejszych:

  • Funkcja Stale podczas ponownego weryfikowania korzysta z odpowiedzi na żądanie z pamięci podręcznej, jeśli jest dostępna, i aktualizuje pamięć podręczną w tle na podstawie odpowiedzi z sieci. Dlatego jeśli zasób nie jest zapisany w pamięci podręcznej, będzie czekać na odpowiedź sieci i z niej skorzystać. To dość bezpieczna strategia, ponieważ regularnie aktualizuje używane przez nią wpisy w pamięci podręcznej. Wadą jest to, że zawsze żąda zasobu z sieci w tle.
  • Najpierw sieć próbuje najpierw uzyskać odpowiedź z sieci. Po otrzymaniu odpowiedzi przekazuje ona ją do przeglądarki i zapisuje w pamięci podręcznej. Jeśli żądanie sieciowe nie powiedzie się, zostanie użyta ostatnia odpowiedź z pamięci podręcznej, co umożliwi dostęp offline do zasobu.
  • Najpierw pamięć podręczna najpierw sprawdza pamięć podręczną i używa odpowiedzi, jeśli jest dostępna. Jeśli żądania nie ma w pamięci podręcznej, używana jest sieć, a każda prawidłowa odpowiedź jest dodawana do pamięci podręcznej, zanim zostanie przekazana do przeglądarki.
  • Ustawienie Tylko sieć wymusza, aby odpowiedź pochodziła z sieci.
  • Tylko pamięć podręczna wymusza, aby odpowiedź pochodziła z pamięci podręcznej.

Możesz zastosować te strategie do wybranych żądań, korzystając z metod oferowanych przez workbox-routing.

Stosowanie strategii buforowania z dopasowywaniem tras

workbox-routing udostępnia metodę registerRoute do dopasowywania tras i obsługi ich za pomocą strategii buforowania. Funkcja registerRoute akceptuje Route obiekt, który z kolei przyjmuje 2 argumenty:

  1. Ciąg znaków, wyrażenie regularne lub dopasowanie zwrotne, które określa kryteria pasujące do trasy.
  2. Moduł obsługi trasy – zwykle strategia oferowana przez workbox-strategies.

Wywołania zwrotne z dopasowania są preferowane do dopasowywania tras, ponieważ udostępniają obiekt kontekstu zawierający obiekt Request, ciąg adresu URL żądania, zdarzenie pobierania oraz wartość logiczną określającą, czy żądanie pochodzi z tej samej domeny.

Następnie moduł obsługi obsługuje dopasowaną trasę. W poniższym przykładzie tworzona jest nowa trasa, która pasuje do przychodzących żądań obrazów z tej samej domeny. W tym przypadku stosowana jest pamięć podręczna, a w przypadku strategii sieciowej.

// 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);

Korzystanie z wielu pamięci podręcznych

Workbox umożliwia grupowanie odpowiedzi w pamięci podręcznej w osobne instancje Cache za pomocą opcji cacheName dostępnej w pakietach strategii.

W poniższym przykładzie obrazy korzystają ze strategii „Nieaktualne w trakcie ponownej weryfikacji”, podczas gdy zasoby CSS i JavaScript korzystają ze strategii sieci, która w pierwszej kolejności korzysta z pamięci podręcznej. Trasa każdego zasobu umieszcza odpowiedzi w osobnych pamięciach podręcznych przez dodanie właściwości cacheName.

// 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);
. Zrzut ekranu przedstawiający listę instancji pamięci podręcznej na karcie aplikacji w Narzędziach deweloperskich w Chrome. Dostępne są 3 różne pamięci podręczne: jedna o nazwie „scripts”, druga „styles”, a ostatnia o nazwie „images”.
Przeglądarka pamięci podręcznej w panelu Aplikacje w Narzędziach deweloperskich w Chrome. Odpowiedzi na różne typy zasobów są przechowywane w osobnych pamięciach podręcznych.

Ustawianie daty wygaśnięcia wpisów w pamięci podręcznej

Podczas zarządzania pamięciami podręcznymi instancji service worker pamiętaj o limitach miejsca na dane. ExpirationPlugin upraszcza konserwację pamięci podręcznej i jest udostępniany przez workbox-expiration. Aby jej użyć, określ ją w konfiguracji strategii buforowania:

// 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);

Przestrzeganie limitów miejsca na dane może być skomplikowane. Sprawdzoną metodą jest uwzględnienie użytkowników, którzy często mają problemy z miejscem na dane lub chcą go maksymalnie wykorzystać. W osiągnięciu tego celu mogą pomóc pary ExpirationPlugin w Workbox.

Uwagi na temat zasobów z innych domen

Interakcja między skryptem service worker a zasobami z innych domen znacznie się różni od zasobów z tej samej domeny. Cross-Origin Resource Sharing (CORS) jest skomplikowany, a złożoność obejmuje sposób obsługi zasobów z innych domen w skrypcie service worker.

Nieprzezroczyste odpowiedzi

Jeśli wysyłasz żądanie z innej domeny w trybie no-cors, odpowiedź może zostać zapisana w pamięci podręcznej skryptu service worker, a nawet być używana bezpośrednio przez przeglądarkę. Jednak samej treści odpowiedzi nie można odczytać za pomocą JavaScriptu. Jest to tzw. odpowiedź nieprzezroczysta.

Nieprzezroczyste odpowiedzi to zabezpieczenie, które ma uniemożliwić sprawdzanie zasobów z innych domen. Nadal możesz wysyłać żądania zasobów z innych domen, a nawet buforować je, ale nie będziesz mieć jednak możliwości odczytania treści odpowiedzi ani odczytania jej kodu stanu.

Pamiętaj, aby włączyć tryb CORS

Nawet jeśli wczytujesz zasoby z innych domen, które mają ustawione mniej rygorystyczne nagłówki CORS umożliwiające odczytywanie odpowiedzi, treść odpowiedzi z innej domeny może być nieprzezroczysta. Na przykład poniższy kod HTML wywoła żądania no-cors, które będą prowadzić do nieprzejrzystych odpowiedzi, niezależnie od ustawionych nagłówków CORS:

<link rel="stylesheet" href="https://example.com/path/to/style.css">
<img src="https://example.com/path/to/image.png">

Aby jawnie aktywować żądanie cors zwracające nieprzejrzystą odpowiedź, musisz wyraźnie zaakceptować tryb CORS, dodając atrybut crossorigin do kodu HTML:

<link crossorigin="anonymous" rel="stylesheet" href="https://example.com/path/to/style.css">
<img crossorigin="anonymous" src="https://example.com/path/to/image.png">

Jest to ważne, aby pamiętać, kiedy trasy w zasobach podrzędnych pamięci podręcznej instancji usługi są wczytywane w czasie działania.

Workbox nie może buforować nieprzezroczystych odpowiedzi

Domyślnie Workbox ostrożnie podchodzi do buforowania nieprzezroczystych odpowiedzi. Sprawdzenie kodu odpowiedzi pod kątem nieprzezroczystych odpowiedzi jest niemożliwe, dlatego przechowywanie w pamięci podręcznej odpowiedzi błędu może spowodować trwałe uszkodzenie działania w przypadku użycia strategii skoncentrowanej na pamięci podręcznej lub tylko w pamięci podręcznej.

Jeśli chcesz zapisać nieprzejrzystą odpowiedź w pamięci podręcznej w Workbox, użyj strategii dotyczącej najpierw sieci lub nieaktualnej weryfikacji w trakcie sprawdzania. Tak. Oznacza to, że żądanie zasobu jest nadal wysyłane z sieci za każdym razem, ale dzięki temu nieudane odpowiedzi nie utrwalają się i z czasem zostaną zastąpione użytecznymi odpowiedziami.

Jeśli użyjesz innej strategii buforowania, a odpowiedź będzie nieprzejrzysta, Workbox wyświetli ostrzeżenie, że w trybie programistycznym odpowiedź nie została zapisana w pamięci podręcznej.

Wymuszaj buforowanie nieprzezroczystych odpowiedzi

Jeśli masz absolutną pewność, że chcesz zapisać nieprzejrzystą odpowiedź w pamięci podręcznej, korzystając ze strategii skoncentrowanej na pamięci podręcznej lub tylko w pamięci podręcznej, możesz wymusić wykonanie tej czynności w module workbox-cacheable-response:

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);

Odpowiedzi nieprzezroczyste i interfejs API navigator.storage

Aby zapobiec wyciekowi informacji między domenami, rozmiar nieprzejrzystej odpowiedzi używanej do obliczania limitów miejsca na dane jest znacznie większy. Ma to wpływ na sposób raportowania limitów miejsca na dane przez navigator.storage API.

To dopełnienie różni się w zależności od przeglądarki, ale w przypadku Chrome minimalny rozmiar pojedynczej nieprzezroczystej odpowiedzi w pamięci podręcznej (w języku angielskim) to około 7 megabajtów. Pamiętaj o tym podczas określania liczby nieprzezroczystych odpowiedzi, które chcesz buforować, ponieważ możesz łatwo przekroczyć limity miejsca na dane o wiele szybciej, niż się spodziewasz.