快取儲存空間是一項強大的工具。這可讓應用程式較不容易受到網路狀況的影響。妥善運用快取功能,您就能讓網路應用程式在離線狀態下運作,並在任何網路狀況下盡可能快速提供素材資源。如素材資源和資料一文所述,您可以決定最佳的快取必要素材資源策略。如要管理服務工作站與 Cache Storage API 互動的快取,
不同的結構定義可以使用 Cache Storage API:
- 視窗內容 (PWA 的主執行緒)。
- Service Worker。
- 您使用的任何其他工作站。
使用 Service Worker 管理快取的其中一項優點是,其生命週期不會與視窗相關聯,這代表您並未封鎖主執行緒。請注意,大多數這類環境都必須在傳輸層安全標準 (TLS) 連線下才能使用 Cache Storage API。
要快取的內容
您可能會先想到快取的內容,雖然這個問題沒有單一答案,但您可以先從所有必要資源著手,這些資源是您轉譯使用者介面所需的。
這些資源應包含:
- 主頁面 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 中快取資產
最常見的情況之一,是安裝服務工作站時,快取最少的資產集合。方法是在 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()
方法會收到承諾,並要求瀏覽器先等待承諾中的工作解決 (完成或失敗),然後才終止 Service Worker 程序。您可能需要鏈結承諾並傳回 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 應用程式分頁中對快取儲存空間的內容進行偵錯。在這個頁面中,您可以查看目前來源中每個快取的內容。我們會在「工具和偵錯」一章中進一步介紹這些工具。