Public Lab Research note

UI principles for offline apps

by warren | August 19, 2019 16:26 19 Aug 16:26 | #20580 | #20580

Public Lab has offered "offline apps" for a long time, starting with Spectral Workbench's capture feature, and with our Software Roadmap ( we are increasingly developing stand-alone JavaScript apps that have (or should have) offline features, like:

Offline apps are apps which, once loaded in your browser, no longer require an internet connection to work; they're saved or cached in your browser the first time. This is really useful for limited connectivity situations.

I wanted to talk through this so we approach offline apps in a consistent way at Public Lab, but also have some broader UI principles and ideas that should be relevant to any offline app.


The recent PWA "standard" (Progressive Web Apps) is really exciting, and brings together some powerful features to web-based apps, basically allowing them to be "installed" on your phone's home screen just like a regular app, even though they're just fancy web pages. PWA features actually help address two different primary goals:

  • fast load time
  • offline use

And, there is a whole checklist of requirements for PWAs to ensure they meet common user expectations; Google's PWA documentation is really strong overall:


However, there are some common pitfalls for PWAs that I've seen over and over, which can affect both developers and users. These fall into a few categories:

  1. version transparency
  2. status and source of current version
  3. user ability to flush cache

Version transparency is about letting the user (or developer) know exactly what version of an app is actually being used, without having to interact with the code or console. What often happens is that a PWA version is cached, and later makes the app available immediately. But if bugfixes or new features are published, it's often very hard to know if you're using the latest version. This complicates bug tracking, as people may report old bugs, and it makes it unclear to the user if they are using the latest version, if their page reload has successfully loaded the latest version, etc.

I recommend:

  1. displaying a version number unobtrusively at the bottom of the page (an NPM version number AND/OR a publication date, or at least a Git hash)

  2. displaying a banner or a prompt to refresh the page once a new version has successfully been fetched

  3. you may consider displaying a version number faintly in the upper right corner, or by the page title, so that screenshots of the app can capture it

Status and source of current version: While displaying the version number, it also makes sense to show whether we're running a locally cached version or a freshly downloaded version. A notice like "App was loaded from 7 seconds ago." versus "App was cached in browser 12 days ago." is still minimal, and really helpful.

User ability to flush cache: this is primarily useful for developers, and especially new contributors to a project, who can make repeated mistakes in trying out new code. A button or link saying "Refresh cached app" or "Flush app cache" can make this straightforward, and is especially nice when paired with version numbering or date-of-download as noted above.

These features are clear and present in the Application tab of the Chrome Dev tools:

image description

However, in an open source project, the user community is often actively engaged in finding and documenting bugs, suggesting and testing new features. So I think the 3 suggestions above make for really useful and minimal information for users as well, without adding unnecessary complexity or confusion.

What do you think? Leave a comment!


Yes, I agree that there are some potential pitfalls that can cause inconvenience to the user as well as the developers. These are some important things to keep in mind when dealing with Progressive web apps, thanks @warren 😃


  • Version transparency: This is really important and is not currently implemented in community-toolbox, definitely a follow-up. Showing a simple hash of the latest commit (latest on the deployed version) can turn out to be so helpful in the future. This can be as simple as,


  • Status and source of current version: Whenever we're designing a PWA that supports offline access, the main goal should be to show the latest copy of data to the user as long as he/she is connected to the internet. When not, the cached version of the data should be displayed and that should be as recent as possible. Offline access logic for community-toolbox is designed keeping above thought in mind. It follows Network with Cache Fallback Policy combined with constant cache updation cycles, which makes sure that
    • User is served with the latest copy of data as long as he/she is connected to the internet. With every successful fetching of data, the cache is updated with the latest info that is received.
    • When the user goes offline, the cached data is displayed which contains the data from the last successful fetch that happened.

So this ensures that cache is getting updated with every successful fetch from the internet and user is guaranteed to get the latest possible copy of data.

But showing the status is a very useful thing to have anyways!

  • User ability to flush cache: This is a useful utility, but we need to make sure that we are able to serve the fresh copy of data beforehand, otherwise, the page would not be having any data as the cache will be flushed and fetching from the net won't be able to get any new data (happens when data source puts a limit on the number of requests you can make in a certain amount of period). Like, in case of Github API, they limit the unauthenticated requests and you cannot make more than 60 req/hr. So precautions should be taken when clearing out the cache.

Is this a question? Click here to post it to the Questions page.

True, maybe a failed flush would just show the last version loaded.

Network with Cache Fallback Policy -- can you link to documentation about this? For example, I'm not sure if follows this policy. Where is it established, and can you check if image-sequencer needs this to be switched on somehow? Thank you!!!

Is this a question? Click here to post it to the Questions page.

Yes, so here is some documentation regarding Network with Cache fallback policy.

Actually, by looking at the service worker file, it doesn't look like image sequencer is following this fact, it follows cache with network fallback policy. You can take a look here. This means that whenever the requested resource is available in the cache, IS shows that cached response and if not successful, falls back on the traditional network call.

Moreover, here's a illustration that shows network with cache fallback policy clearly,


However, community-toolbox implements constant cache updation on top of that, so that the cache is guaranteed to have the most recent copy of data.

Is this a question? Click here to post it to the Questions page.

Oh, awesome. Would you be at all willing to open a PR to change the image-sequencer implementation, or to port over the policy in community-toolbox? It's something we've had some trouble with, and I really appreciate your expertise here!

Is this a question? Click here to post it to the Questions page.

Sure, I would love to do that...I'll take a look at it 👍 😃

Reply to this comment...

Login to comment.