I’ve been experimenting a lot lately with allowing Ruby on Rails to work offline, by this I mean having a sensible fallback for when the network unexpectedly drops out (e.g. the user is underground on a train).
I’ve put together a few screencasts so you can see everything in action.
What is a service worker?
Service Worker Limitations
When researching this topic, I found Service Workers do have some drawbacks you should be aware of:
- The URL of your service worker must stay the same (e.g.
/service-worker.js), so it can be tricky to get it working with the Asset Pipeline & Webpacker.
- If you serve your service worker from a different port (i.e. via
bin/webpacker-dev-server) it won’t intercept HTTP requests as you’d expect.
- The amount of data you can cache is pretty varied between browsers & devices. I’d recommend keeping your usage under 25MB.
Service Workers have been around a few years, as a result there is quite a few libraries which make them a lot easier to work with. Here is a quick summary of the main ones to know about.
The serviceworker-rails Gem
The serviceworker-rails gem will work pretty nicely for most use cases, it works with the Asset Pipeline (Sprockets) & has a very nifty generator for automated setup.
One of the biggest drawbacks with webpack is it’s quite tricky to configure if you’re not working with it regularly. The webpacker-pwa library makes adding the extra configuration a lot easier.
/public directory from a file that doesn’t have a content hash.
There are 3 main approach for caching and serving content which I settled on using.
This is kind of the best default choice for any page which might change between page loads.
As the name hints, it’ll try to request the resource from the webserver (caching it if it’s successful), or falling back to its cached copy if the server is unreachable.
This approach will initially request the file, then cache the response. For subsequent requests it’ll serve the cached file.
This is the quirky option! It serves the cached content, but then in the background it’ll make a request to the server to update its cache.
It’s possible to preload assets into your cache. You can do this from within your
I didn’t make a video on this approach as I wasn’t able to validate anyone else doing it, but I did like it.
After I added a Service Worker to my Rails app, it was able to fallback to a read-only view when the network was down, This was pretty awesome! Especially as I didn’t have to change any of my standard “Rails rendering the HTML” & Turbolinks making things feel a bit snappier approach.
I think most apps could benefit from a Service Worker being added for the small performance win it can offer, plus I think having a read-only fallback for if your server is unreachable a pretty cool trick.
One thing I didn’t figure out, is how to detect if a response was returned from the cache on the current page, i.e. to show the user a notification saying “Hey, you’re offline”.