Yet another intro for localStorage and sessionStorage

肥仔John 發表於 2021-10-04

As we know, localStorage and sessionStorage have came up for years. They're commonly used in front-end cache for both online and offline situations, like, storing JWT.
I suppose you have been way familar with them already, so here's just a quick note for myself. If it's also your jam, stay tuned!

Why we need additional storage objects besides cookies?

Although cookie is capable of storing in client-side, but there are some downsides where the web storage objects have value of.

  • Unlike cookies, web storage objects will not be sent along with every single request. There is no much extra workload, even if we store dozens of data by web storage objects.
  • Most browsers allow at least two megabytes or more (have to configure by user themselves) for web storage objects, so we could have better performance by cache more.
  • The data stored in web storage object can survive from page refresh and even a full browser or OS restart.

The same APIs for both web storage objects

LocalStorage and sessionStorage both land as the immediate property of global object(that's, window), and provide the same APIs for us.

  • setItem(key: string, value: any): void store a key/value pair.
  • getItem(key: string): string get value by key.
  • removeItem(key: string): void remove a key with its value.
  • clear(): void delete everything.
  • key(index: number): string get the key on given position.
  • length: number get the amount of key/value pairs.

The most important thing to note is that, the value passed into setItem method would be converted to a string automatically before store, that means it will call the toString method of the given value first, and then save the returned value finally. If you want to put an object in, call JSON.stringify first, and then execute JSON.parse when get it back.

And it's possible to stringify the whole storage object, e.g. for debugging purposes:

// add formatting options to JSON.stringify to make the object look prettier.
JSON.stringify(localStorage, null, 2)

What's the difference between them?

  • The ability for cross-context communication:

    • SessionStorage is scoped on per-window basis, that means multiple browser tabs with documents on the same origin have a separated sessionStorage, but iframes on the same origin within the same window/tab can share the sessionStorage.
    • LocalStorage can be shared between all browsing-contexts(iframe, window and tabs) and workers.
  • The expiration machinsm:

    • Data stored in sessionStorage will expire automatically when close the browser tab.
    • Data persisted in localStrorage will live as long as it could until user perform data clearence.

Detecting changes by StorageEvent

We can detect all changes(adds, updates and deletes) on both localStorage and sessionStorage.
Here's the properties of StorageEvent:

  • key the key that was changed, null if clear() is called.
  • oldValue the old value, null if the key is newly added.
  • newValue the new value, null if the key is deleted.
  • url the url of the ducument where the change happend.
  • storageArea either localStorage or sessionStorage object where the change occured.

There is a pitfall when listening changes on localStorage, that's event handler will not be called when the change is performed in the same browsing-context, for instance like below:

// a.html
window.addEventListener('storage', evt => {
    console.log('a:', evt.key)
setTimeout(()=> {
    localStorage.setItem('a', 1)
}, 5000)

// b.html
window.addEventListener('storage', evt => {
    console.log('b:', evt.key)
setTimeout(()=> {
    localStorage.setItem('b', 1)
}, 10000)

Console for a.html will show a:b after ten seconds, and that of b.html will echo b:a in five seconds.