Reputation: 9996
We are conducting an experiment to gauge the benefits of service worker. As part of that we are recording pageLoadTime and service worker state. The idea is that the data which has controller state as activated will be treated as pages served via service worker and where service worker is not installed will have controller as null and so no service worker state. This way we can compare pageLoadTime with & without service worker.
Is this the right approach to know that the page is being served from SW? One concern that comes to mind is, if SW gets killed in between and gives us wrong info about the state. However we are recording service worker state way early in page load lifecycle as soon as our js code boots up. So at this point SW should be up & running intercepting traffic from the page. This looks to be a safe technique. Any thoughts are this ?
Another approach that comes to mind after reading PerformanceResourceTiming API on MDN is to use workerTime.
The workerStart read-only property of the PerformanceResourceTiming interface returns a DOMHighResTimeStamp immediately before dispatching the FetchEvent if a Service Worker thread is already running, or immediately before starting the Service Worker thread if it is not already running. If the resource is not intercepted by a Service Worker the property will always return 0.
As per the doc, it mentions workerTime will always be zero if SW is not there. Can there be a scenario when SW is installed and yet workerTime is zero?
As an trial, I crawled to Pinterest and queried following in Chrome dev console, workerTime is always zero though SW is there.
performance.getEntriesByType('navigation')[0]
Upvotes: 0
Views: 274
Reputation: 30451
For your own applications, where you're in control of the code that registers the service worker, the best way to determine whether a service worker was in control of the page at load time is to check navigator.serviceWorker.controller
before you call navigator.serviceWorker.register()
. If navigator.serviceWorker.controller
is not null
that means a service worker was in control when the page was loaded.
Note, it's important to check navigator.serviceWorker.controller
before registering your service worker, because a service worker can start controlling the page after it's registered (if it calls clients.claim()) but in such cases it wasn't controlling the page at load time, which is what you care about.
On my website, here's the code I use on my blog to determine the initial service worker state:
export const initialSWState = !navigator.serviceWorker ? 'unsupported' :
navigator.serviceWorker.controller ? 'controlled' : 'supported';
And since this code runs in the initial evaluation of the module, I know it runs before I register my service worker (which I postpone until after the load
event.
One concern that comes to mind is, if SW gets killed in between and gives us wrong info about the state.
That's not a problem. When a service worker is in control of a page, navigator.serviceWorker.controller
will always return a reference to that service worker, even if it's not currently running.
As per the doc, it mentions workerTime will always be zero if SW is not there. Can there be a scenario when SW is installed and yet workerTime is zero?
Yes there can. Looking at my own analytics data over the last 30 days, I see a 0
value for workerStart
in 14.5% of cases where I knew (using the above technique) that the service worker was in control at page load time. And of 14.5%, almost all of them were either Firefox or Safari, so it looks like those browsers don't correctly set the workerStart
value.
Upvotes: 1