PouchDB

PouchDB is the best kept secret in web development. It’s a database that runs in your browser that lets you store and query data locally; it picks a suitable local storage mechanism for you, and presents a clean, modern API to allow your web app to store data.

A database … that runs in your browser. Why would you want that? So that your web application can collect and query data regardless of whether it’s connected to the web or not. Although many of us enjoy fast 4G connectivity on our mobile devices, much of the world has patchy or a prohibitively expensive mobile data service. If your app’s data resides on the user’s mobile device, they can continue to query and create data offline.

But that’s not all. PouchDB database can also sync with remote CouchDB, PouchDB or IBM Cloudant databases letting you modify data on the server side, the client side, or both, and sync in both directions, without loss of data. This unlocks a new generation of web apps – often called offline-first apps. By using local on-device storage, the user gets a high-performance, always-on user experience.

Creating a local database and replicating data from a remote database takes only a few lines of client-side code:

  var localdb = new Pouchdb('mydb');
  var remotedb = new Pouchdb('https://myremote.cloudant.com/mydb');
  localdb.replicate.from(remotedb);

The best news is that PouchDB is free and open source!

Offline-First

A simple example of an offline-first website is my own home page www.glynnbird.com. It’s hosted on Bluemix, IBM’s platform-as-a-service and its dynamic data is synced from a Cloudant NoSQL database. When the page first loads, it replicates its data from Cloudant and stores it locally in PouchDB. By leveraging browser caching, the website’s assets (CSS, JavaScript, etc) are also cached and so the page works even when your machine is not connected to the Internet.

Service Workers

To cache its page assets, my homepage uses the deprecated Appcache API. The best practice today is to use Service Workers instead. The Service Worker API is more complicated than AppCache, but gives the developer fine-grained control of how web requests that originate from client-side code are routed. Requests can go through a local caching layer, be directed to the internet at large, or be answered with custom responses – it’s up to you.

Unfortunately at time of writing, the AppCache API is deprecated and its replacement the Service Workers API, is “experimental” and browser support is patchy.

Web Workers

The Web Workers API is a new API that lets JavaScript code run in multiple threads. Threads are not new in computer science, but JavaScript code has normally been single-threaded, with an event loop handling concurrency. With Web Workers, we can now split our JavaScript code into separate threads; perhaps the database on one thread and the user interface rendering on another. This allows greater parallelism in the execution of JavaScript code, making the most of modern multi-core CPUs and preventing the user interface from becoming jerky or unresponsive, which can happen when database work steals processing time from front-end rendering code.

Programming with multiple threads can be more complicated for the developer because threads are isolated from each other, and communicate via messages or ports.

Using PouchDB in a Web Worker

The worker-pouch plugin transparently moves the database tasks to a separate thread, leaving the main thread free to do other work. Load PouchDB first, then add the worker-pouch plugin:

<script src="pouchdb.js"></script>
<script src="pouchdb.worker-pouch.js"></script>

When you create a new database, add { adapter: 'worker' } as an option, and you’re done:

var db = new PouchDB('mydb', {adapter: 'worker'});

Unfortunately, browser support for Web Workers isn’t universal yet, so you’ll probablly need to detect whether worker-pouch is supported on the browser you are running on and fall back on standard PouchDB if it isn’t. Full details in the worker-pouch README.

Putting it all together

An excellent example of an offline-first web app that uses Cloudant to PouchDB syncing to store data in the browser, is https://www.pokedex.org/. Reference data from the Pokémon games is presented in a web app that:

  • renders nicely on mobile, desktop and tablet
  • uses CSS animations to provide an engaging and performant user interface
  • once loaded, works offline as well as it did online (on browsers that support Service Workers)
  • carefully separates animation and database work into separate threads to give the best performance using Web Workers

The author, Nolan Lawson, is also one of the key contributors to the PouchDB project and his blog about pokedex.org provides much more detail on how he made this Progressive Web App with meticulous attention to detail when it comes to performance.

1 comment on"Running PouchDB in a Web Worker"

  1. […] Running PouchDB in a Web Worker, Glynn […]

Join The Discussion

Your email address will not be published. Required fields are marked *