localForage vs. XHR

22 October 2014   9 comments   JavaScript

Mind that age!

This blog post is 7 years old! Most likely, its content is outdated. Especially if it's technical.


tl;dr; Fetching from IndexedDB is about 5-15 times faster than fetching from AJAX.

localForage is a wrapper for the browser that makes it easy to work with any local storage in the browser. Different browsers have different implementations. By default, when you use localForage in Firefox is that it used IndexedDB which is asynchronous by default meaning your script don't get blocked whilst waiting for data to be retrieved.

A good pattern for a "fat client" (lots of javascript, server primarly speaks JSON) is to download some data, by AJAX using JSON and then store that in the browser. Next time you load the page, you first read from the local storage in the browser whilst you wait for a fresh new JSON from the server. That way you can present data to the screen sooner. (This is how Buggy works, blogged about it here)

Another similar pattern is that you load everything by AJAX from the server, present it and store it in the local storage. Then you perdiocally (or just on onload) you send the most recent timestamp from the data you've received and the server gives you back everything new and everything that has changed by that timestamp. The advantage of this is that the payload is continuously small but the server has to make a custom response for each client whereas a big fat blob of JSON can be better cached and such. However, oftentimes the data is dependent on your credentials/cookie anyway so most possibly you can't do much caching.

Anyway, whichever pattern you attempt I thought it'd be interesting to get a feel for how much faster it is to retrieve from the browsers memory compared to doing a plain old AJAX GET request. After all, browsers have seriously optimized for AJAX requests these days so basically the only thing standing in your way is network latency.

So I wrote a little comparison script that tests this. It's here: https://www.peterbe.com/localforage-vs-xhr/index.html

It retrieves a 225Kb JSON blob from the server and measures how long that took to become an object. Equally it does the same with localforage.getItem and then it runs this 10 times and compares the times. It's obviously not a surprise the local storage retrieval is faster, what's interesting is the difference in general.

What do you think? I'm sure both sides can be optimized but at this level it feels quite realistic scenarios.


Peter Bengtsson

Thank you!
Fixed now.


It's funny that the linked Buggy is buggy! :D

Might want to check if localStorage is enabled before trying to use it kids. Even if there aren't many users who disable cookies by default, your site shouldn't look utterly broken (very embarrassing for you) when they visit ;)

Peter Bengtsson


Are you saying that by Buggy tool isn't perfect?! I'm surprised.

I'm not entirely sure how localforage works if neither IndexedDB or localStorage is enabled.

What does cookies have to do with it?

André Jaenisch

I thought, localForage would fallback to cookies as last resort, if IndexedDB, WebSQL and localStorage aren't available, but it turned out after reading the source code, that IndexedDB > WebSQL > localStorage is the preferred handling.

As far as I understand the code from reading, localForage throws an error, if neither storage technique is usable: https://github.com/mozilla/localForage/blob/master/src/localforage.js#L314 (commit f9556e8).


http://www.peterbe.com/localforage-vs-xhr/index.html is not working for IE8 or IE9. I wonder what will be the results there as localForge supports this ancient browsers :).

Peter Bengtsson

What's IE8 or IE9?


Do I need a server to use localforage? I wanted offline capabilities for an app without any server, but handling data storage and retrieval.

Peter Bengtsson

No not at all. localforage is just a thin wrapper on the browser's localStorage or its IndexedDB capability.

The advantage with localforage is that it's a really simple API interface. Just getItem(), setItem() and removeItem(). Really easy to use.

Normally I just use localforage to store a blob of text that is a piece of JSON. In fact, that's what localforage takes care of for you automatically. You do `localForage.setItem('key', {foo: 'value'})` and then you can do `localForage.getItem('key').then(function(thing) { alert( thing.foo) })`

Your email will never ever be published.

Related posts