Workbox

隨著 PWA 的發展,維護 Service Worker 和快取儲存邏輯並不容易。Workbox 是一組開放原始碼程式庫,可協助您完成這項作業。Workbox 會封裝低階 API (例如 Service Worker API 和 Cache Storage API),並公開更適合開發人員使用的介面。

可協助處理部分工作,包括將快取策略與路徑 (或轉送模式)、處理串流,以及使用背景同步處理功能和適當的備用選項。

Workbox 可以幫助您管理資產快取與服務需求。也是服務工作處理程序最常用的程式庫。54% 的行動版網站。許多建構工具和 CLI 都使用這類網站,包括 Angular CLI、Create-React-App 和 Vue CLI。此外,大部分的其他程式庫和架構也有外掛程式,例如 Next.js。

54%

服務工作人員的行動版網站會使用 Workbox 程式庫

Workbox 模組

Workbox 包含數個程式庫 (稱為內部模組),每個程式庫分別著重於管理資產與服務工作人員行為的不同面向。

Workbox 模組可在不同的情況下運作,例如:

  • 在 Service Worker 環境中:匯入所需的模組,並從 Service Worker 檔案中使用這些模組,例如以不同策略管理快取及提供檔案。
  • 在主要 window 環境中:協助註冊 Service Worker 並與其通訊
  • 建構系統的一部分:例如 Webpack,用於建立資產資訊清單,或甚至產生整個 Service Worker。

熱門模組包括:

  • workbox-routing:當 Service Worker 攔截要求時,這個模組會將這些要求轉送至提供回應的其他函式。這個程式庫會實作 fetch 事件處理常式,如服務章節中所述。
  • workbox-strategies:一組執行階段快取策略,可處理要求的回應,例如重新驗證時快取和過時的快取。這個過程會實作放送章節中提及的各種策略。
  • workbox-precaching:實作在 Service Worker 的 install 事件處理常式 (亦稱「預先快取」) 中快取檔案的方式,如快取章節所述。透過這個模組,你可以輕鬆預先載入一組檔案,並有效管理這些資產的更新作業。我們會在更新章節中說明如何更新資產。
  • workbox-expiration:這種外掛程式能與快取策略搭配使用,根據快取中的項目數量或快取要求的存在時間,移除快取要求。這有助於管理快取,並設定時間限制和每個快取中的項目數量。
  • workbox-window:要在 PWA 網頁內部執行的一組模組,也就是視窗內容。您可以簡化 Service Worker 的註冊和更新程序,讓在 Service Worker 環境中執行的程式碼和視窗內容能夠輕鬆通訊。

使用 Workbox

Workbox 提供了多種整合 PWA 的方式。您可以選擇最適合應用程式的架構:

  • Workbox CLI:一種指令列公用程式,用於產生完整的 Service Worker、插入預先快取資訊清單,或複製所需的 Workbox 檔案。
  • Workbox 建構:npm 模組,用於產生完整 Service Worker、插入預先快取資訊清單並複製 Workbox 檔案。本功能預計與您的建構程序整合。
  • workbox-sw:一種從不使用建構程序的 CDN 中載入 Workbox 服務工作站套件的方法。

Workbox CLI 會提供精靈,逐步引導您建立 Service Worker。如要執行精靈,請在指令列中輸入以下內容:

npx workbox-cli wizard

在終端機中運作的 Workbox CLI

使用 Workbox 快取及提供內容

Workbox 的常見用途是同時使用轉送模組和策略模組來快取及提供檔案。

workbox-strategies 模組提供立即可用的快取策略,請參閱「素材資源與資料」和「放送」章節。

workbox-routing 模組可協助您為服務工作站收到的要求排序,並將要求與快取策略或函式進行比對,以取得這些要求的回應。

將路徑與策略比對後,Workbox 也可以使用 workbox-cacheable-response 外掛程式,篩選要新增至快取的回應。舉例來說,有了這個外掛程式,您可以只快取未傳回錯誤的回應。

下列程式碼範例使用快取優先策略 (透過 CacheFirst 模組) 快取及提供網頁瀏覽活動。

import { registerRoute } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import { CacheableResponsePlugin } from 'workbox-cacheable-response';

const pageStrategy = new CacheFirst({
  // Put all cached files in a cache named 'pages'
  cacheName: 'pages',
  plugins: [
    // Only requests that return with a 200 status are cached
    new CacheableResponsePlugin({
      statuses: [200],
    }),
  ],
});

使用這個外掛程式,您就能進入 Workbox 的快取及要求解析生命週期。此處的 CacheableResponsePlugin 僅用於快取結果為 200 的要求,以避免將不良的要求儲存至快取。

建立策略後,即可註冊要使用的路徑。以下範例會呼叫 registerRoute(),將 Request 物件傳遞至其回呼。如果 request.mode"navigate",則會使用上一個程式碼範例中定義的 CacheFirst 策略 (此處稱為 pageStrategy)。

// Cache page navigations (HTML) with a Cache First strategy
registerRoute( ({ request }) => request.mode === 'navigate',
  pageStrategy );

如需更多範例和最佳做法,請參閱 Workbox 說明文件

離線備用

workbox-routing 模組也提供匯出的 setCatchHandler(),可在路徑擲回錯誤時提供處理功能。您可以運用這項功能設定離線備用機制,讓使用者知道目前無法取得指定的路線。

在這個例子中,只要結合 Workbox 和 Cache Storage API,即可利用僅快取策略,提供離線備用方案。 首先,在 Service Worker 的安裝生命週期內,系統會開啟 offline-fallbacks 快取,並將離線備用陣列新增至快取。

import { setCatchHandler } from 'workbox-routing';

// Warm the cache when the service worker installs
self.addEventListener('install', event => {
  const files = ['/offline.html']; // you can add more resources here
  event.waitUntil(
    self.caches.open('offline-fallbacks')
        .then(cache => cache.addAll(files))
  );
});

然後在 setCatchHandler() 中判定擲回錯誤的要求目的地,並開啟 offline-fallbacks 快取。如果目的地是文件,系統會將離線備用內容傳回給使用者。如果不存在,或是目的地不是文件 (例如圖片或樣式表),系統會傳回錯誤回應。無論是文件、圖片、影片、字型或任何想提供的內容,皆可當做離線備用方案。

// Respond with the fallback if a route throws an error
setCatchHandler(async (options) => {
  const destination = options.request.destination;
  const cache = await self.caches.open('offline-fallbacks');
  if (destination === 'document') {
    return (await cache.match('/offline.html')) || Response.error();
  }
  return Response.error();
});

食譜

有些轉送和快取模式 (例如 NetworkFirst 導覽和離線備用選項) 很常見,因此封裝到可重複使用的方案中。勾選「workbox-recipes」,如果對方提供適合您架構的解決方案,他們就能提供協助。通常可做為一行程式碼使用,讓您加進服務工作處理程序的程式碼。

快取及更新資產

快取資產也包括更新資產。Workbox 可協助您以自己偏好的方式更新資產。如果伺服器在伺服器上變更,或正在等待應用程式新版本推出,這些程式可能會持續更新這些執行個體。 請參閱更新章節,進一步瞭解如何更新。

使用 Workbox 暢玩

您可以透過以下程式碼研究室立即使用 Workbox:

資源