Progressive Web Application Tutorial – Save Upto 90% Data

Pros (+)

  • Lightweight.
  • Lightning quick.
  • Work offline.

Cons (-)

  • Tricky to setup.
  • Not well-known.

Progressive Web Apps or PWAs as they’re more commonly known are a concept that blends the old-fashioned web page with the more modern computer application or app.

According to Google progressive web apps are:

  • Reliable – instant loading and even without a network connection they show some content.
  • Fast – super responsive with greased-lightning scrolling. No judder or janky movement.
  • Engaging – high quality desktop experience that feels like a natural mobile app.

That’s just the start, here’s some other useful things to consider.

  • PWAs are installable and can be launched from the home screen, same as a regular application.
  • Can save up to 90% in data transfer. This improves reliability, saving everyone money and time.
  • AliExpress improved conversions on all browsers by 104% and on iOS by 82%.
  • Web push notifications are a superb way to increase user engagement;  they can be used within your PWA to convey your message.

Mozilla are also a good source of PWA information.

Mozilla PWA Logo
Mozilla PWA Logo

1. What are PWAs Good for?

Modern apps have gotten bloated. They started out like an Olympic athlete, but are now more like a couch potato dipped in triple chocolate.

This recent post from 2017 shows the mind-blowing statistic that top iPhone apps have grown by 1000% in just four years. Wow!

Bearing in mind that iOS is usually smaller like-for-like when compared to Android. You can be certain that the figures for Android are going to be far worse.

This means that downloading lots of apps eats into your storage and data allowances, especially in this mobile-first world we now live in.

PWAs are simply web pages that are controlled by a service worker. The service worker caches them and we can use them at a later date, even when offline.

In essence then we have a webpage that can work offline – this is the key feature of PWAs.

Off course in defence of regular apps, a PWA is never going to offer the exact same features, but it’s a neat alternative when it comes to speed and efficiency. You don’t have to download a PWA like you do an app, but of course it won’t work until you’ve visited the website at least once.

Your second trip to the website will be extremely rapid, as the content is already cached and the service worker can grab your content from there.

Let’s be clear here – even a regular app doesn’t work till you download it so PWA’s aren’t a failure in this regard.

The first visit will simply be the normal website experience users are comfortable with.

Depending on how the PWA is set up will determine how many webpages are availlable. The idea isn’t to cache a thousand pages, but to give the user a better experience than having the Google downasaur.

Typically you might cache the homepage and then after that the pages that the user has already visited. This is good starting point.

Web site pages and posts can be restricted in the PWA scope, although this isn’t mandatory.

2. PWAs for WordPress

If you search the WordPress plugin directory, you’ll find several PWA plugins that will do the job for you. However, it’s simple enough to create one yourself.

Plus you can’t really have much faith in SuperPWA plugin when this happens.

  • Installed SuperPWA’s website on my desktop.
  • Turned off my WiFi to test it out.
  • Clicked the icon to start and…
SuperPWA Site Offline
SuperPWA Site Offline

To clarify, I didn’t install their plugin, I installed their own website which is a PWA that no doubt uses their own plugin. Regardless, it’s not a good look for them.

So now we know it’s best to go our own way, let’s get it on!

Hopefully I will explain it nice and clearly so you can do yourself proud.

There are differences between PWAs for AMP and regular WordPress, but don’t worry, I’ve got you covered with both versions.

Here’s what my Gossip Lolly website looks like when opened from Windows’ home screen. It even works on a basic level without a network connection, as the progressive-web-app Gods intended.

Gossip Lolly PWA
Gossip Lolly PWA

When I first started experimenting with PWAs, you could make them either:

  • Standalone.
  • Minimal.
  • Full screen.
  • Browser.

The above image shows my site using Standalone, but out of all my sites now it’s the only one that still displays like this. Not quite sure the reasons why, but my others display in browser mode, even though the manifest is set to standalone.

All I can put it down to is one of those computer moments, where everything seems identical, but for whatever reason you get different results.

3. The Essential Steps to Building a PWA

Before we jump into the details, let’s quickly go over the steps we must take to get a working PWA. Please bear in mind that I’m not a full-stack developer so if there’s any improvements to add, I am grateful for any constructive criticism.

One thing that really bugs me is when people are defensive about learning and self-improvement. If someone points out you’re wrong, use this to improve rather than sulk or hide the fact. It’s for our own good, after all.

Back to the matter in hand, here’s the order we will proceed in.

  1. Make a suitable icon 512 x 512 px in size.
  2. Create a web app manifest, using a manifest generator is preferable for first-time users.
  3. Register a service worker from header.php, in your child theme ideally so it doesn’t get overwritten.
  4. Create and upload either serviceworker.js or sw.js file in the root folder of your hosting account.
  5. Upload the icons to your root folder in your website hosting account.
  6. Create and upload your site.manifest or manifest.json file. (.json is more popular.)

You can make a child theme in seconds using Child Theme Configurator, then delete the plugin afterwards.

The amount of icons and sizes you need will depend on your viewership’s devices. Initially I combined the icons from the Firebase manifest generator to the icons created in Real Favicon Generator, as I was concerned that I’d miss an icon size out.

In the end I simplified my process and now use Real Favicon Generator, as you can use their favicon checker to see if everything is okay.

Just don’t forget to align your manifest with the actual icons in your root folder, otherwise it won’t load them.

Also being pedantic, I originally went with .manifest, but you’re probably better off going with .json because it’s more popular and most of the caching plugins won’t cache .manifest unless you tweak your .htaccess file.

It’s important to see a PWA as an important tool in your overall WordPress kit, which should include essentials like Cloudflare for it’s CDN and security features.

4. Make a Suitable Favicon/Icon Set

Firstly you will need a favicon to upload to either Real Favicon Generator or Firebase

You can make a 512 x 512 px icon in Photoshop or Canva – free version. This needs to be a .jpg or .png image file. You can then upload it to Firebase instead of RFG. Check them both out and see which one you prefer.

For Real Favicon Generator, I’ve included every single step below.

The only considerations are that it must be suitable to be installed on a smartphone or desktop home screen. When I say suitable, think of the length of your name, short name and color scheme.

Here’s a selection of PWA’s that are on my Windows Desktop, to give you an idea of what you’ll find once you’ve made your own version.

PWA Icons Windows Desktop
PWA Icons Windows Desktop

4.1 Real Favicon Generator

This section might seem over the top for some, but I want to ensure that all the information is at hand for people who are unsure about such things.

Uploading the icon set to your root directory and configuring the HTML in your theme files – header.php – will ensure you’re PWA-ready when the time comes to unleash the beast.

A full-house PWA review is on the cards, but there’s so much to cover, I’ll leave it for now.

Instead head over to Real Favicon Generator and select your favicon image. (Existing users can check a favicon to see if your site complies.)

Real Favicon Generator Select or Check
Real Favicon Generator Select or Check

You can’t submit an image under 70 x 70 pixels, but it recommends 260 x 260 pixels or more for optimum results. Due to WordPress insisting on 512 x 512, for the customizer, I tend to make most of my square logo images this size and that’s what I went with…

Select 512 x 512 Pixel Logo Image


Select 512 x 512 Pixel Logo Image

You can use a round logo, but they tend to turn out too small and are almost invisible in the browser bookmark bar. Square is the best option.

4.2 Favicon for iOS – Web Clip

The settings are super easy, just go with the flow and you’ll be fine.

Favicon iOS SettingsFavicon iOS Settings

You can see how my logo looks in the mockup above. Simple yet effective.

Favicon iOS AssetsFavicon iOS Assets

Next on the to-do list is the Assets tab. If you’re unsure just follow my choices, which will leave you with the smallest amount of icons. Let’s be honest, who cares about legacy tech? If someone is that tight chances are they’re not on your website anyway.

Most regular surfers will have a recent smartphone on a contract.

Favicon iOS Dedicated PictureFavicon iOS Dedicated Picture

The Detailed Picture tab is to alter your image if it looks naff. In theory you can have as many designs as you wish, but best to stick to one and only alter it if necessary.

4.3 Favicon for Android Chrome

Favicon Android Main SettingsFavicon Android Main Settings

More of the same, just repeating the process with an extra tab in this case. One thing to notice on Android is the window-in-window tabs for the Home – Switcher – Splash. 

In order to make it easier for you, I clicked on each on in the screenshots. Thoughtful, eh? 🙂

Favicon Android OptionsFavicon Android Options

Options is a new tab, but in reality it’s all similar stuff. Only this time you can fill in the Start URL and this goes in your site manifest. If in doubt always put your homepage.

Favicon Android AssetsFavicon Android Assets

Another assets tab – just leave the radio button as you find it. That’s all I did.

Favicon Android Dedicated PictureFavicon Android Dedicated Picture

If you’re happy with the image there’s nothing to do here.  Swiftly moving on to Windows…

4.4 Windows Metro Settings

Favicon Windows Metro SettingsFavicon Windows Metro Settings

You know the drill by now: Settings, Assets, Dedicated Picture.

Favicon Windows Metro AssetsFavicon Windows Metro Assets

Again, if in doubt leave the tick boxes as they are.

Favicon Windows Metro Dedicated PictureFavicon Windows Metro Dedicated Picture

That’s it – now it’s macOS

4.5 macOS Safari

Favicon Mac OS SettingsFavicon Mac OS Settings

The slider bar can catch you out here, but if the picture is okay then don’t even touch it.

Favicon MacOS Detailed PictureFavicon MacOS Detailed Picture

Short and sweet, only two tabs to MacOs.

Now we’re on the last lap… the final few selections for compression and algorithm bits and bobs. You’ll need to check your file sizes after compression to see if it has actually worked. There’s been a couple of times when I didn’t see a difference.

It could be that some sections work and others don’t. Anyway, I’ve emailed the developer to see if he/she can shed some light on the situation.

4.6 Favicon Generator Options

Favicon Generator Options PathFavicon Generator Options Path

If you’re uploading your icon set to your root directory there’s no further action necessary.

Favicon Generator Options Version RefreshFavicon Generator Options Version Refresh

Version/Refresh is a tab that I left standard. Can’t really see why you’d need to alter it either. Perhaps on a second or third visit to Real Favicon Generator.

Favicon Generator Options CompressionFavicon Generator Options Compression

As you can see, I left this as standard on the first radio button.

Favicon Generator Options Scaling AlgorithmFavicon Generator Options Scaling Algorithm

Nothing to do here, unless you like the blocky shapes. Unless you’ve got the equivelant of laser eyes, it’s unlikely that you’ll even see anything happening.

Favicon Generator Options App NameFavicon Generator Options App Name

Finally we’re onto the penultimate tab: App name. You’ll need to fill this in to suit your site.

Favicon Geneator Options Additional FilesFavicon Geneator Options Additional Files

Check both of the tick boxes. Then you’ll have a copy of your HTML that goes in header.php.

Once you’re happy with all your choices you can click the big blue button…

Generate Your Favicons and HTML CodeGenerate Your Favicons and HTML Code

Wait a few seconds and you’ll get a chance to copy the code, as displayed below.

Install Your FaviconInstall Your Favicon

If you’ve definitely selected the additional files and a copy of the HTML, you needn’t worry about copying the code above.

Once your Zip file package has downloaded, extract it to your preferred location. You’ll find the HTML markup in an empty web page, but don’t worry, if you right click and view the source code it will be waiting for you.

Favicon Source Code for Header FileFavicon Source Code for Header File

The rest of your favicon files should look something like this…

Real Favicon Generator Zip File ContentsReal Favicon Generator Zip File Contents

Well that’s about it for favicons. Actually there’s one last step, go back to Real Favicon Generator and test your site. You’ll get a report detailing exactly what’s missing or not.

5. Creating a Web App Manifest

You’ve no doubt already been considering the manifest that we mentioned earlier. This is a small JSON file that tells the browser where your icons live, plus information about various things like color and size.

“name”: “Page Speed Tweaks”,
“short_name”: “Page Speed Tweaks”,
“icons”: [
“src”: “/android-chrome-192×192.png”,
“sizes”: “192×192”,
“type”: “image/png”
“src”: “/android-chrome-512×512.png”,
“sizes”: “512×512”,
“type”: “image/png”
“theme_color”: “#ffffff”,
“background_color”: “#ffffff”,
“start_url”: “”,
“display”: “standalone”

You can use the manifest from either Real Favicon Generator or Firebase, but make sure it looks something like this, but with your colours and details in place of mine.

There is a big options list for the manifest keys that you can include, but to be honest, for our sake stick to the essentials. Once you’ve mastered the PWA setup then start adding more features.

The above manifest is enough to keep Google happy and that’s what matters.

Check you’re linking to it correctly with this manifest validator.

If your .manifest file won’t open to edit it, you can either upload it and edit it in your hosting account root folder. Alternatively you can temporarily rename it from site.manifest to site.txt then open it in notepad.

The benefit of using manifest.json is that you can simply open it as it is to edit it.

For those that prefer .manifest, I have a code snippet to place at the bottom of your .htaccess file.

Make sure you either backup your full website or at least download a copy of your .htaccess file to prevent a big headache. It’s also better to edit it from your hosting account than the WordPress file editor, as it’s easier to reverse changes.

<IfModule mod_mime.c>
AddType application/manifest+json .webmanifest
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType application/manifest+json A31536000

If you want to alter your manifest regularly, keep the cache expiry shorter.

The A31536000 is a year in seconds. For a safer approach, a month would be A2592000, but the manifest is only icons and your start URL so should be fine set for a year once you’re happy it’s working.

Pro tip: minify your manifest using JSON minify, as it won’t usually be picked up by your standard minification or caching plugins. This will typically reduce the size from 9 kb to 3 kb. 

If you run into problems then use this unminify website to reverse your changes.

Some people will say it’s pointless doing such things, but this site is all about gaining those extra milliseconds.

Even the smallest files often get stuck on download – look at any waterfall chart. One file that’s stuck in the pipeline could be the difference between a sale and losing one.

You don’t want to end up like the guys over at AMP, do you? Looks like they could do with some of that acceleration for their mobile pages.

AMP DEV Website GT Metrix Audit
AMP DEV Website GT Metrix Audit

To be fair, the WordPress side seem to be trying a bit harder…

WordPress AMP Website GT Metrix Audit
WordPress AMP Website GT Metrix Audit

Yes, I know that audits and real world speed are two entirely different things, but a nigh-on 10 mb web page is inconsiderate to say the least. Imagine downloading that from a third-world country? Would take fifteen minutes and zap all of your data allowance. Not funny!

Perhaps they just thought lazy loading was eating lots of cakes in the office. 🙂

Back to the task in hand…

6. Registering a Service Worker

A service worker is a type of web worker, which is a javascript file that runs alongside or seperately to your browser. It can do lots of trick stuff like show the user messages, even when the browser isn’t running. However, we will only be looking at caching so you can at least make an installable and fully functional PWA.

Crucially, though, the service worker doesn’t directly affect the performance of the page. It does inderectly improve it, though, as we first mentioned.

Firstly we’ll cover service workers that are suitable for regular WordPress. Then we’ll go over the small-but-important differences for an AMP version.

All you need to do now is insert the following script, inbetween a pair of script tags, in WordPress header.php. Preferably this will be in your child theme so it doesn’t get overwritten when you update your theme.

Ensure your service worker file matches the /sw.js below. You can call it anything you want, but sw.js keeps it relevant and simple.

“serviceWorker” in navigator && window.addEventListener(“load”, function() {
    navigator.serviceWorker.register(“/sw.js”).then(function(e) {
        console.log(“ServiceWorker registration successful with scope: “, e.scope)
    }, function(e) {
        console.log(“ServiceWorker registration failed: “, e)

You can see it in action here, but don’t get mixed up with JSON minify and JavaScript Minify, as they aren’t the same.

Registering Service Worker WordPress Header.php
Registering Service Worker WordPress Header.php

If you visit your website in Chrome then right click and look at the console tab, you should see a message. Hopefully it says: ServiceWorker registration succesful with scope:

Service Worker Registration Successful Chrome DevTools Console Tab
Service Worker Registration Successful Chrome DevTools Console Tab

Now that we’ve successfully registered a service worker, let’s get on with creating one.

7. Creating a Service Worker

The service worker can be your own design, but a popular way to speed things up is let someone else create it for us and we can then link to their version.

For this we’re going to use Workbox.

Workbox consists of a selection of JavaScript libaries and node modules to help app developers cache their assets and simplify the build process for progressive web apps.

We’ll also be adding two messages to let us know if it’s good or bad.

  • Yay! Workbox is loaded 🎉
  • Boo! Workbox didn’t load 😬

The cache name is sw-cache, but you can change that to anything you like. Previous service workers that I used had different caches for images, javascript, etc, but after having issues I went the simple route.

It makes more sense, because if you want to cache something, as long as it can be displayed when it’s needed that’s what matters.


if (workbox) {
    console.log(`Yay! Workbox is loaded 🎉`);
} else {
    console.log(`Boo! Workbox didn’t load 😬`);

    new RegExp(‘/*’),
    new workbox.strategies.NetworkFirst({
        // Use a custom cache name.
        cacheName: ‘sw-cache’,

Again if you want to save a fraction – 0.1 kb in this case – you can minify the JavaScript or unminify it if you need to reverse your changes.

Also if you need to edit sw.js you can rename it to sw.txt for desktop editing. You can also edit it in the uploads folder of your hosting account.

Here’s the same code, but minified.

importScripts(“”),workbox?console.log(“Yay! Workbox is loaded 🎉”):console.log(“Boo! Workbox didn’t load 😬”),workbox.routing.registerRoute(new RegExp(“/*”),new workbox.strategies.NetworkFirst({cacheName:”sw-cache”}));

Once you’ve registered and uploaded the service worker, you can check it’s actually loading Workbox by going to Chrome DevTools again in the console tab.

Workbox Loaded Message Chrome DevTools Console Tab
Workbox Loaded Message Chrome DevTools Console Tab

8. Uploading Icons to Web Hosting Account

This is the easy bit, just upload your icon set that we created earlier to the root folder for your website.

You can also see that I’ve highlighted the manifest and service worker files.

Hosting Account Root Folder Public HTML
Hosting Account Root Folder Public HTML

Don’t forget that we also need to link to our icons that aren’t included in the manifest. This is because different browsers have different methods of locating things.

Link Manifest Icons WordPress Header.php
Link Manifest Icons WordPress Header.php

To be precise, the icons that are outside of the manifest aren’t strictly necessary, but it’s good practice to serve them as well. Then you’re covering the most popular browsers and also your PWA’s needs.

9. Uploading Website Manifest

This is a simple job, too. Just upload your manifest to the same folder as above. It’s usually the /public_html folder, but please be aware that yours might be named differently.

While uploading my new manifest.json file I noticed that even when minified, it’s a lot clearer when viewed from my web hosting accout. This is another small reason to go with .json over .manifest.

Manifest JSON Minified
Manifest JSON Minified

Here’s the site.webmanifest viewed from the same folder.


They’re both exactly the same size in kilobytes. Not exactly earth-shattering news, but it might help you decide if you were on the fence.

More importantly, though.

Now it’s time to link to your manifest from header.php in WordPress.

Linking Manifest WordPress Header.php
Linking Manifest WordPress Header.php

Pro tip: to remove an unnecessary network connection add crossorigin=”use-credentials”

<link rel=”manifest” href=”/manifest.json” crossorigin=”use-credentials”>

That’s about it, we’ve covered all the bases.

  1. Icons – create, upload and link.
  2. Manifest – create, upload and link.
  3. Service worker – register, create and upload.

Now you can take your shiny new progressive web app for a test drive.

10. Test Your Favicons with Favicon Checker

To ensure that all your lovely new favicons are accesible to browsers and your PWA, nip over to Real Favicon Generator and use the Favicon Checker we mentioned earlier.

Favicon Checker Page Speed Tweaks
Favicon Checker Page Speed Tweaks

Favicon Checker tests for the following:

  1. IOS Safari 
  2. There is an Apple Touch icon
  3. The 180×180 Apple Touch icon is present
  4. There is an Apple Touch icon in the root directory
  5. Android Chrome
  6. The Web App Manifest is declared
  7. There is an icon for Android Chrome
  8. The 192×192 icon for home screen is present
  9. Windows 8 and 10
  10. The Browser Configuration file is present
  11. There is a tile icon for Windows
  12. Max OS X El Capitan
  13. The mask icon color is declared
  14. The mask icon for Safari pinned tabs is present
  15. Classic, Desktop Browswers
  16. favicon.ico is available in the root of your web site
  17. There is an icon for classic browsers
  18. favicon.ico is present
  19. favicon.ico contains the highest resolution icon (48×48)
  20. favicon.ico contains all icons of recommended sizes

Once you’re happy with the results, now it’s time to check the PWA itself.

11. Testing Your Progressive Web App

Before your PWA is ready for the big time, it’s essential that you put it through its paces. Don’t count your Google Easter Eggs just yet, though, because progressive web apps can be tricky to get going. Even when they work, they can be temperamental. You’ll run them and they say something is wrong, then you hit the audit button a second time and everything is fine.

It’s something that you’re going to have to get used to if you are rocking the progressive route on a regular basis.

Anyway, back to the job at hand.

There are lots of different ways to check your progressive web application, but the most popular is to use Google’s very own Chrome browser. Specifically you can use Chrome DevTools.

Make sure you use an incognito browser window for optimum performance during testing.

Don’t worry about messing anything up in here. There’s not a lot that can go wrong so have a play around and get to know DevTools and how it can help you out. In this section you’re only affecting what the browser has downloaded.                                      

Chrome DevTools Application Tab Manifest
Chrome DevTools Application Tab Manifest

To reiterate the above:

  1. Select Application tab.
  2. Select Manifest tab.
  3. Manifest name is linked in blue –
  4. Check all manifest information is correct.
  5. Icons show if you scroll down the page.

There are different tabs/labels on the left-hand side referencing your cache names.

We’re caching everything together for simplicity, but you can easily alter the service worker code to seperate your image, css, js and so on.

The primary reason to use seperate caching is you can delete each cache at a different date.

Here’s a great Mozilla explainer on caching and another useful tool for checking HTTP headers on your assets is – REDbot. so you can see in REDbots own words:

REDbot checks HTTP resources to see how they’ll behave, pointing out common problems and suggesting improvements. Although it is not a HTTP conformance tester, it can find a number of HTTP-related issues.

Although caching concepts are interesting, the above is for basic caching, so let’s get back to testing our PWA and see if everything is all rosey.

I’ll just briefly say that there are several PWA caching concepts, but they can get confusing when you’re first starting out. One method is called ‘stale while revalidate.’ Essentially it means use stale content while checking in the background for fresh so as not to hold up the process in any way.

Chrome Stale While Revalidate
Chrome Stale While Revalidate

Next step is to either flick through the tabs in the Application section or do a quick audit. Probably best to have a quick peek at what’s what.

Chrome DevTools Application Tab Service Workers
Chrome DevTools Application Tab Service Workers

For the sake of clarity here’s what it says in the image:

  1. Select Application tab.
  2. Select Service Workers tab.
  3. Tick update on reload – for fresh service worker.
  4. Source should be name of service worker: sw.js.
  5. Update or unregister service worker if necessary.
  6. Ignore service workers from other origins. 

The service workers from other origins will typically be from any websites you’ve visited that use PWAs. Most popular websites now serve their main site from a progressive web app. 

Twitter is a good example…

Twitter Install Progressive Web App Chrome Browser
Twitter Install Progressive Web App Chrome Browser

You can quickly spot a PWA when you see the plus icon in the right-hand side of the Chrome Search Bar. Sometimes it takes a few visits before Chrome offers you the option to install a website.

Chrome DevTools Application Tab Clear Storage
Chrome DevTools Application Tab Clear Storage

The final tab in the Application section is Clear Storage.

  1. Select Application tab.
  2. Select Clear Storage tab.
  3. View Cache Storage from drop down arrow.
  4. Clear site data if necessary for a clean audit process.
  5. Unregister all service workers from here – not just your own!

Of course you might not see anything in the last few sections until you run an audit, which we’re going to do right now…

Chrome DevTools Audits Run Button
Chrome DevTools Audits Run Button
  1. Go to your homepage in Google Chrome browser.
  2. Right click to access DevTools.
  3. Select Audits tab.
  4. Ensure Progressive Web App is selected. (The other audits aren’t essential.)
  5. Tick clear storage checkbox – to ensure a clean audit. Also try running tests without clearing storage, as this usually prevents seeing the “does not report with 200 when offline” error.
  6. Select Mobile or Desktop audit.
  7. Run Audit and check your results.

In general you’ve got two main choices for running audits. 

  • Mobile audit.
  • Desktop audit.

The primary difference is that with Mobile you’ll get more throttling, either real or synthetic. Plus it’s usually harder to achieve a high score with the mobile audit for the aforementioned reasons.

Pro tip: Mobile audit is the one you should pay most attention to, due to the fact we live in a mobile centric world. The vast majority of your website traffic is likely mobile. Therefeore, mobile users should be where you’re paying the most attention.

12. PWA Specific Audit Results

Don’t despair if you don’t get a perfect audit first time round. It takes perseverance to become fluent with concepts like progressive web apps.

Even though I know how to configure them for a small website, I’m not proclaiming to be a PWA ninja by any stretch of the imagination.

The thing is, though, you don’t need to be John Logie Baird to watch television, in the same way you don’t need to be a Google Engineer to use a PWA.

You simply need to know enough to get you by.

That’s where I’d like to think you are now: far from a master, but clued-up enough to get a working PWA on your WordPress installation. 

Here’s what I get for my own website…

Lighthouse Audit PWA Test
Lighthouse Audit PWA Test

Although we’re only interested in the PWA section of the audit, if you get full marks on the other four sections, you’ll be surprised by a hidden Google Easter Egg and a confetti cannon. Not exactly a million-dollar prize fund, but hey, it’s better than nothing, right?

It usually shows you it in dark mode, to highlight the diference, but light mode is clearer.

What really spurred me on was the fact that when I first uploaded a video on this from my AMP site, it was only the second one on YouTube that I could find. First would have been better, but you can’t win them all.

Here’s a better close up…

Lighthouse Audit Google Easter Egg
Lighthouse Audit Google Easter Egg

The Progressive Web Application test can be further broken down into the following sections.

  • Progressive Web App Validation.
  • Progressive Web App Installable.
  • Progressive Web App Optimized.

Let’s cover installable first of all. You get the PWA icon, which covers the Fast and Reliable section.

Progressive Web App Validation

Progressive Web App Validation

  1. Page Load is fast enough on mobile networks.
  2. Current page responds with a 200 when offline.
  3. Start_url responds with a 200 when offline.

Please note that the icon will change if one or more of the criteria isn’t met from the full PWA list, including the sections below.

It won’t reveal the PWA text and instead has a plus icon in the middle of the shield.

Progressive Web App Installable is next on our list…

Progressive Web App Installable
Progressive Web App Installable
  1. Uses HTTPS.
  2. Registers a service worker that controls page and start_url.
  3. Web app manifest meets the installability requirements.

Finally we’ve got the longest part of the Chrome DevTools PWA module to consider.

Progressive Web App Optimized
Progressive Web App Optimized

This more lengthy section includes the following items:

  1. Redirects HTTP to HTTPS.
  2. Configured for a custom splash screen.
  3. Sets a theme color for the address bar.
  4. Content is sized correctly for the viewport.
  5. Has a <meta name=”viewport”> tag with width or initial-scale.
  6. Contains some content when JavaScript is not available.
  7. Provides a valid apple-touch-icon.

If you’ve followed the tutorial and completed every step in the process, then I can’t see why you won’t have a fully functioning Progressive Web Application that runs a service worker to cache your pages.

Should you have any problems or questions, please don’t hesitate to ask as it is my pleasure to help you get this super-useful item working properly.

13. AMP WordPress Plugin

The process for AMP WordPress setups is exactly the same, apart from the following two items.

  • Sevice worker code in sw.js.
  • Registering the service worker is done using an AMP-only script tag.

Looking at the service worker code, all you need to do is add a file called sw.js into the root folder of your website, which is usually /public.html. It’s so small there’s no need to minify it.


All it does is call the service worker files from the AMP CDN, which saves us having to make one ourselves. While it simplifies the process, it does take away some control for those who wish to experiment more. From our point of view, though, it’s definitely the best thing for simplicity.

From header.php the service worker is registered using an AMP-specific tag like this:

Register WordPress AMP Service Worker
Register WordPress AMP Service Worker

The code is as follows…

<amp-install-serviceworker src=”/sw.js”

Essentially all the code is doing is registering the service worker to be installed in a hidden iframe.

When you place the service worker in the root of your /public_html folder the service worker has access to everything, but placing the service worker lower down the file structure will restrict it.

Then once your PWA is set up, as long as you visit a web page it will be stored in cache for offline use.

On the other hand, you can’t expect to open a page that hasn’t been visited. If you could they’d have called it a miracle worker instead.

14. Troubleshooting

Once you’ve mastered the steps involved in creating a PWA, it’s all downhill from there. However, there will still be times when you’re left scratching your head.

You can generally split your problems into two camps.

  • Incorrect code or syntax errors.
  • Caching issues.

From my experience, the most annoying error message is start url did not respond with a 200 when offline.

Start URL Does Not Respond 200 When Offline
Start URL Does Not Respond 200 When Offline

There are plenty of websites that parrot this message, like, but they don’t provide a solution. Neither does Google. Handy, eh?

Of course, they will no doubt argue that every website is different, blah, blah.

Truth of the matter is that if you’ve got everything correct, it’s usually resolved by clearing your caches on your website and browser. After you’ve cleared your caches, you may need to give the network a few minutes to clear its throat.

Sometimes the changes appear instantly, othertimes they take a while. Presumably it’s traffic dependant. On a quiet day it will happen sooner than on a busy one.

To sum up there are a few things that have worked for me.

  • Use an incognito browser window for better performance through less interference.
  • Clear the caches – browser, website, CDN, etc.
  • Give the network time to show the new changes.
  • Reload the page afterwards, as sometimes security certificates aren’t logged first time round.
  • Also after clearing caches, uncheck the boxes so the next test is audited with a full cache. This ensures a more realistic situation and as explained the service worker needs cached assets to work.
  • It’s useful to have multiple websites then, if one PWA is working, you can transfer settings to the new one. This also enables you to differentiate between your own mistakes and a slow network much easier.
  • Above all be patient. Go through each step and pay attention to the errors and warnings, because often it’s the small things that can make the biggest difference.
First-Time Loading Incognito Window Security Tab
First-Time Loading Incognito Window Security Tab

Reloading your page won’t necessarily make your PWA suddenly start working, but it’s good to make sure that as many small things are pointing in the right direction.

It’s also more realistic to reload it, simply because a PWA doesn’t fully function until you’ve revisited the page, because it needs cached content to show the user.

We are all familiar with app installation. You couldn’t use an app until you’ve done so, stating the obvious. However, when we first visit a web page controlled by a service worker – our PWA – this first visit is akin to installing an app, albeit a slimmed-down version.

So think of your first visit as the PWA installation phase.

Second-Time Loading Incognito Window Security Tab
Second-Time Loading Incognito Window Security Tab

15. Aiming for Audit Gold

Now we’ve got the tricky part, the PWA badge in the bag, it’s understandable that you’ll want to progress the audit until there’s no more to be done.

There’s nothing wrong with wanting top marks in anything, but as long as you’re not chasing benchmarks that in reality make your site worse. If you’re continuously improving your site and, most importantly, user exprience, then you’re good. Nobody can tell you otherwise.

Eventually I hope to have a tutorial on every important plugin and process for you to follow. For now, though, you’ll have to make do with this snippet, which should give you an idea of how I resolve things.

Links Cross Origins Best Practices Audit
Links Cross Origins Best Practices Audit

Lighthouse has pulled me up for missing out the rel attribute in my footer links. So I opened my theme editor in WordPress and got to work.

Always do your due dilligence and back up any files, before playing around with them.

There are various stategies you can use for this, but I usually go with no-reffer for my Referrer Policy. So I simply added the following code to my inline SVGs to all my footer follow icons.


Rel=Noreferrer Attribute Footer.php Child Theme
Rel=Noreferrer Attribute Footer.php Child Theme

It’s surprising how quickly you can improve the score by tweaking one or two small things. Especially with the Google page-speed tools, because they’re usually more relevant than GT Metrix and Pingdom, which use outdated methods first started by Yahoo – remember them?

Once I’d finished tweaking the footer links, I checked Gossip Lolly for Best Practices again.

After Adding Correct Rel Attributes Footer Links
After Adding Correct Rel Attributes Footer Links

I know people have their favorite tools, usually the ones they get the highest score on.

As for me, well I’m not biased at all because they have pros and cons rather than one is the outright best.

Regarding PWAs, you might run into problems like all of a sudden getting marked down for not using a CDN by WebPage Test.

WebPage Test Effective Use CDN
WebPage Test Effective Use CDN

WebPage Test will mark you down if less than 80% of your static assets are served from a CDN, but this isnt’ a problem in this case.

  • Running a hyper-light website makes it more sensitive to audit results.
  • Simply because you have less resources so each one is proportionately larger.
  • For example, adding more images would improve our score above 80% even though the Workbox assets will stay exactly the same, only they will decrease proportionately.
Use CDN for Static Assets
Use CDN for Static Assets

Our own sw.js file registers a Workbox script that calls four more Workbox files. They’re all loaded after the document is complete and classed as low priority so won’t affect your website’s speed in any way.

Also, if you notice, Workbox is part of Google and they serve their files from a Google domain. They’ve even named them workbox-cdn so you would imagine that this is on a high-speed network at the very least, even if it isn’t on a CDN.

This is easily overcome by self-hosting the Workbox files. The only downside then is that you will have to update them once in a while to ensure there are no bugs or security risks.

16. Self-Hosting Workbox Files

Firstly, place the four files above into one JavaScript file called workbox.js.

Place this file into your root folder.

To aggregate the four files, all you need to do is paste the link from one file at at time into your browser and press return/enter. You should then see a window full of JavaScript, which you can copy and paste into a new file. Save it in a text editor first, then you can save it as .js afterwards.

Ensure you copy them in this order with the code from workbox-sw.js top of your new file.


Secondly, you’ll need to change the file path in sw.js to this:

importScripts(“/workbox.js“),workbox?console.log(“Yay! Workbox is loaded 🎉”):console.log(“Boo! Workbox didn’t load 😬”),workbox.routing.registerRoute(new RegExp(“/.*”),new workbox.strategies.NetworkFirst({cacheName:”sw-cache”}));

(I’ve recently changed my caching strategy from NetworkFirst to StaleWhileRevalidate, as ideally the service worker should be checking cache first. Try either one to suit your goals.)

You’ll probably need to clear your caches and reload your web page, as we discussed earlier.

The end result will be that you no longer get the dreaded error message, plus the request count will be minus three JavaScript files.

WebPage Test Effective Use CDN Result
WebPage Test Effective Use CDN Result

I’ve since made a slight change to this site’s service worker file so everything we need is now in the sw.js file and the workbox.js file isn’t necessary, which saves another request.

Here’s the sw.js file for this website, as it stands.

Last line of the code, you’ll notice that it misses out: importScripts(“/workbox.js”),

Code now starts at: workbox?console.log(“Yay!…

Other than that it’s exactly the same.

Hope that made sense? If you’re unsure don’t feel stupid asking questions, because PWA’s can be stressful even when you’re familiar with them.

It’s entirely up to you how many requests you want to save. Obviously at some point it makes more sense to keep things seperate, but I like to think of myself as the Adrian Newey of website optimization. Only he’s a millionaire working on the fastest car in the world and I’m skint.

Can’t argue the fact that we’re both micro-optimizers saving milliseconds.

Here’s a few rules to make things easier if you’re struggling.

  1. Manifest file goes in the root of your hosting account: /public_html
  2. Link to manifest from header.php so the browser can find it.
  3. Upload icons registered in manifest to hosting account: /public_html
  4. Service worker file goes in, you’ve guessed it: /public_html
  5. Register the service worker from header.php
  6. For simplicity use this site’s service worker – copy the contents of the file.
  7. Check your icons using this favicon checker.
  8. Test your manifest using this manifest validator.
  9. Use Chrome DevTools Audit tab to check your PWA for errors.
  10. Chrome DevTools Application tab can clear storage and update on reload.

* You might have to reload your website at least once before trying the Chrome Dev Tools, as service workers don’t usually function first time if the cache is empty.

17. Real-World Page Speed

What makes me laugh is when people use audits to mislead people. They use real audits, which gives the impression their message is real, when in fact it isn’t so.

Point being, just like on the motorway, fast cars often go slow when they’re stuck in traffic. Conversely slow cars can go fast when they’re going downhill or the wind is behind them.

Websites are no different. You will always get benchmarks results that seem out of place.

That’s why we should use our own judgement sometimes.

You can’t say “hey, guys, this is how I got 100/100 on GT Metrix” and then in another post say “don’t use Google PageSpeed Insights because it’s doesn’t have a timer.”

In fact, PageSpeed Insights is even more relevant because it shows the times that matter, like first contentful paint, time to interactive, etc. 

PageSpeed Insights Mobile Test
PageSpeed Insights Mobile Test

Google knows that the most important part of a web page is above the fold.

You know, what users actually care about.

Above-the-fold content is what your users see first.

If your above the fold content loads in 0.4 seconds and the rest of the site takes 5 seconds, the user will perceive that site to be faster than one that loads in 3 seconds, but has an above the fold time of 1 second.

Anyone that says Google’s tools aren’t worthy either have poor PSI scores or usually come from an expensive hosting company and no doubt get lots of complaints saying “why is my PSI score low?”

Just saying…

If you have any questions, please don’t hesitate to ask.

Also if you disagree with anything I’ve said, your constructive criticizm is more than welcome.

18. PWA Builder by Microsoft

Here’s a link to a nifty website that I just come across. It’s called PWA Builder by Microsoft. Apparently they’ve done it to help promote progressive web apps. This obvoiously helps us, but I was also reading that they see PWAs as a good way to make up for the lack of apps in the Microsoft App Store.

Suppose people only have to convert an existing website rather than make an expensive native app.

Regardless, it’s a really cool website, but isn’t specifically for WordPress so take that into account.

You can put your website URL into the box below…

PWA Builder by Microsoft
PWA Builder by Microsoft

Once you enter your site name, click START then you should get a report with a website score. Seen as though I’ve already got a PWA running on the test site I entered, it gave me a high score.

The 5% that it knocked me down was for ‘generated’ but I’m not sure what it refers to? One possibility is user geneated content, as in adding push notifications.

PWA Builder Website Report
PWA Builder Website Report

Anyway, I thought it might be handy to know, especially the pre-made service worker recipes and snippets that they offer in the features section.

You’re probably better of using my service worker recipe, as it’s less code and does the job. However, once you are more familiar with progressive web apps, you can come back to PWA Builder further down the line.

Such websites are always good to have in your skills wallet.

Share This Post


4 thoughts on “Progressive Web Application Tutorial – Save Upto 90% Data”

    • Hi Martin,

      Here’s a link to a specific – web manifest validator.

      It’s hard to pinpoint the problem without seeing the code, but check you’re linking to your manifest correctly. If that’s okay, it should still work even if there’s a glitch in the manifest itself.

      To begin with, I’d just import the Workbox code without combining it, then once you’re comfortable with the process it’s easy to combine it later.

      However, if you click this link aggregated service worker file you’ll get a better idea of what the file should look like.

      Hope this helps?


      • Thanks for the informative article 🙂

        Can i actually use your service worker file? i’m struggling using worbox on my own to cache assets as i use lightspeed cache wp plugin and i have multiple css/js files loading.

        Do you have any insights on the approach when having multiple css/js files you want to be cached bu the service worker?

        Any additional lines i should put on .htaccess ? i’m kinda fear that after i’ll make changes toward PWA i will have situations where users will get un-updated version of the pages / css or js files.

        appreciate your response..

        • Hi Roee,

          Yes, by all means use my service worker. It’s just 4 x Workbox files made into one, with the service worker registration snippet at the bottom.

          After trying several recipes, Workbox seemed the best option and most reliable.

          Regarding .htaccess the few lines of code I put in that were for the caching and compression of the .webmanifest file as it isn’t on Cloudflare’s approved file types. Although they’ve just added it so you can ignore that section.

          The service worker is where you set your caching strategy, .htaccess is more for the cache duration.

          Although my PWAs are pretty reliable themselves, I’m yet to find out how people are finding them at their end. Your thoughts echo mine. 🙂

          Keep up the good work!

Comments are closed.