Other Posts

Ship PWA Guided by Lighthouse

coverimage
Photo by Robert Wiedemann

Nowadays, PWA is so hyped. All the cool kids are implementing PWA, or on the way to implement it. It’s like a magic box, they said, what contains ultimate happiness for users. Wow it sounds awesome, right? How is it possible that I could miss this opportunity to stay as a member of the cool kids club?

What is actually PWA?

According to Google, Progressive Web Apps are user experiences that have the reach of the web, and are [1]:

  • Reliable: Load instantly and never show the downasaur, even in uncertain network conditions.
  • Fast: Respond quickly to user interactions with silky smooth animations and no janky scrolling.
  • Engaging: Feel like a natural app on the device, with an immersive user experience.

Personally, I prefer another alternative version because it uses one word to represent PWA: F.I.R.E 🔥 Fast, Integrated, Reliable and Engaging. [2]:

Many people are confused by the fancy term of PWA, like this: Google’s continued use of the term “quality” in describing things leaves me with a ton of confusion… [3]

To be honest, PWA is not a new technology at all. It’s a new web app quality standard for web experiences [4].

How to get my app on F.I.R.E.?

Are you sold by the idea of PWA? I’ll buy it. Because I would do whatever I could to improve the user experience. So, I decided to optimize my blog site for reaching PWA standard.

Step 1: Run a performance audit

Lighthouse is a must-have tool to audit web app performance. Lighthouse is already integrated in the recent versions of Chrome and Chromium, as a part of DevTools, which makes it super convenient to use:

Inspect -> Audits -> Perform an audit...

Step 2: Read audit report carefully

After running an audit in Lighthouse, it will provide a detailed report. First, it shows the overall scores:

before-overview
Overview of the first Lighthouse audit result

I’m not surprised by this result, not at all. These numbers are making people feel good when they have greens. Besides that, I would suggest to ignore them.

When continuing reading the report, I find the interesting parts: failed audits. It’s a nicely organized To-Do list, especially the Learn more links which open documents to explain why the audit is important and how to pass the audit.

before-pwa
Failed audits for PWA section

Step 3: Get hands dirty

It’s time to handle all failed cases one by one. Most of them are rather easy to solve by following “Learn more” tutorials. Only “Does not register a Service Worker” and “Does not respond with a 200 when offline” are relatively tough. I’d like to share some tips, which come from my Aha moments.

A working service worker has 4 essential parts:

  • manifest.json: It’s a json file located in / web app root directory:
{
  "short_name": "Kevin",
  "name": "Kevin Cui",
  "icons": [
    {
      "src":"/images/kc.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "/",
  "background_color": "#000",
  "theme_color": "#000",
  "display": "standalone"
}
  • Link manifest.json in index.html:
<link rel="manifest" href="/manifest.json">
  • Service worker js: It must be created in web app root directory, alongside with manifest.json. Here is an example of the service worker called sw.js:
var CACHE_NAME = 'kevin-site';
var urlsToCache = [
    '/',
    '/#blog',
    '/css/font.min.css',
    '/css/animate.min.css',
    '/css/monokai.min.css',
    '/js/umbrella.min.js',
    '/js/highlight.min.js'
];

self.addEventListener('install', function(event) {
  // Perform install steps
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        if (response) {
          return response;
        }

        var fetchRequest = event.request.clone();

        return fetch(fetchRequest).then(
          function(response) {
            if(!response || response.status !== 200 || response.type !== 'basic') {
              return response;
            }

            var responseToCache = response.clone();

            caches.open(CACHE_NAME)
              .then(function(cache) {
                cache.put(event.request, responseToCache);
              });

            return response;
          }
        );
      })
    );
});
  • A piece of JavaScript code to register service worker in index.html:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js')
  .then(function(registration) {
    console.log("Service Worker Registered", registration);
  })
  .catch(function(err) {
    console.log("Service Worker Failed to Register", err);
  })
}

For more details of all these parts above, there is a good tutorial to follow: Add Your Web App to a User’s Home Screen and a good example of PWA app to check its source code: airhorn

My app is on 🔥!

Once the dirty jobs are well done, it’s time to run another performance audit. Although I know all score numbers are meaningless without contexts, it still feels damn awesome when I see all greens, right?

after-overview
Another overview of Lighthouse audit result

Surprisingly, Firefox now starts to support PWA as well.

What else?

I have to admit that it’s not hard to pass Lighthouse audit checks. However, I must keep in mind that it’s just one step of improving web app performance towards the goal of “better user experience”. Many steps ahead I still need to move on.

What’s your opinion about PWA? Would you like to ship your app guided by Lighthouse? And join the cool kids club?


[1] Google: Progressive Web Apps
[2] Ewa Gasperowicz: From Website to Progressive Web App
[3] Ben Halpern: What the heck is a “Progressive Web App”? Seriously.
[4] Thao Tran and Chris Wilson: The New Bar for Web Experiences