Channels ▼
RSS

Web Development

Understanding Client-Side Storage in Web Apps


When the Web was young, our servers were powerful and our clients were weak — so websites stored the vast majority of their data and logic on the server. But now we have increasingly more powerful clients, thanks in large part to the rapid innovation of mobile browsers and the advent of HTML5. As a result, websites are moving more of their data and logic to the client.

In this two-part series, I explain how to store data on the client using HTML5 APIs, and how client-side storage can improve both application performance and the user experience.

How We Got Here

To understand client-side storage today, it helps to look at the history of how we got to where we are now. In the first iteration of the Web, there was no way for websites to store data in the browser that would persist across browser sessions. It was possible to store state by using the query URL, like remembering a session ID (?sessionID=3213) and retrieving state from a database, but if users left a website or restarted their computer, the session information would be gone.

In 1994, a few engineers at Netscape were working on an e-commerce solution and needed a way to track the content of shopping cart baskets across browser sessions. They invented the concept of Web cookies (based on the computing concept of "magic cookies") and introduced them in the Mosaic Netscape browser later that year. Internet Explorer (IE) supported them the following year in IE2, and soon many websites started using them. They were most often used for user sessions, website personalization, ad tracking, and website analytics.

There was an increasing number of issues with cookies, however, especially as Web developers tried to use them in ways the creators didn't originally envision.

Cookies pose multiple security issues. They are unencrypted, so unless your entire website is delivered over SSL, the cookies aren't secure. As some hackers discovered, cookies can also be stolen via cross-site scripting techniques and DNS spoofing. When users found out about the security and privacy issues with cookies (thanks to mainstream news articles and US FTC hearings), many users started to restrict or entirely disable cookies — meaning that websites could not always assume they could use cookies.

Cookies also pose performance issues. Because cookies are included in every HTTP request, they can affect how long it takes for a browser to download a webpage — which means you don't want to store large amounts of data in them. And even if you wanted to store lots of data, you usually couldn't. Most browsers restricted each cookie to a max size of 4KB and allowed a max of 20 cookies per domain — not a lot of space.

Web developers wanted a way to persistently store data in the client, and they weren't getting what they needed from cookies. A few clever developers came up with hacks for client-side storage, like using window.name or Flash local storage, but, well, you can only go so far with these hacks.

The HTML5 Storage APIs

Luckily, we are now in the era of "HTML5": the new set of HTML, CSS, and JavaScript specifications that try to make Web development easier and websites more powerful. These specifications include multiple approaches to client-side storage that go far beyond cookies: localStorage, IndexedDB, and the File API. Why multiple approaches? As we'll see, the APIs are quite different and so are their use cases.

localStorage

The localStorage API comes from the Web Storage specification, and it's the simplest of the APIs. It's a straighforward key/value store for string values that persists the data in the browser. That spec also includes sessionStorage, a way to store data for just a session, but it's not pertinent to this discussion because it's not as persistent. Both APIs expose the same set of methods for setting and getting items, plus events for finding out when items are added and removed.

In this example, I store a favorite fish in localStorage, retrieve and display the value, and then remove the value and check that it's gone.

localStorage.setItem('favoriteFish', 'tuna');
document.getElementById(‘fish’).innerHTML = “My favorite fish is: “ + localStorage.getItem('favoriteFish');

localStorage.removeItem('favoriteFish');
if (!localStorage.getItem('favoriteFish')) {
  document.getElementById(‘fish’).innerHTML = “I don’t have a favorite fish anymore :( ”;
}


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Comments:

ubm_techweb_disqus_sso_-fa15af4a2bd791bed7b1ae734fb867c2
2012-06-28T12:47:34

Enjoyed the article and overview of these APIs. Thanks for the write-up. However, the compatibility table and comments about compatibility of the File API are incorrect. caniuse.com has more information:
http://caniuse.com/#feat=filea...

Firefox has supported it since 3.6. Also Opera and Opera Mobile have both had it since their version 11.1's.

Thanks again for the write-up.


Permalink
ubm_techweb_disqus_sso_-4932a5b9e22af120823590e699c132dd
2012-05-07T19:26:25

Great intro to the topic. Thanks!


Permalink
dblake950
2012-04-26T15:07:38

Thanks for the catch (the storage restrictions table inadvertently contained data from the previous table on page 2). It is fixed now.


Permalink
ubm_techweb_disqus_sso_-37e5dd9e69f532e484cd41859c9f946d
2012-04-25T14:10:27

I think you have some problems in the storage restrictions table on page 3. The storage quota you provide for localstorage is actually the quota for IndexedDB. localstorage's restriction should read something like "varies; 2MB up to free disk space, averaging around 5MB."


Permalink
Dr. Dobb's TV