Step away from the localStorage

There has been much discussion (example, example, example, example) recently about how the in-browser localStorage API is terrible and must be killed with fire.

My first reaction here is step away from the bacon, son, leave the bacon out of this. The localStorage API seems to have a few quoted problems, the main ones being that it’s synchronous, it does file IO, and it’s got bad event support. Put against that, rather snidely it seems, is the benefit that “it’s easy to use”.

Did I miss a meeting? Is being easy to use suddenly a bad thing? Isn’t that one of the major benefits of using Apple stuff, that it makes sense and people can get it without a PhD in computer science? Or does that only apply to users, who are presumably too busy on the sofa with a bag of Cheetos, and not to developers, who are meant to do things the hard way whenever possible?

Doing file IO and having bad event support are, certainly, issues with localStorage if you’re trying to use it for any kind of really serious data storage. If you’re Gmail, maybe you want something better. But you know what? Most of the things I build aren’t Gmail, and most of the things you build aren’t either. I don’t need event support for localStorage; I just want to stash a value in it and then move on. That’s all. Doing file IO… well, any storage mechanism had better be doing file IO at some point so that my data gets saved to disc!

Ah, no, say the detractors, but it’s synchronous. That’s bad: it blocks. This seems to boil down to two problems: it might block my tab, and it might block other people’s tabs. Now, that’s an issue, right enough. However, blocking my tab is something that I can think about and decide whether I’m prepared to run the risk or not. Because what you’re asking for is that I replace this:

localStorage.setItem("key", "value");

with this

storeSomething = function(key, value) {
    var request = indexedDB.open("mydbname",
        "This is a description of the database.");
    request.onsuccess = function(e) {
        var v = "1.0";
        var db = e.target.result;
        if (v!= db.version) {
            var setVrequest = db.setVersion(v);
            setVrequest.onsuccess = function(e) {
                var store = db.createObjectStore(
                    "myobjectstore", 
                    {keyPath: "timeStamp"});
                var request = store.put({key: value, 
                    "timeStamp" : new Date().getTime()});
                request.onsuccess = function(e) {
                    // now carry on with what I was doing
                };
            };
        }
    };
}

and you know what? Given that choice… I believe I might at least sometimes choose that blocking my tab for a microsecond and very occasionally blocking my tab for two whole seconds is actually OK. I’m allowed! It’s my tab!

Fine, I’m being a bit facetious. There are problems with localStorage, and it would be good to see them resolved. But there are alternatives other than “you must ditch it and use IndexedDB, Mr Developer”, I think. What would be wrong with providing an asynchronous variant of localStorage, so I do localStorage.setItemAsync("key", "value", function() { carryon... })? Mozilla say “Implement localStorage in an asynchronous fashion in browsers – actively disregarding the spec? (this could set a dangerous precedent though)”, as if the idea of the browser manufacturers working together to adjust the spec is just impossible; did I miss something there? The spec process is open to stuff being adjusted or added to; that’s the point of it, right? And localStorage use in my tab blocking other people’s tabs… I can’t think of a nice way of saying “that’s a browser issue”, but it is. I feel sad having to say that, because I know that the engineers at Mozilla and other places have done superhuman work in this area and will continue to do so, but really one tab blocking causing others to block is surely something which is a problem for more than just localStorage?

There are problems with localStorage. Real ones. But I think that those calling for its complete removal are vastly underestimating the attractiveness of an API that’s easy to use, and also vastly underestimating how annoying it is to be forced to use something way more complicated because it copes better with pathological cases. I’d love to hear more argument on this subject, but I don’t want it to look like there’s a consensus around “it must go”. Someone needs to speak up for developers who just wanna get stuff done, like me…