I’m making an offline first WordPress PWA, part 4

App Shell Model

This series consists of the following parts:

In the last part, I created a service worker using WorkBox. This is how it looks like at this point in time:

It does two things:

Caches all files from the directory wp-content/themes/wp-pwa/assets/

Caches the front page which makes the blog load even if the user is offline or has an unstable connection, “Lie-fi”.

I’m using the cacheFirst() strategy in both cases which means that the file will always be served from the cache. If the file doesn’t exist in the cache it will of course be downloaded from the server as usual and then stored in the cache.

This means less bandwidth usage for the user and a very fast loading blog due to the minimal amount of network requests.

The disadvantage of this strategy is that the files will always be served from the cache and not the server, no matter what. This means that if the CSS file is updated on the server, the user will still be served with the old one from the cache.

This can certainly be resolved by adding a version number as a query string: style.css?version=1.1 The browser will then perceive this as a new file and download it and store in the cache.

The problem is that the HTML file itself is currently stored in the cache. If the HTML isn’t updated, the href won’t be updated from style.css?version=1.0 to style.css?version=1.1

But the biggest problem is that the blog itself won’t be updated. The user won’t see any new blog posts if the HTML, which is stored in the cache, never gets updated.

A new strategy?

The cacheFirst() strategy doesn’t seem sustainable, at least when it comes to the HTML pages on the blog. The App Shell Model could be an alternative for me.

In short, by using the App Shell Model I could save an “empty” version of the blog in the cache, a shell without content. The shell would be populated with content on the client side using JavaScript.

A visualization of the App Shell Model. The image comes from Google

But no matter how much I like JavaScript, I’m reluctant when it comes to relying to much on client side rendering. Sure, Facebook or YouTube won’t work without JavaScript, but this is a simple blog and not that kind of web app. The blog should more or less be working without both CSS and JavaScript!

On the other hand, a PWA is a bit more forgiving since you don’t have to wait for the scripts to be loaded. That means faster rendering on the client side.

But it’s still important to remember that all web browsers doesn’t have support for service workers yet. Just because you’ve made a PWA doesn’t mean everybody will experience the benefits of a PWA.

App Shell Model and Vue.js

But I shouldn’t reject anything without testing it first. Building entire sites using JS frameworks like React and Vue is becoming more and more common, so I decided to give the App Shell Model a chance and made the following:

Instead of rendering the blog posts on the server side, I’m now using the WordPress loop for rendering placeholders.

Server side rendered Facebook style placeholders.

On line 4 in the code example above you might have noticed the <blog-post /> element. This is a Vue Component which is rendered when the blog post has been loaded with fetch() from WordPress built in JSON API.

app.js looks like this now:

And here’s blogPost.vue :

And here’s the animated .GIF that shows how it looks like when the blog is being loaded with the network speed throttled to Slow 3G in Chrome Developer tools:

Note that the service worker isn’t active at this point. The .GIF shows the experience of a first visit. The loading time is approximately 13 seconds, but this number is greatly improved on the next visit.

The network speed is still throttled to Slow 3G, but the blog loads in a little bit more than two seconds! If the network speed is increased to Fast 3G, the loading time is improved to 1,7 seconds!

This is possible because the HTML, CSS, JavaScript and the header image is stored in the cache. The only thing that is loaded over the network is a little bit of JSON data from the WordPress API.

Offline?

The content will always be up to date since it’s no longer stored in the cache. The disadvantage of this approach is that the blog won’t be working offline. It will certainly load, but the shell with placeholders will never be replaced with actual content.

The good thing is that this can be solved by saving the data from the WordPress API in the cache. But that’s a mission for the next part…