Can Blazor WebAssembly reliably verify restored state after Service Worker cache rebuild?
0 reputation · 29 Oct 2022, 17:12 UTC
0 reputation · 29 Oct 2022, 17:12 UTC
When a Blazor WebAssembly app is installed as a PWA and the Service Worker cache is rebuilt—due, for example, to an update or a manual cache purge—developers need to ensure that any data persisted in localStorage or sessionStorage remains intact and reflects the latest application state.
The unresolved question is how to implement a robust, low‑overhead verification mechanism that confirms the integrity of restored data immediately after a cache rebuild.
localStorage?33275 reputation · 29 Oct 2022, 20:41 UTC
Yes, Blazor WebAssembly can reliably verify restored state, but it is critical to understand that a Service Worker cache rebuild affects static assets (DLLs, WASM, HTML), not the browser storage (LocalStorage, IndexedDB) where application state is typically persisted. Because these are separate storage mechanisms, state remains intact during a cache rebuild unless the browser explicitly clears site data or the developer manually triggers a purge.
To ensure the integrity of restored data—especially when a new version of the app may have changed the data schema—the most robust approach is to use a Versioned Hash strategy. Since Blazor does not provide a built-in hashing function, you must leverage the browser's native capabilities via JS Interop.
SubtleCrypto.digest('SHA-256', data) method. This is the most suitable strategy because it is hardware-accelerated, native to all modern browsers, and handles complex JSON strings efficiently without adding external library overhead.{
"version": "1.2.0",
"hash": "a5f6...",
"payload": { ... }
}
OnInitializedAsync), retrieve the object, re-calculate the hash of the payload, and compare it to the stored hash.version is outdated, treat the state as corrupted. To preserve the offline experience, implement a fallback chain: Attempt to load a cached "safe default" state first, then trigger a background fetch to synchronize with the server once connectivity is confirmed.This approach assumes that the state is small enough to fit in LocalStorage (typically <5MB). For larger datasets, IndexedDB is recommended, though the hashing logic remains the same. Be aware that localStorage access is synchronous and can block the UI thread if the payload is excessively large; for high-performance needs, perform the hashing in a separate JavaScript worker.
To verify if your state survives a cache rebuild during development, use the Chrome DevTools Application tab: check "Update on reload" under the Service Worker section, refresh the page, and observe if your LocalStorage keys persist while the Cache Storage is cleared and rewritten.
Diagnostic Detail Needed: Are you persisting state as simple JSON strings in LocalStorage, or are you utilizing a more complex structure like IndexedDB?
Use comments to ask for clarification. Post a solution as an answer.
33,275 reputation · 29 Oct 2022, 17:41 UTC
When hashing the payload, first serialize it with JSON.stringify(state, Object.keys(state).sort()) to guarantee a stable byte sequence regardless of property order; otherwise a harmless reorder could cause a false mismatch. Encode the string with new TextEncoder().encode() before passing it to SubtleCrypto.digest('SHA-256', ...). Because storage reads are asynchronous, perform the hash comparison inside an async OnInitializedAsync handler and await both localStorage.getItem (via JS interop) and the crypto operation; this avoids race conditions where the app renders before verification completes.