10 Client-side Storage Options and When to Use Them


Ten Client-side Storage Options

Storing and manipulating data in the browser — also known as client-side storage — is useful when it’s not necessary or practical to send it to the web server.

Situations for storing and manipulating data in the browser include:

  • retaining the state of a client-side application — such as the current screen, entered data, user preferences, etc.
  • utilities which access local data or files and have strict privacy requirements
  • progressive web apps (PWAs) which work offline

Here are ten ways to store browser data:

This article digs into these ten different ways to store data in the browser, covering their limits, pros, cons, and the best uses of each technique.

Before we browse the options, a quick note about data persistence …

Data Persistence

In general, data you store will either be:

  1. persistent: it remains until your code chooses to delete it, or
  2. volatile: it remains until the browser session ends, typically when the user closes the tab

The reality is more nuanced.

Persistent data can be blocked or deleted by the user, operating system, browser, or plugins at any point. The browser can decide to delete older or larger items as it approaches the capacity allocated to that storage type.

Browsers also record page state. You can navigate away from a site and click back or close and re-open a tab; the page should look identical. Variables and data regarded as session-only are still available.

1. JavaScript Variables

metric comment
capacity no strict limit but browser slowdowns or crashes could occur as you fill memory
read/write speed the fastest option
persistence poor: data is wiped by a browser refresh

Storing state in JavaScript variables is the quickest and easiest option. I’m sure you don’t need an example, but …

const
  a = 1,
  b = 'two',
  state = {
    msg:  'Hello',
    name: 'Craig'
  };

Advantages:

  • easy to use
  • fast
  • no need for serialization or de-serialization

Disadvantages:

  • fragile: refreshing or closing the tab wipes everything
  • third-party scripts can examine or overwrite global (window) values

You’re already using variables. You could consider permanently storing variable state when the page unloads.

2. DOM Node Storage

metric comment
capacity no strict limit but not ideal for lots of data
read/write speed fast
persistence poor: data can be wiped by other scripts or a refresh

Most DOM elements, either on the page or in-memory, can store values in named attributes. It’s safer to use attribute names prefixed with data-:

  1. the attribute will never have associated HTML functionality
  2. you can access values via a dataset property rather than the longer .setAttribute() and .getAttribute() methods.

Values are stored as strings so serialization and de-serialization may be required. For example:

// locate <main> element
const main = document.querySelector('main');

// store values
main.dataset.value1 = 1;
main.dataset.state = JSON.stringify({ a:1, b:2 });

// retreive values
console.log( main.dataset.value1 ); // "1"
console.log( JSON.parse(main.dataset.state).a ); // 1

Advantages:

  • you can define values in JavaScript or HTML — such as <main data-value1="1">
  • useful for storing the state of a specific component
  • the DOM is fast! (contrary to popular opinion)

Disadvantages:

  • fragile: refreshing or closing the tab wipes everything (unless a value is server-rendered into the HTML)
  • strings only: requires serialization and de-serialization
  • a larger DOM affects performance
  • third-party scripts can examine or overwrite values

DOM node storage is slower than variables. Use it sparingly in situations where it’s practical to store a component’s state in HTML.

3. Web Storage (localStorage and sessionStorage)

metric comment
capacity 5MB per domain
read/write speed synchronous operation: can be slow
persistence data remains until cleared

Web Storage provides two similar APIs to define name/value pairs. Use:

  1. window.localStorage to store persistent data, and
  2. window.sessionStorage to retain session-only data while the browser tab remains open (but see Data Persistence)

Store or update named items with .setItem():

localStorage.setItem('value1', 123);
localStorage.setItem('value2', 'abc');
localStorage.setItem('state', JSON.stringify({ a:1, b:2, c:3 }));

Retrieve them with .getItem():

const state = JSON.parse( localStorage.getItem('state') );

And delete them with .removeItem():

localStorage.removeItem('state')

Other properties and methods include:

Changing any value raises a storage event in other browser tabs/windows connected to the same domain. Your application can respond accordingly:

window.addEventListener('storage', s => {

  console.log(`item changed: ${ s.key }`);
  console.log(`from value  : ${ s.oldValue }`);
  console.log(`to new value: ${ s.newValue }`);

});

Advantages:

  • simple name/value pair API
  • session and persistent storage options
  • good browser support

Disadvantages:

  • strings only: requires serialization and de-serialization
  • unstructured data with no transactions, indexing, or search
  • synchronous access will affect the performance of large datasets

Web Storage is ideal for simpler, smaller, ad-hoc values. It’s less practical for storing large volumes of structured information, but you may be able to avoid performance issues by writing data when the page unloads.

4. IndexedDB

metric comment
capacity depends on device. At least 1GB, but can be up to 60% of remaining disk space
read/write speed fast
persistence data remains until cleared

IndexedDB offers a NoSQL-like low-level API for storing large volumes of data. The store can be indexed, updated using transactions, and searched using asynchronous methods.

The IndexedDB API is complex and requires some event juggling. The following function opens a database connection when passed a name, version number, and optional upgrade function (called when the version number changes):

// connect
function dbConnect(dbName, version, upgrade) {

  return new Promise((resolve, reject) => {

    const request = indexedDB.open(dbName, version);

    request.onsuccess = e => {
      resolve(e.target.result);
    };

    request.onerror = e => {
      console.error(`indexedDB error: ${ e.target.errorCode }`);
    };

    request.onupgradeneeded = upgrade;

  });

}

The following code connects to a myDB database and initializes a todo object store (analogous to a SQL table or MongoDB collection). It then defines an auto-incrementing key named id:

(async () => {

  const db = await dbConnect('myDB', 1.0, e => {

    db = e.target.result;
    const store = db.createObjectStore('todo', { keyPath: 'id', autoIncrement: true });

  })

})();

Once the db connection is ready, you can .add new data items in a transaction:

db.transaction(['todo'], 'readwrite')
  .objectStore('todo')
  .add({ task: 'do something' })
  .onsuccess = () => console.log( 'added' );

And you can retrieve values, such as the first item:

db.transaction(['todo'], 'readonly')
  .objectStore('todo')
  .get(1)
  .onsuccess = data => console.log( data.target.result );
  // { id: 1, task: 'do something' }

Advantages:

  • flexible data store with the largest space
  • robust transactions, indexing, and search options
  • good browser support

Disadvantages:

  • a complex callback and event-based API

IndexedDB is the best option for reliably storing large quantities of data, but you’ll want to reach for a wrapper library such as idb, Dexie.js, or JsStore.

Continue reading
10 Client-side Storage Options and When to Use Them
on SitePoint.

This article was republished from its original source.
Call Us: 1(800)730-2416

Pixeldust is a 20-year-old web development agency specializing in Drupal and WordPress and working with clients all over the country. With our best in class capabilities, we work with small businesses and fortune 500 companies alike. Give us a call at 1(800)730-2416 and let’s talk about your project.

FREE Drupal SEO Audit

Test your site below to see which issues need to be fixed. We will fix them and optimize your Drupal site 100% for Google and Bing. (Allow 30-60 seconds to gather data.)

Powered by

10 Client-side Storage Options and When to Use Them

On-Site Drupal SEO Master Setup

We make sure your site is 100% optimized (and stays that way) for the best SEO results.

With Pixeldust On-site (or On-page) SEO we make changes to your site’s structure and performance to make it easier for search engines to see and understand your site’s content. Search engines use algorithms to rank sites by degrees of relevance. Our on-site optimization ensures your site is configured to provide information in a way that meets Google and Bing standards for optimal indexing.

This service includes:

  • Pathauto install and configuration for SEO-friendly URLs.
  • Meta Tags install and configuration with dynamic tokens for meta titles and descriptions for all content types.
  • Install and fix all issues on the SEO checklist module.
  • Install and configure XML sitemap module and submit sitemaps.
  • Install and configure Google Analytics Module.
  • Install and configure Yoast.
  • Install and configure the Advanced Aggregation module to improve performance by minifying and merging CSS and JS.
  • Install and configure Schema.org Metatag.
  • Configure robots.txt.
  • Google Search Console setup snd configuration.
  • Find & Fix H1 tags.
  • Find and fix duplicate/missing meta descriptions.
  • Find and fix duplicate title tags.
  • Improve title, meta tags, and site descriptions.
  • Optimize images for better search engine optimization. Automate where possible.
  • Find and fix the missing alt and title tag for all images. Automate where possible.
  • The project takes 1 week to complete.