漸進式Web Apps (PWA) 提供強大的本地資料儲存選項,讓使用者即使網路連線不穩定或離線,仍能持續工作。
PWA 有多種方式可以在裝置上儲存資料,例如本地儲存、快取 API 或 IndexedDB。
下表說明了不同的選項,本文其餘部分將詳細說明每種選項的使用情境。
| 儲存選項 | 描述 |
|---|---|
| 網頁儲存 | 網頁儲存有兩種類型:會話區和本地。 Web Storage 很有用,可以儲存應用程式前端程式碼中少量的資料。 資料以鍵值對結構化,僅提供當前應用程式的來源。 以會話儲存為例,資料會在會話結束時被清除,例如應用程式關閉,或使用者在同一視窗或分頁中瀏覽到其他來源。本地儲存會持續存在,直到應用程式移除資料為止。 |
| 索引資料庫 | IndexedDB 是一個用於儲存大量結構化資料的 API。 API 是非同步的,可以同時從應用程式的前端程式碼和服務工作者程式碼中使用。 使用 IndexedDB API 在用戶端儲存大量結構化資料,或二進位資料,例如加密的媒體物件或檔案。 |
| 快取 | 快取 API 可用來管理快取資源。 快取 API 採用承諾基礎,允許開發者儲存與檢索多種網路資源——包括 HTML、CSS、JavaScript、圖片、JSON 等等。 通常,快取 API 會用於服務工作者,但它也可以提供給你應用程式的前端程式碼。 |
| 檔案系統存取 | 檔案系統存取 API 允許你的 PWA 讀取使用者裝置上的檔案和資料夾,並將變更存回去。 |
注意:請勿使用 WebSQL 或應用程式快取。 雖然這兩種是另外兩種瀏覽器儲存機制,但都已被棄用。 不要用 WebSQL,改用 IndexedDB。 與其使用 Application Cache,不如使用 Cache API。
網頁儲存
網頁儲存對於在使用者裝置上儲存少量字串資料非常有用。 Web Storage 的鍵值對系統簡單易用。
網頁儲存只在你應用程式的主執行緒中同步運作。 這表示網頁儲存無法用於服務工作者,且大量使用網路儲存可能會對您的應用程式造成效能問題。
每種類型的網頁儲存,無論是會話型還是本地型,都被維護為獨立的資料儲存庫,且與建立該儲存區隔離。
-
sessionStorage只會持續整個會話期間——例如瀏覽器開啟時,包括頁面重新整理時。 -
localStorage直到應用程式程式碼、使用者或瀏覽器移除資料為止。
以下程式碼說明如何使用 localStorage,與 sessionStorage 的使用方式相似:
const browserInformation = {
name: 'Microsoft Edge',
version: 108
};
localStorage.setItem('browser', JSON.stringify(browserInformation));
上述程式碼會將 JavaScript 物件以 JSON 字串localStoragesetItem()的形式儲存,並指派一個等於 browser的鍵。 你可以使用getItem()以下方法取得這些資訊localStorage:
const value = localStorage.getItem('browser');
const browserInformation = JSON.parse(value);
欲了解更多,請參閱 MDN 上的 Web Storage API 。
索引資料庫
IndexedDB 是一個非同步 API,用於儲存可用於應用程式前端程式碼或服務工作者程式碼的結構化資料。 使用 IndexedDB API 在用戶端儲存大量結構化資料,或二進位資料,例如加密媒體物件或檔案。
IndexedDB 是將資料儲存在 PWA 的最佳選擇,因為使用 API 不會因為阻塞主執行緒而拖慢應用程式,且可以同時從應用程式的前端程式碼和服務工作者中使用。
使用 IndexedDB 比使用 Web Storage 更複雜,且需要以下步驟來儲存資料:
- 透過使用函
window.indexedDB.open()式開啟資料庫。 - 在資料庫中建立物件儲存,方法是使用 函
IDBDatabase.createObjectStore()式。 - 透過函
IDBDatabase.transaction()式啟動交易來儲存資料。 - 透過聆聽事件,等待手術完成。
欲了解更多並查看程式碼範例,請參閱 Using IndexedDB on MDN。
快取
快取 API 是一個用來儲存和檢索網路請求與回應的系統,儲存在你的應用程式前端程式碼或服務工作者中。 它可用於將資產,如圖片和檔案,儲存在使用者的裝置上。 這能讓你的應用程式即使在離線時也能正常運作,或透過減少渲染應用程式所需的網路請求數量來提升效能。
以下程式碼片段展示了如何在服務工作者中監聽 fetch 事件,並透過快取 API 儲存來自伺服器的回應:
self.addEventListener("fetch", event => {
async function cacheAndReturnRequest() {
// Get the response from the server.
const fetchResponse = await fetch(event.request.url);
// Open the app's cache.
const cache = await caches.open("cache-name");
// Put the response in cache.
cache.put(event.request.url, fetchResponse.clone());
// And return the response.
return fetchResponse.
}
event.respondWith(cacheAndReturnRequest());
});
欲發現其他有用的快取 API 情境,請參閱 MDN > 的>快取參考 漸進式網頁應用>指南。
檔案系統存取
檔案系統存取 API 讓你的應用程式能以類似原生應用程式的方式存取使用者裝置上的檔案。 它可用來建立能讀寫檔案的應用程式,例如文字或影像編輯器。
要從使用者裝置開啟檔案,請使用以下 showOpenFilePicker() 函式:
openFileButton.addEventListener("click", async () => {
const fileHandles = await window.showOpenFilePicker();
});
欲了解更多,請參閱 MDN 上的 Window.showOpenFilePicker () 。
檔案系統存取 API 也可以搭配 PWA 檔案處理功能,將應用程式註冊為特定檔案類型的處理者,因此對使用者來說更貼近原生。 欲了解更多,請參閱 「處理 PWA 中的檔案」。
原始檔案系統存取 API 是檔案系統存取 API 的變體,旨在為使用者提供更多隱私。 它也允許應用程式存取使用者裝置上的檔案,但只能存取特定目錄,該目錄對應用程式來源是私密的。 此外,此 API 並非為了讓使用者能輕鬆使用檔案總管存取私人目錄。
若要從 origin-private 檔案系統開啟檔案,請使用 navigator.storage Promise-based API:
// Get the origin-private directory handle.
const root = await navigator.storage.getDirectory();
// Get the handle for a file in the directory.
const fileHandle = await root.getFileHandle("my-file.txt");
儲存配額
在 Microsoft Edge 中,本地與會話儲存各限制約 5MB。
其他類型的資料儲存,如 IndexedDB、Cache API 或 Origin Private File System Access API,則可使用裝置上最多 60% 的磁碟空間。 例如,如果你的應用程式所運行的裝置有 64GB 的磁碟,Microsoft Edge 允許你的應用程式儲存約 38GB 的資料。
請注意,裝置上實際可用的空間可能少於 60% 的儲存配額。 舉例來說,如果你執行應用程式的裝置有 64GB 的磁碟,但作業系統和其他檔案已經用了 50GB,即使儲存配額還是 38GB,你的應用程式也只能儲存 14GB 的資料。
你可以用 navigator.storage.estimate() 來詢問 Storage Manager API 應用程式來源的儲存配額是多少,以及已經使用了多少。 欲了解更多,請參閱MDN上的 StorageManager.estimate () 。
嘗試儲存超過可用或允許的資料,會導致 JavaScript 錯誤。 你的程式碼應該會用 try...catch 語句來偵測這個錯誤。 以下程式碼片段展示了如何在使用 Web Storage 儲存資料時捕捉超額配額錯誤:
try {
localStorage.setItem('foo', 'bar');
} catch (e) {
// Code that handles the lack of storage space.
}
資料驅逐
當使用者的裝置開始出現可用磁碟空間不足(也稱為 儲存壓力)時,Microsoft Edge 會開始驅逐非持久性資料。
這表示你的應用程式透過快取 API、IndexedDB、Origin 私有檔案系統存取 API 或網頁儲存所儲存的資料可能會被驅逐。
預設情況下,你 App 儲存的資料不被視為持久的,當儲存壓力增加時可能會被驅逐。 如果你的應用程式儲存了關鍵資料,請使用這個 navigator.storage.persist() 功能讓應用程式的儲存空間持久化。 持久儲存只能由使用者自行清除。 欲了解更多,請參閱 MDN 上的 StorageManager.persist () 。