HTML5 localStorage

I played around with HTML5 localStorage today, a way for Javascript on a web site to store persistent data client-side in the browser with a simple key/value store. It’s pretty neat, works well in modern browsers (IE8+, everything else), but is kind of slow. Here’s what I learned.

Useful docs:

The API is really simple. Boils down to

  • setItem(key, value)
  • getItem(key)
  • removeItem(key)
  • clear()
  • key(index)
  • length

key and value are both strings. If you want to store Object values, as is sensible, you have to serialize them yourself to JSON like this.

length and key(index) let you iterate over the collection in an undefined order. Also it’s undefined what happens if someone asynchronously modifies localStorage while you’re iterating. localStorage is not an Array, so you can’t use modern methods like forEach() on them. Back to the old school for loop.

It all works pretty well and is straightforward. My one complaint is it seems pretty slow, at least in Chrome. I’ve put about 3200 objects in localStorage, about 200 bytes each. That’s not much data, but with it even just iterating over all the keys (doing nothing with the values) is slow, like 400ms. Here’s my code that is so slow:

function getLocalKeys() {
    var localKeys = [];
    var n = localStorage.length;
    for (var i = 0; i < n; i++) {
        localKeys.push(localStorage.key(i));
    }
    return localKeys;
}

Surprisingly, doing real work on the values isn’t much slower. I can parse all the value strings back into Javascript objects and then sort an array of all 3000 objects and it doesn’t add appreciable time to the work. That suggests all the time is spent in the localStorage implementation itself. I wonder if it’s actually going to disk? Need to dig in more.

I could optimize by storing my collection of all keys itself as a value in localStorage, sort of my own index. But that’s brittle if I forget to update it in the code.

Update: some performance notes here and here confirm it’s not just me seeing bad performance. One issue is that localStorage needs to be synchronous across multiple browser tabs, so localStorage may be implemented as purely on-disk to do that easily. Both benchmarks suggest Chrome is uniquely slow and indeed my code runs visibly faster in Safari.

Update 2: I rewrote my code to simply have one object in localStorage, itself a stringified Javascript Object operating as a hash table. That works much, much faster; the storage time is negligible. My data is 500k stringified, btw, uncomfortably close to the 2.5MB limit!

2 thoughts on “HTML5 localStorage

  1. interesting! i thought being disk backed was part of the promise of localStorage, at least originally, so it could be used to implement offline webapps. i guess i did expect something like a write through cache so reads and iterating are faster, though, especially if iterating behavior is undefined when there are concurrent modifications. maybe it’s still not widely used enough that there’s much pressure on the browser vendors to speed it up.

    have you looked at any of the generic data synchronization protocols intended for localStorage and offline webapps? i know Google and MS each did one, and i expect there are open source one(s) too. deceptively difficult and interesting problem!

  2. Yeah being disk backed is essential, but it’s a shame there’s apparently no cache of any sort. I suspect most apps use localStorage to store just one or two keys, not a whole bunch like it was a hashtable. My plan is to do that myself, maintain my own data structure as a single key in localStorage.

    I haven’t looked at any of the higher level data storage libraries. The new HTML5 standards hotness seems to be IndexedDB, but it’s still a bit in flux.

Comments are closed.