My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Friday, March 02, 2012

What's localStorage About

I've read even too many articles recently talking about storing anything you want in the localStorage ... and I believe this is wrong in so many levels.
First of all, localStorage is not a database, 'cause if you consider it a database you should have considered a database document.cookie before ...

As Simple As That

document.cookie has been there, problematic as it is, since ever.The limit of this technique has always been the 2Mb on average across different browsers.
Have you ever asked yourself what the hell is document.cookie doing and how comes it's instantly available?
Well, it's about storing some stuff in your hard disk or your browser (SQLite) database, so that every single request will send this file loads of key/values pairs through the HTTP request.
The side effect of this technique is that more you pollute cookies in your site to remember stuff, the more the interaction will be slower, specially on mobile, since all these info have to be sent to the server for each bloody request.

What's localStorage Good For

First of all don't forget localStorage does synchronous I/O which means it's blocking and the bigger it is, the slower it will be to retrieve or store data. Secondly, don't forget that if every script in your page is using it, the possibility that its rich 5Mb gonna be filled up are higher.
As summary, the moment you start storing files there you are kinda doing it wrong. You don't know how long it takes to retrieve or store data in the localStorage and the moment you feature detect this delay you have already potentially compromised your page/app visualization time.
localStorage best practice is to keep it small, as small you have kept, hopefully, until now, any document.cookie related task.
Of course if your code is the only one using localStorage, and you have things under control, you may think to use it as generic key/value paris DB but on Web, where usually more than a framework/library is in place, you can't pollute this storage as much as you like because is like polluting the global scope with any sort of crap ... and I hope we got this is bad, right?

As Less As You Can Remembering It's Public

True story bro, if you care about your code behavior don't trust, believe, use, this storage that much. Store what you think is necessary and nothing more, use proper DBs interfaces to store more, use the browser cache if you have your server under control, use the manifest if you want to make your app available off-line.
If you are thinking to speed up, without considering localStorage side-effects, the initialization of your page, storing your script once because it's too heavy ... well, the moment you both block the I/O to read that script and the moment you gonna evaluate it, you have gained zero performances boost in 90% of the cases.
Keep it small, think about other libraries, never be greedy with the localStorage, the worst case scenario is that your web page will temporarily kill your same startup time, or the stored data is more than 5Mb and we are screwed, or other libs in your page may be so greedy to erase everything that's not in their prefixed key namespace in a call

for (var key, i = localStorage.length; i--;) {
key = localStorage.key(i);
if (key.slice(0, 3) !== "my-") {
localStorage.remove(key);
}
}

Without considering the fact that a single clear() call performed from another library would destroy all the data you rely on.

Bear In Mind

document.cookie should be used as client/server channel while localStorage is client only matter. Put in cookies what the server should know, and put in localStorage what you would like to remember for the user always keeping in mind, as explained before, that its data is available for any other lib in your page.

So ... now you know ;)

5 comments:

Aadaam said...

I think I used localStorage for map moderator.

The thing was simple: we had a bunch of POIs on a map (like, between 1000 and 20000 for a city), and you had to tell if some of them was wrong.

We used it as your personal storage as an "unsaved" state... So you moderated like 100 places out, and then you sent those in a batch to a server.

I did this because I didn't want to deal with server-side storage + authentication + unstable data state + unreliable connection.

Still today I use SSS for basically "unsaved document" state. I try to send the changes to the server ASAP, but if the server connection is broken, the client is frozen,anything, it's good if I have something I can just simply reload data from.

So the client assumes the latest revision is in the SSS, loads it on startup, checks with the server if it has a newer one, if not, commits to the server, if yes, loads it from the server. If equals, lets the user edit.

As long as the user's browser didn't freeze, work can be continued and everything will be saved, even if only to the client.

Is it legal usage for data-based documents?:)

lrbabe said...

2MB for document.cookie? I thought it was only 4K...

Andrea Giammarchi said...

Aadaam there are sure cases where localStorage may become handy but it's good to do not abuse it.

Irbabe I remember during test some browser was storing up to many Kb of cookies and I have reached a 2Mb limit.

Cookies have been used to store any sort of data and 2Kb seems too small to me but I will double check and eventually fix the post.

Thanks for underlying this

Chris Price said...

I came across some interesting details on how localStorage is implemented in Firefox, especially relating to your comment about when the performance penalty of the IO being blocking is encountered -
https://blog.mozilla.com/tglek/2012/02/22/psa-dom-local-storage-considered-harmful/

Anonymous said...

As I understand it (and I’m not too sure about this), as soon as a reference to localStorage is seen on a page (compile time?) it blocks the thread and reads the data from disk to populate the localStorage memory for reference. Or maybe it looks for data on disk if the domain has stored data in the past and so it knows localstorage is used there already.

In either case, say we insert an iframe into the page, which is dynamically loaded with a different domain as its source. If we use this iframe to do all the localstorage reading and writing via postMessage as described in this post (http://www.nczonline.net/blog/2010/09/07/learning-from-xauth-cross-domain-localstorage/), wouldn’t the thread only be blocked as soon as we load the iframe? Does this give us an asynchronous method of using localstorage? Or am I totally off?