Highlights from Google’s Progressive Web Apps training in London

Last week, Google kindly invited Ada Rose Edwards and me to join them at “Building Progressive Web Apps”, a 3-day PWA bootcamp at Skills Matter in London. The event was free for attendees — the only “catch” was that they wanted lots of feedback, as it was the first of its kind (yes, a “beta”, but as their joke went, everything at Google is either beta or deprecated!).

With Sarah Clark and Sam Dutton leading the teaching and support from their colleagues, we covered a wide range of topics, including service workers, fetch, promises, flexbox, IndexedDB and Web Payments.

Why PWAs

First, though, we were encouraged to consider our users and their requirements. When, where and how might they access our content? What are their offline needs — what kinds of connectivity do they have and are they affected by data costs? How could we improve their experience, if we could combine the best of the web and the best of native apps?

Progressive web apps combine the capability of native apps with the reach of the web. Native apps have a very bad long tail problem; discoverability is better on the web.

Another advantage for web apps is reduced friction — there is no need to turn your users away, to say “Why are you here? Go to the app store!”

Image from Jules Jamison via http://wtfmobileweb.com/

Instead, provide a great experience at your own front door — the web.

“PWAs are all about removing friction”.

PWAs are not only about removing the friction of having to download an app. They are about removing the friction of having to wait for a site to load — the friction of unresponsive and poorly designed web pages. It’s time for a new era for the web. PWAs should be fast, reliable and work well across platforms.

App shells, caching and rendering

Motivated by the potential, we were guided through the building blocks of PWAs. In general, we were advised to consider the separation of our “app shell” — the initial scaffolding that does not change very often — and the actual content which may change all the time. The app shell is a prime candidate for precaching with a service worker. For an app shell example, see Jake Archibald’s Offline Wikipedia.

As for server-side vs client-side rendering, Google’s recommended patterns, in order, are:

  • Server-side render (SSR) the app shell and the content for the entry page. Then use JavaScript to fetch the content for other routes and “take over” client-side rendering (CSR).
  • If you can’t do that, server-side render only the app shell and use JavaScript to fetch the content once the shell is loaded.
  • If you can’t do that, server-side render the full page.
  • If you can’t do that, client-side render the full page.

We learned not to precache too much content on install. Just cache the minimum amount that your app needs to start functioning straight away. Other resources may be cached on fetch (but precaching every request for a site may not be feasible).

Another tip is to think of cache entries as URLs, not files. Some examples out there use a variable name such as ‘filesToCache’, but this is confusing. As an example, a problem that people ran into in the workshop was that they needed to add precache entries for both “/” and “/index.html”.

Tools

Some of the useful tools that came up frequently were:

  • Lighthouse, a progressive web app auditing tool. Run it against your PWA to see what score it achieves and advice for improvements.
  • sw-precache is a Node module you can incorporate into your build process, to generate a suitable service worker to precache your resources. Google have a free Code Lab for learning sw-precache here.
  • sw-toolbox is a collection of service worker tools that make it easy to implement various caching strategies — see below.

Caching strategies

These strategies are all easy to implement with sw-toolbox, including configuring timeouts:

  • “cache first”, then fallback to the network — if it is in the cache, it won’t touch the network.
    E.g. toolbox.router.get(‘/images’, toolbox.cacheFirst);
  • “network first”, then fallback to the cache — if you want to try for up-to-date content first. As an example, it was suggested that a publication such as the FT would probably opt for this strategy.
    E.g. toolbox.router.get(‘/api’, toolbox.networkFirst);
  • “fastest” — set the cache and network off in a race and serve whichever one comes back first. You would expect that this would always be the cache, but Sam mentioned that they saw examples where the network returned faster — perhaps because of network caching.
    E.g. toolbox.router.get(‘/profile’, toolbox.fastest);
  • “network only” — to return fresh data only.
  • “cache only” — when you want to guarantee that no network requests will be made.

Web Payments

Somewhat tangential to the core PWA APIs, but another example of reducing friction: Web Payments.

“Web Payments will make a huge difference to the web”.

66% of purchases on mobile are on the web. I did not realise, but the PaymentRequest API is already supported in Chrome for Android since v53. Its aim is to make transactions really easy, especially on mobile.

Push Notifications

Another highlight for me was the session on push notifications. This actually comes down to two APIs, the Notification API — for displaying notifications and responding to their click and close events — and the Push API, for subscribing to receive push data. Service workers can receive this data in the background and display an appropriate notification, from which (if you have provided something useful or interesting) the user may re-engage with your app.

Image Capture

Another new API that got a mention is Image Capture, which specifies methods for takePhoto() and grabFrame(). The draft W3C spec and Chromium thread contain further details. (I’m excited to try this out for Snapwat!)

Lots More

I still only really scratched the surface with this post. The 3 days also covered topics such as responsive design, tooling and analytics. We even had a special guest appearance by Paul Lewis with an impromptu, yet polished, run-through of front-end performance. All-in-all, a thorough and enjoyable journey through all the elements required to develop fast, responsive and engaging web experiences.

Thanks again to Google for inviting us to participate and help out. They even invited Ada up front to give a remote debugging demo and share how to debug other browsers like Samsung Internet. It just shows how open and collaborative everyone is in the web development community ❤.

Google may be considering rolling out similar training sessions in other locations, so if you are interested to attend, keep an eye out for news from Chrome Developers via all your favourite channels. For additional reaction from the event, check the hashtag #LearningPWA.