使用 IndexedDB 持續保留應用程式狀態的最佳做法

瞭解在 IndexedDB 和熱門狀態管理程式庫之間同步應用程式狀態的最佳做法。

使用者首次載入網站或應用程式時,通常需要花費大量心力建構初始應用程式狀態,用於算繪 UI。舉例來說,應用程式有時需要在用戶端驗證,然後提出多項 API 要求,才能取得需要在頁面上顯示的所有資料。

將應用程式狀態儲存在 IndexedDB 中,是加快重複造訪載入時間的絕佳方法。接著,應用程式就能在背景同步處理任何 API 服務,並以「stale-while-revalidate」策略,以非同步方式更新 UI 中的新資料。

不過,使用 IndexedDB 時,有許多重要事項需要考量,這些事項對新手開發人員來說可能不太明顯。本文件將回答常見問題,並討論在 IndexedDB 中儲存應用程式狀態時,應留意的一些重要事項。

讓應用程式提供可預測的體驗

IndexedDB 的許多複雜性都源自於開發人員無法控制的許多因素。本節將探討使用 IndexedDB 時必須留意的許多問題。

寫入儲存空間可能會失敗

寫入 IndexedDB 時可能會發生錯誤,原因有很多種,在某些情況下,這些原因超出開發人員的控制範圍。舉例來說,部分瀏覽器不允許在私人瀏覽模式下寫入 IndexedDB。使用者的裝置磁碟空間可能快用完,瀏覽器就會限制使用者無法儲存任何內容。

因此,請務必在 IndexedDB 程式碼中一律實作適當的錯誤處理機制。這也表示,除了儲存應用程式狀態之外,通常將其保留在記憶體中也是不錯的做法,這樣一來,即使在私人瀏覽模式下執行或無法使用儲存空間,使用者介面也不會中斷 (即使某些需要儲存空間的其他應用程式功能無法運作也是如此)。

儲存的資料可能已遭使用者修改或刪除

與伺服器端資料庫不同,您無法限制未經授權的存取,瀏覽器擴充功能和開發人員工具可以存取用戶端資料庫,而且使用者可以清除這些資料庫。

雖然使用者不太可能修改本機儲存的資料,但清除資料則是常見的操作。應用程式必須能夠處理這兩種情況,且不會發生錯誤。

儲存的資料可能已過時

與前一個部分類似,即使使用者未自行修改資料,他們儲存的資料也可能是由舊版程式碼 (可能含有錯誤) 寫入。

IndexedDB 內建支援結構定義版本,並可使用其 IDBOpenDBRequest.onupgradeneeded() 方法進行升級;不過,您仍需要以可處理來自舊版 (包括有錯誤的版本) 的使用者的方式編寫升級程式碼。

單元測試在這裡非常實用,因為手動測試所有可能的升級路徑和案例通常不切實際。

確保應用程式效能良好

IndexedDB 的一項重要功能是其非同步 API,但請勿誤以為使用時不必擔心效能。在許多情況下,不當使用方式仍可能封鎖主執行緒,導致無回應。

一般來說,對 IndexedDB 的讀取和寫入作業不應超過存取資料所需的大小。

雖然 IndexedDB 可將大型巢狀物件儲存為單一記錄 (從開發人員的角度來看,這麼做確實相當方便),但不建議採用這種做法。這是因為 IndexedDB 儲存物件時,必須先建立該物件的結構化複本,而結構化複製程序會在主執行緒上執行。物件越大,阻斷時間就越長。

在規劃如何將應用程式狀態儲存至 IndexedDB 時,這會帶來一些挑戰,因為大多數熱門的狀態管理程式庫 (例如 Redux) 會將整個狀態樹狀結構視為單一 JavaScript 物件來管理。

雖然以這種方式管理狀態有許多優點,而且將整個狀態樹狀結構儲存在 IndexedDB 中做為單一記錄可能很誘人且方便,但在每次變更後執行這項操作 (即使已節流/去抖動) 會導致主執行緒不必要地阻斷,進而增加寫入錯誤的可能性,在某些情況下甚至會導致瀏覽器分頁當機或沒有回應。

請將整個狀態樹狀圖分割成個別記錄,並只更新實際變更的記錄,而非將整個狀態樹狀圖儲存在單一記錄中。

如同大多數最佳做法,這並非全有或全無的規則。如果無法分割狀態物件,而只能寫入最少的變更集,則將資料分割為子樹狀結構,並只寫入這些子樹狀結構,仍比一律寫入整個狀態樹狀結構來得好。即使只有小幅改善,也比完全沒有改善來得好。

最後,您一律應評估所寫程式碼的效能影響。雖然寫入 IndexedDB 的小型資料會比大量資料的寫入作業效能更好,但這只有在應用程式執行的 IndexedDB 寫入作業實際上導致長時間任務,而阻斷主執行緒並降低使用者體驗時才重要。請務必進行評估,瞭解您要最佳化的目標。

結論

開發人員可以使用 IndexedDB 等用戶端儲存機制,不僅可在各個工作階段中保留狀態,還可縮短重複造訪時載入初始狀態所需的時間,進而改善應用程式的使用者體驗。

雖然正確使用 IndexedDB 可大幅改善使用者體驗,但如果使用方式不正確或無法處理錯誤情況,可能會導致應用程式損毀,使用者也會因此感到不滿。

由於用戶端儲存空間涉及許多您無法控制的因素,因此務必確保程式碼經過充分測試,並能妥善處理錯誤,即使這些錯誤一開始似乎不太可能發生也一樣。