Frontend Development 10 min read

Understanding Browser Database IndexedDB and Using localForage

This article explains the architecture, features, and compatibility of IndexedDB, compares it with traditional storage options, introduces the localForage library for simplified asynchronous storage, and provides practical code examples for managing data and caching video content in web applications.

LOFTER Tech Team
LOFTER Tech Team
LOFTER Tech Team
Understanding Browser Database IndexedDB and Using localForage

Existing browser storage solutions are unsuitable for large amounts of data: cookies are limited to 4 KB and are sent with every request; LocalStorage provides only a few megabytes and lacks search or custom indexing capabilities. IndexedDB is a non‑relational, NoSQL‑like database designed for key‑value storage.

IndexedDB Architecture

In IndexedDB the smallest unit is a key‑value pair, which corresponds to a record in a relational database. The database contains objectStore objects (analogous to tables) and each record is stored directly as a key‑value pair without predefined fields. Transactions are built‑in, and all read/write operations occur within a transaction.

Both IndexedDB and SQL databases have the concept of a database.

SQL databases have tables; IndexedDB uses objectStore .

SQL records have columns; IndexedDB records are simple key‑value pairs.

Although an objectStore resembles a SQL table, its storage format is much simpler, and all operations are transaction‑based.

Indexes

Indexes are a core feature of IndexedDB, allowing queries on arbitrary object properties rather than just the primary key. An index is defined outside the objectStore but bound to it, providing additional lookup paths.

Without an index you can only query by the primary key; with an index you can query by any attribute path.

Key Features of IndexedDB

Key‑value storage : Stores any JavaScript object; each record has a unique primary key.

Asynchronous : Operations do not block the UI, unlike the synchronous LocalStorage.

Transactional : A failure in any step rolls back the entire transaction.

Same‑origin restriction : Databases are scoped to the origin that created them.

Large storage quota : Typically at least 250 MB, varying by browser and device.

Binary support : Can store ArrayBuffer and Blob objects.

Compatibility

IndexedDB is supported by all major browsers; see caniuse.com for detailed tables.

Browser Storage Quota

Web storage APIs allow developers to query available storage using the StorageManager API, test quota exhaustion with simple tools, handle QuotaExceededError , and understand browser eviction policies.

localForage

localForage is a JavaScript library that provides an asynchronous API similar to LocalStorage but stores data using IndexedDB, WebSQL (deprecated), or falls back to LocalStorage. It supports storing any data type, not just strings, and works across Chrome, Firefox, IE, and Safari (including Safari Mobile).

Usage

// callback form
localforage.setItem('key', 'value', function(err) {
  // if err is non‑null, we got an error
  localforage.getItem('key', function(err, value) {
    // if err is non‑null, we got an error. otherwise, value is the value
  });
});

// Promise form
localforage.setItem('key', 'value').then(function() {
  return localforage.getItem('key');
}).then(function(value) {
  // we got our value
}).catch(function(err) {
  // we got an error
});

// async/await form
try {
  const value = await localforage.getItem('somekey');
  // This code runs once the value has been loaded from the offline store.
  console.log(value);
} catch (err) {
  // This code runs if there were any errors.
  console.log(err);
}

The library adds transaction handling to methods such as setItem and provides a LocalStorage‑like interface.

Multiple Instances

var store = localforage.createInstance({
  name: "nameHere"
});

var otherStore = localforage.createInstance({
  name: "otherName"
});

// Setting a key on one instance does not affect the other.
store.setItem("key", "value");
otherStore.setItem("key", "value2");

Data Caching Practice

Video data fetched asynchronously can be stored in IndexedDB; a version identifier is saved with the data, and if the identifier changes the data is refreshed. This allows pre‑loading videos to avoid playback issues caused by network latency.

const loadVideo = async (url) => {
  let res = await fetchVideoBlob(url);
  return res;
}

export const getVideoData = async (videoKey) => {
  const loadSrc = STORAGE_KEY[videoKey].src;
  return localForage.getItem(STORAGE_KEY[videoKey].key).then(async function(value) {
    if (value && value.src === loadSrc) {
      // localForage successfully got item
      const videoBlobUrl = URL.createObjectURL(value.data);
      return videoBlobUrl;
    } else {
      // localForage failed to get item
      const videoData = await loadVideo(loadSrc);
      const storeData = {
        src: loadSrc,
        data: videoData
      };
      return localForage.setItem(STORAGE_KEY[videoKey].key, storeData).then(function(video) {
        const videoBlobUrl = URL.createObjectURL(video.data);
        return videoBlobUrl;
      });
    }
  }).catch(err => {
    throw new Error(`${videoKey} init error`);
  });
}

localForage does not create indexes; native IndexedDB APIs must be used for that purpose. Developers should also implement error handling, as localForage’s fallback to LocalStorage does not occur automatically when IndexedDB throws errors.

References

IndexedDB compatibility: https://caniuse.com/?search=indexDB

Web storage overview: https://web.dev/i18n/zh/storage-for-the-web/

Quota testing tool: https://storage-quota.glitch.me/

localForage API documentation: https://localforage.docschina.org/

IndexedDB Chinese tutorial: https://www.tangshuang.net/3735.html

frontendIndexedDBweb storageBrowser DatabaselocalForage
LOFTER Tech Team
Written by

LOFTER Tech Team

Technical sharing and discussion from NetEase LOFTER Tech Team

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.