localStorage, perhaps not so harmful
Recently, Christian Heilmann and Taras Glek, both at Mozilla, posted articles critical of localStorage. The arguments in each of these really didn’t gel with my experience, and both felt unduly alarmist (“considered harmful” as argued elsewhere really should be retired as a post heading). So, I wanted to run the ruler over the arguments, and see whether they had validity.
Christian’s and Tara’s positions are very similar, so I’ll address them via Christian’s post. The essence of Christian’s criticism is
we have to stop advocating localStorage as a great opportunity for storing data as it performs badly
Strong words indeed. Is there evidence to back this up?
Christian then outlines these concerns in more detail
localStorage is synchronous in nature, meaning when it loads it can block the main document from rendering
Now, this is certainly true, and in theory, we could block the main UI in most browsers (Opera threads the main browser UI separately from scripts), as well as blocking the remainder of a script which uses localStorage while it waits on a read or write. But, in practice, is this a big deal? I’m a bit of a fan of evidence and testing, rather than theory alone, so I set out to test this. You can follow along at home if you like
Reading, writing and arithmetic
Here’s what I did. The test page allows you to specify what you want to save (as everything is saved to localStorage as a string, you just input a string value), and how many times you want to save it. Then, I just save the string that number of times to localStorage in a tight loop, measuring how long it takes, and report that back. Keep in mind this is very quick and dirty, and can fall over without any warning if you over fill your localStorage.
The test is really simple, but we should get a sense of how big a performance hit localStorage is. Here are results for writing 18bytes 10,000 times inside a tight loop (results are meant to be indicative), then reading them back out again
Browser | Write 10K | Read 10K |
---|---|---|
IE10 | 1250ms | 24ms |
Chrome (19) | 2097ms | 1578ms |
Safari 5 | 58ms | 3ms |
Firefox 8 | 232ms | 130ms |
Opera 11.6 | 764ms | 597ms |
iPhone 4G iOS 5.0 | 115ms | 82ms |
iPad 1 iOS 5.0 | 102ms | 69ms |
At worst, we have a 2s wait (in, of all browsers Chrome 19, a developer preview). In many browsers the wait is less than a tenth of a second. Remember this is for reading or writing 10,000 times to localStorage.
What about for larger amounts of data? Here’s the results for reading and writing 128 bytes
Browser | Write 10K | Read 10K | Chrome (19) | 2081ms | 1514ms |
---|---|---|
Safari 5 | 57ms | 3ms |
Firefox 8 | 250ms | 136ms |
Opera 11.6 | 664ms | 614ms |
iPhone 4G iOS 5.0 | 221ms | 112ms |
iPad 1 iOS 5.0 | 161ms | 69ms |
So, in essence, we’re really not seeing the performance impacted even when we increase the amount of data stored by a factor of 6 or so.
Given that writing 10,000 times to localStorage in a tight loop is I’d argue an edge case (and probably not advisable), on the face of it, the assertion that localStorage, being synchronous, and for that very reason has performance issues is largely misplaced in fact.
Christian continues
localStorage does file I/O meaning it writes to your hard drive, which can take long depending on what your system does (indexing, virus scanning…)
On a developer machine these issues can look deceptively minor as the operating system cached these requests – for an end user on the web they could mean a few seconds of waiting during which the web site stalls depending on what your system does (indexing, virus scanning…)
emphasis mine
Again in theory this looks worrisome, but I think in practice browser developers will use some sort of in memory caching and then asynchronously write to disk (actually based on my tests below I suspect that’s what they are doing)
In order to appear snappy, web browsers load the data into memory on the first request – which could mean a lot of memory use if lots of tabs do it
They may do, but this is an implementation detail for browser developers, and regardless of whatever mechanism they implement for persistent client side data (IndexedDB, webSQL…) in order to appear snappy, some sort of memory caching will be required.
localStorage is persistent. If you don’t use a service or never visit a web site again, the data is still loaded when you start the browser
Again this is an implementation detail for browser developers, and I doubt browsers have to load the localStorage DBs for all pages ever stored when they launch. I can imagine all kinds of caching strategies to balance responsiveness with memory use, application developers (speaking as one for many years) do this sort of thing all the time.
But above all, in practice, are we actually seeing any of this taking place in the wild? Can Christian point to sites that are suffering because of these theoretical limitations in localStorage?
Christian then makes something of a curious leap when he argues
In essence this means that a lot of articles saying you can use localStorage for better performance are just wrong
So, when the likes of Steve Souders, and teams of very smart people at places like Google and Bing research and develop techniques using localStorage for client side resource caching, they are “just wrong” because in theory localStorage has performance issues. To be direct, I find this position baffling. Especially when not a single datapoint is quoted (the tests cases I developed here took in the order of an hour, so it’s not overly taxing to do).
None of this is to say localStorage is perfect. Its limitations as to storage size, the fact that everything stored is simply a string, and that JavaScript strings are UTF-16, thereby halving the effective storage space are all real issues. Is the synchronous nature of localStorage an issue? Synchronous APIs are easier for developers to use (no need for callback functions), and so the idea of a simple client side storage mechanism, webStorage, coupled with a more sophisticated, high performance database standard (currently mired in standardization issues, far from localStorage’s fault) makes excellent architectural sense IMO.
But frankly, Christian and Tara do developers no benefit asserting localStorage is “harmful”, or that “there is no simple solution for local storage”. localStorage is very widely supported (IE8 up), very straightforward to use, has excellent performance for most use cases, and has been implemented in a large number of real world projects, including by Bing and Google. Sure, if you’re writing an app that does 10K simultaneous writes to a database, you’ll have the chops to get around a 2s write time in the worst case, but you will doubtless have all kinds of other performance and memory use challenges. So by all means help developers understand the potential shortcomings of a given technology, outline the gotchas, and workarounds, and propose improvements. But do so based on evidence, and also with the acknowledgement that localStorage is here to stay, and that any alternative also faces many similar, as well as their own additional challenges, and in the case of client side storage is perhaps years away from the same level of support as webStorage. The perfect, as is often stated, is the enemy of the good, or adequate. Let’s by all means make the adequate good, and the good excellent, but let’s not wait around forever for the perfect. We’ll be waiting a while.
Edited to correct Taras’ name
Great reading, every weekend.
We round up the best writing about the web and send it your way each Friday.