Client-side Storage
tl;dr
Below
5MB, an effective design pattern is tofetch/XHRdocs per REST/JSON API, store the network payload as is (serialized JSON; string), yet parse and maintain the payload as the in-memory state store (object/array); repeating this parse-per-net when stale, which is observable per Etag or some such. This is buildable into a synch scheme.Note that JSON parses faster than POJO (Plain Old Javascript Obj). It is often less perfomant to parse JSON payload into POJO and then store/pull data to/from, per object key; a scheme relying much, much more on these flakey (browser-variant) storage APIs.
Document Stores
- @ Browser —
Cache/CacheStorageInterface(a.k.a.CacheAPI) is a document store; stores URL-addressable resources per Request/Response (k/v) pairs; aServiceWorkerAPI interface; not well supported. Hard limit on cache size, per browser, per origin.
- Workbox is the latest/leanest way to auto-generate a Service Worker (
.js) and its associated manifest (.json), and to handle theCachedocument store, andIndexedDBas application state store. - Synch schemes
- Background Sync API (Chrome only); a
ServiceWorkerAPI
- Background Sync API (Chrome only); a
- Workbox is the latest/leanest way to auto-generate a Service Worker (
- @ Android — SQLcipher (@ GitHub); an encrypted database; an extension of SQLite. Used by WeChat app (
EnMicroMsg.db). SeeTech.Stacks(- Web Storage API includes two
k-vstores; value must be string; per domain; insecure;5MBlimit; well supported, though not available atWeb Worker; use for small amounts of data. Unlike Cookie API, this is readable by client only. Insecure. Do not store JWTs here.sessionStorage; available for the duration of the page session.localStorage; same, but persists even when browser closed/reopened.store.js(12KB) @IndexedDB(API); value can be anything (JS object); a transactional, asynchronous α store that returns notifications per DOM Events (onsuccess,onerror,oncomplete, …); well supported;IDBDatabaseinterface; RDBM-type key-indexed for high-performance β ; accessible per same-origin policy; storage limited per browser scheme(s). Intro. Best Practices.5MB-10MB, per browser vendor.- Successor to Web SQL Database API.
- Available at
Web Workers. - Wrappers/Libraries (smallest to biggest):
idbidb-keyval; subset ofidb.
- LocalForage (
28KB); fallback toWebSQL, then tolocalStorage; simple but powerful API. - Dexie.js (
55KB); + synch (beta). - PouchDB (
121KB) / RxDB (500KB); synch per CouchDB sync protocol; fallback toWebSQL. - Synch schemes
- CouchDB / PouchDB; CouchDB is a JSON (document) store and (Erlang) server; has its own synch protocol; API (CRUD) is HTTP/REST; distributed architecture, with bi-direction replication and synchronization; designed to handle off-line app operations.
- Firebase; Google's mobile web-app platform; vendor lock-in (superglued to GCP); messaging, OAuth, storage (RT database), and hosting.
- CouchDB / PouchDB; CouchDB is a JSON (document) store and (Erlang) server; has its own synch protocol; API (CRUD) is HTTP/REST; distributed architecture, with bi-direction replication and synchronization; designed to handle off-line app operations.
- α — Do not store JSON payload as one big complex object (value) under one key because … The larger the object, the longer the blocking time … increase write errors … cause the browser tab to crash or become unresponsive.
- β — IndexedDB isn’t as performant as believed … blocks the DOM significantly in Firefox and Chrome … slower than both LocalStorage and WebSQL for basic key-value insertions.
For performance comparison between the two key-value stores, see lab @
DEV/front-end/js/storage/localStorage-vs-IndexedDB. ImmortalDB (
50KB)
A persistentk-vstore; wraps all the browser'sk-vstores, and stores redundantly;cookie,IndexedDB,localStorage, and atsessionStorage; self heals.- Utilizes
idb-keyvalandjs-cookie.
- Utilizes
Web SQL Database API.
- Precursor to
IndexedDBAPI. - No adoption beyond Google Chrome and Android Browser (2010)
- Precursor to
HTTP cookies (
4KB)- HTTP Headers
Cookie@ RequestCookie: <cookie-list> Cookie: name=value Cookie: name=value; name2=value2; name3=value3Set-Cookie@ ResponseSet-Cookie: <cookie-name>=<cookie-value> Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly
- For storing sensitive data; a small piece of data sent by server. Client may store and send it back with next request to same server.
- Browser automatically adds
Cookieheader per request containing all cookies existing/stored of that request's domain. - GDPR (General Data Protection Regulation; 2018) and Cookie Law (ePrivacy Directive; 2002/2009)
- Persistent Cookies require consent notice;
- Session Cookies do not.
HTTP Request Header
- See
Network.HTTP.Headers(set security flags:httpOnlyPrevent XSS; forbid any JS access. SameSite=strictPrevent CSRF. secure=trueVia HTTPSonly.
Web API ::
document.cookieCookies are domain specific; sent by browser only to domain which wrote them.
With every request to a specific domain, the client's web browser looks to see if there is a cookie from that domain on the client's machine. If found, the browser will send the cookie with every request to that domain.
Cookie data limitations: if the data is hex (hash), okay to store raw, else base64-encode the raw string data.
window.btoa(raw) // ... btoa() is scope to Window OR GlobalWorkerCookies :: Special Key Names
__Host-*— Require HTTPS,Secure, sansDomain__Secure-*— Require HTTPS,Secure- Else cookie is not set.
JS Cookie Libraries
js-cookie(1KB); popular; simple API (get,set,remove).Cookies.set(key, val, { path: '/', sameSite: 'strict' }Minimal :: Get / Set ::
document.cookie// Get function cookieGet(name) { var c = "; " + document.cookie; var x = c.split("; " + name + "="); if (x.length === 2) { return x.pop().split(";").shift(); } } // Set function cookieSet(name, value) { var expires = ""; var date = new Date(); date.setTime(date.getTime() + (365 * 24 * 60 * 60 * 1000)); expires = "; expires=" + date.toUTCString(); document.cookie = name + "=" + value + expires + "; path=/"; }
HTTP Caching ::
ETag/If-Matchheaders ( - Web Storage API includes two