Menyimpan resource ke dalam cache selama runtime

Beberapa aset di aplikasi web Anda mungkin jarang digunakan, sangat besar, atau bervariasi berdasarkan perangkat pengguna (seperti gambar yang responsif) atau bahasa. Pada kasus semacam ini, precaching mungkin merupakan anti-pola, dan Anda harus mengandalkan caching runtime sebagai gantinya.

Di Workbox, Anda dapat menangani penyimpanan cache runtime untuk aset menggunakan modul workbox-routing untuk mencocokkan rute, dan menangani strategi penyimpanan dalam cache untuk aset tersebut dengan modul workbox-strategies.

Strategi penyimpanan dalam cache

Anda dapat menangani sebagian besar rute untuk aset dengan salah satu strategi cache bawaan. Hal-hal tersebut telah dibahas secara mendetail sebelumnya dalam dokumentasi ini, tetapi berikut beberapa yang perlu merangkumnya:

  • Tidak Berlaku Saat Validasi Ulang menggunakan respons yang di-cache untuk permintaan jika tersedia dan memperbarui cache di latar belakang dengan respons dari jaringan. Oleh karena itu, jika tidak di-cache, aset akan menunggu respons jaringan dan menggunakannya. Ini adalah strategi yang cukup aman, karena secara rutin memperbarui entri cache yang bergantung padanya. Kelemahannya adalah ia selalu meminta aset dari jaringan di latar belakang.
  • Network First mencoba mendapatkan respons dari jaringan terlebih dahulu. Respons yang diterima akan diteruskan ke browser dan disimpan ke cache. Jika permintaan jaringan gagal, respons terakhir yang di-cache akan digunakan, sehingga mengaktifkan akses offline ke aset.
  • Cache First memeriksa cache untuk menemukan respons terlebih dahulu dan menggunakannya jika tersedia. Jika permintaan tidak ada di cache, jaringan akan digunakan dan setiap respons yang valid akan ditambahkan ke cache sebelum diteruskan ke browser.
  • Jaringan Saja memaksa respons berasal dari jaringan.
  • Cache Only memaksa respons berasal dari cache.

Anda dapat menerapkan strategi ini untuk memilih permintaan menggunakan metode yang ditawarkan oleh workbox-routing.

Menerapkan strategi penyimpanan cache dengan pencocokan rute

workbox-routing menampilkan metode registerRoute untuk mencocokkan rute dan menanganinya dengan strategi penyimpanan data dalam cache. registerRoute menerima objek Route yang kemudian menerima dua argumen:

  1. String, ekspresi reguler, atau callback pencocokan untuk menentukan kriteria pencocokan rute.
  2. Pengendali untuk rute—biasanya strategi yang disediakan oleh workbox-strategies.

Callback pencocokan lebih disukai agar cocok dengan rute karena memberikan objek konteks yang menyertakan objek Request, string URL permintaan, peristiwa pengambilan, dan boolean untuk mengetahui apakah permintaan tersebut merupakan permintaan origin yang sama.

Pengendali kemudian menangani rute yang cocok. Pada contoh berikut, rute baru dibuat yang cocok dengan permintaan gambar dari origin yang sama, dengan menerapkan cache terlebih dahulu, dan kembali ke strategi jaringan.

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

Menggunakan beberapa cache

Workbox memungkinkan Anda mengelompokkan respons yang di-cache ke dalam instance Cache terpisah menggunakan opsi cacheName yang tersedia dalam strategi paket.

Pada contoh berikut, gambar menggunakan strategi yang sudah tidak berlaku saat validasi ulang, sedangkan aset CSS dan JavaScript menggunakan metode beralih ke strategi jaringan yang mengutamakan cache. Rute untuk setiap aset menempatkan respons ke dalam cache terpisah, dengan menambahkan properti 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);
Screenshot daftar instance Cache di tab aplikasi DevTools Chrome. Ada tiga cache berbeda yang ditampilkan: satu bernama 'skrip', satu lagi bernama 'gaya', dan yang terakhir bernama 'gambar'.
Penampil Penyimpanan cache di panel Application pada Chrome DevTools. Respons untuk jenis aset yang berbeda disimpan dalam cache terpisah.

Menyetel waktu habis masa berlaku untuk entri cache

Perhatikan kuota penyimpanan saat mengelola cache pekerja layanan. ExpirationPlugin menyederhanakan pemeliharaan cache dan diekspos oleh workbox-expiration. Untuk menggunakannya, tentukan dalam konfigurasi untuk strategi caching:

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

Mematuhi kuota penyimpanan bisa jadi rumit. Sebaiknya pertimbangkan pengguna yang mungkin mengalami tekanan penyimpanan, atau ingin memaksimalkan penggunaan penyimpanan mereka. Pasangan ExpirationPlugin workbox dapat membantu mencapai sasaran tersebut.

Pertimbangan lintas origin

Interaksi antara pekerja layanan dan aset lintas origin sangat berbeda dengan aset origin yang sama. Cross-Origin Resource Sharing (CORS) itu rumit, dan kompleksitas tersebut meluas ke cara Anda menangani resource lintas asal dalam pekerja layanan.

Respons buram

Saat membuat permintaan lintas origin dalam mode no-cors, respons dapat disimpan dalam cache pekerja layanan dan bahkan digunakan langsung oleh browser. Namun, isi respons itu sendiri tidak dapat dibaca melalui JavaScript. Hal ini dikenal sebagai respons buram.

Respons buram adalah tindakan keamanan yang dimaksudkan untuk mencegah inspeksi aset lintas origin. Anda masih dapat membuat permintaan untuk aset lintas origin dan bahkan meng-cache-nya, hanya saja Anda tidak dapat membaca isi respons atau bahkan membaca kode status-nya.

Jangan lupa ikut serta dalam mode CORS

Meskipun Anda memuat aset lintas origin yang memang menetapkan header CORS permisif yang memungkinkan Anda membaca respons, isi respons lintas origin mungkin masih buram. Misalnya, HTML berikut akan memicu permintaan no-cors yang akan menghasilkan respons buram, apa pun header CORS yang ditetapkan:

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

Untuk memicu permintaan cors secara eksplisit yang akan menghasilkan respons nonburam, Anda harus secara eksplisit memilih ikut serta dalam mode CORS dengan menambahkan atribut crossorigin ke HTML Anda:

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

Penting untuk diingat saat rute di subresource cache pekerja layanan Anda dimuat saat runtime.

Kotak kerja tidak boleh menyimpan cache respons buram

Secara default, Workbox mengambil pendekatan dengan hati-hati untuk menyimpan cache respons buram. Karena tidak mungkin memeriksa kode respons untuk respons buram, caching respons error bisa menyebabkan pengalaman yang terus-menerus rusak jika strategi cache-first atau cache-only digunakan.

Jika Anda perlu menyimpan respons buram di Workbox, Anda harus menggunakan strategi yang mengutamakan jaringan atau validasi usang untuk menanganinya. Ya, ini berarti bahwa aset akan tetap diminta dari jaringan setiap saat, tetapi hal ini memastikan bahwa respons yang gagal tidak akan bertahan, dan pada akhirnya akan diganti dengan respons yang dapat digunakan.

Jika Anda menggunakan strategi caching lain dan respons buram ditampilkan, Workbox akan memperingatkan bahwa respons tidak di-cache saat dalam mode pengembangan.

Memaksa caching respons buram

Jika Anda sangat yakin bahwa Anda ingin meng-cache respons buram menggunakan strategi cache-first atau cache saja, Anda dapat memaksa Workbox untuk melakukannya dengan modul 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);

Respons Buram dan navigator.storage API

Untuk menghindari kebocoran informasi lintas-domain, ada padding signifikan yang ditambahkan ke ukuran respons buram yang digunakan untuk menghitung batas kuota penyimpanan. Hal ini memengaruhi cara navigator.storage API melaporkan kuota penyimpanan.

Padding ini bervariasi menurut browser, tetapi untuk Chrome, ukuran minimum yang dikontribusikan oleh satu respons buram yang di-cache terhadap keseluruhan penyimpanan yang digunakan adalah sekitar 7 megabyte. Anda harus mengingat ini saat menentukan berapa banyak respons buram yang ingin di-cache, karena Anda bisa dengan mudah melebihi kuota penyimpanan jauh lebih cepat dari yang diperkirakan.