Service worker weirdness in Chrome
I think I’ve found some more strange service worker behaviour in Chrome.
It all started when I was checking out the very nice new redesign of WebPageTest. I figured while I was there, I’d run some of my sites through it. I passed in a URL from The Session. When the test finished, I noticed that the “screenshot” tab said that something was being logged to the console. That’s odd! And the file doing the logging was the service worker script.
I fired up Chrome (which isn’t my usual browser), and started navigating around The Session with dev tools open to see what appeared in the console. Sure enough, there was a failed fetch
attempt being logged. The only time my service worker script logs anything is in the catch
clause of fetching pages from the network. So Chrome was trying to fetch a web page, failing, and logging this error:
The service worker navigation preload request failed with a network error.
But all my pages were loading just fine. So where was the error coming from?
After a lot of spelunking and debugging, I think I’ve figured out what’s happening…
First of all, I’m making use of navigation preloads in my service worker. That’s all fine.
Secondly, the website is a progressive web app. It has a manifest file that specifies some metadata, including start_url
. If someone adds the site to their home screen, this is the URL that will open.
Thirdly, Google recently announced that they’re tightening up the criteria for displaying install prompts for progressive web apps. If there’s no network connection, the site still needs to return a 200 OK
response: either a cached copy of the URL or a custom offline page.
So here’s what I think is happening. When I navigate to a page on the site in Chrome, the service worker handles the navigation just fine. It also parses the manifest file I’ve linked to and checks to see if that start URL would load if there were no network connection. And that’s when the error gets logged.
I only noticed this behaviour because I had specified a query string on my start URL in the manifest file. Instead of a start_url
value of /
, I’ve set a start_url
value of /?homescreen
. And when the error shows up in the console, the URL being fetched is /?homescreen
.
Crucially, I’m not seeing a warning in the console saying “Site cannot be installed: Page does not work offline.” So I think this is all fine. If I were actually offline, there would indeed be an error logged to the console and that start_url
request would respond with my custom offline page. It’s just a bit confusing that the error is being logged when I’m online.
I thought I’d share this just in case anyone else is logging errors to the console in the catch
clause of fetches and is seeing an error even when everything appears to be working fine. I think there’s nothing to worry about.
Update: Jake confirmed my diagnosis and agreed that the error is a bit confusing. The good news is that it’s changing. In Chrome Canary the error message has already been updated to:
DOMException: The service worker navigation preload request failed due to a network error. This may have been an actual network error, or caused by the browser simulating offline to see if the page works offline: see https://w3c.github.io/manifest/#installability-signals
Much better!