快取儲存空間是一項強大的工具。這可讓應用程式較不容易受到網路狀況的影響。只要妥善運用快取,您就能讓網路應用程式在離線狀態下運作,並在任何網路狀況下盡可能快速地提供素材資源。如素材資源和資料一文所述,您可以決定最佳的快取必要素材資源策略。如要管理快取,服務 worker 會與 Cache Storage API 互動。
您可以在不同情境下使用 Cache Storage API:
- 視窗內容 (PWA 的主執行緒)。
- Service Worker。
- 您使用的任何其他工作站。
使用服務工作者管理快取的優點之一,就是其生命週期不會與視窗綁定,也就是說不會封鎖主執行緒。請注意,如要使用 Cache Storage API,這些情境大多必須在 TLS 連線下執行。
快取內容
您可能會想知道快取內容的首要問題是,雖然這個問題沒有單一答案,但您可以先從所有必要資源著手,這些資源是您轉譯使用者介面所需的。
這些資源應包含:
- 主頁面 HTML (應用程式的 start_url)。
- 主要使用者介面所需的 CSS 樣式表。
- 使用者介面中使用的圖片。
- 轉譯使用者介面所需的 JavaScript 檔案。
- 呈現基本體驗所需的資料,例如 JSON 檔案。
- 網頁字型。
- 在多頁應用程式中,您想快速提供或在離線時提供的其他 HTML 文件。
可離線使用
雖然離線功能是漸進式網頁應用程式的要求之一,但請務必瞭解,並非每個 PWA 都需要完整的離線體驗,例如雲端遊戲解決方案或加密貨幣資產應用程式。因此,您可以提供基本使用者介面,引導使用者在這些情況下操作。
PWA 不應顯示瀏覽器錯誤訊息,指出網頁轉譯引擎無法載入網頁。請改用服務 worker 顯示您自己的訊息,避免出現一般且令人困惑的瀏覽器錯誤。
視 PWA 需求而定,您可以使用許多不同的快取策略。因此,請務必設計快取用途,提供快速可靠的體驗。舉例來說,如果所有應用程式素材資源都能快速下載、不會占用太多空間,且不需要在每次要求中更新,那麼將所有素材資源快取起來就是有效的策略。另一方面,如果您有需要使用最新版本的資源,建議您完全不要快取這些素材資源。
使用 API
使用 Cache Storage API 在來源中定義一組快取,每個快取都會以您定義的字串名稱標示。透過 caches
物件存取 API,而 open
方法可用於建立或開啟已建立的快取。open 方法會傳回快取物件的承諾。
caches.open("pwa-assets")
.then(cache => {
// you can download and store, delete or update resources with cache arguments
});
下載及儲存素材資源
如要要求瀏覽器下載及儲存素材資源,請使用 add
或 addAll
方法。add
方法會發出要求並儲存一個 HTTP 回應,而 addAll
會根據要求或網址陣列,將一組 HTTP 回應做為交易。
caches.open("pwa-assets")
.then(cache => {
cache.add("styles.css"); // it stores only one resource
cache.addAll(["styles.css", "app.js"]); // it stores two resources
});
快取儲存空間介面會儲存整個回應,包括所有標頭和內文。因此,您日後可以使用 HTTP 要求或網址做為金鑰來擷取該金鑰。請參閱「服務」一章,瞭解如何進行這項操作。
快取時機
在 PWA 中,您可以決定快取檔案的時機。雖然在安裝服務工作者時盡可能儲存大量素材資源是一種方法,但通常不建議這麼做。快取不必要的資源會浪費頻寬和儲存空間,並可能導致應用程式提供不必要的過時資源。
您不需要一次快取所有素材資源,可以在 PWA 的生命週期中多次快取素材資源,例如:
- 服務工作者安裝時。
- 首次載入網頁後。
- 使用者前往某個部分或路線時。
- 網路閒置時。
您可以在主執行緒或服務工作者內容中要求快取新檔案。
在 Service Worker 中快取資產
最常見的情況之一,是當服務工作站安裝時,快取最少的資產集合。如要這麼做,您可以在服務工作者中的 install
事件中使用快取儲存空間介面。
由於服務工作者執行緒可隨時停止,您可以要求瀏覽器等待 addAll
應許完成,以便增加儲存所有資產的機會,並維持應用程式的一致性。以下範例示範如何使用服務工作者事件事件監聽器收到的事件引數 waitUntil
方法來執行這項操作。
const urlsToCache = ["/", "app.js", "styles.css", "logo.svg"];
self.addEventListener("install", event => {
event.waitUntil(
caches.open("pwa-assets")
.then(cache => {
return cache.addAll(urlsToCache);
});
);
});
waitUntil()
方法會接收承諾,並要求瀏覽器等待承諾中的任務解決 (完成或失敗),然後再終止服務工作程式程序。您可能需要鏈結承諾並傳回 add()
或 addAll()
呼叫,以便單一結果傳送至 waitUntil()
方法。
您也可以使用 async/await 語法處理承諾。在這種情況下,您需要建立非同步函式,以便呼叫 await
,並在呼叫後傳回承諾給 waitUntil()
,如以下範例所示:
const urlsToCache = ["/", "app.js", "styles.css", "logo.svg"];
self.addEventListener("install", (event) => {
let cacheUrls = async () => {
const cache = await caches.open("pwa-assets");
return cache.addAll(urlsToCache);
};
event.waitUntil(cacheUrls());
});
跨網域要求和不透明回應
PWA 可以下載及快取原始網域和跨網域的資產,例如第三方 CDN 的內容。在跨網域應用程式中,快取互動與相同來源要求非常相似。系統會執行要求,並將回應的副本儲存在快取中。與其他快取的素材資源一樣,這類素材資源只能在應用程式的來源中使用。
素材資源會儲存為不透明回應,也就是說,您的程式碼無法查看或修改該回應的內容或標頭。此外,不透明回應不會在儲存空間 API 中公開實際大小,因此會影響配額。有些瀏覽器會顯示較大的大小,例如 7 MB,即使檔案只有 1 KB 也一樣。
更新及刪除資產
您可以使用 cache.put(request, response)
更新素材資源,並使用 delete(request)
刪除素材資源。
詳情請參閱「快取物件說明文件」。
偵錯快取儲存空間
許多瀏覽器都提供一種方法,可在 DevTools 應用程式分頁中對快取儲存空間的內容進行偵錯。您可以在該頁面中查看目前來源中的每個快取內容。我們會在「工具和偵錯」一章中進一步介紹這些工具。