Service Worker ⚙ Termination by a Timeout Timer was Canceled ❌ because Devtools is Attached [Solution] 👍
Are you receiving the message in the console?
"service worker termination by a timeout timer was canceled because devtools is attached"
Are you worried you have added something bad to your service worker?
There is no need to worry, this is a new 'information' message Chrome has added in recent versions and does not indicate anything is wrong with your code or logic.
How a Service Worker's Life Span is Determined
Not to be confused with the Service Worker Life Cycle, the time a browser keeps a site's service worker active once it has been triggered varies by browser and is what we are discussing here.
When a user opens a page associated with a registered service worker and the service worker is not active the browser instantiates the service worker. It runs in its own thread, technically external to the page. To conserve resources only one instance of the service worker is created and all associated pages use the single instance.
Even if a page is open in a tab, it may be idle, which means there is no need for a service worker to be active. If it were active excess CPU, memory and other resources are tied up when they are not needed. This means the user's battery drains faster than it needs and no one wants that.
Each browser uses it on calculations to determine when to kill an active, but unused service worker. There is no magic time in seconds when a service worker dies. It could be a minute or 30 minutes for all I know.
The specification states the following:
A user agent may terminate service workers at any time it:
- Has no event to handle.
- Detects abnormal operation: such as infinite loops and tasks exceeding imposed time limits (if any) while handling the events.
My guess is each browser does some sort of internal calculation based on available resources, if the device is using the battery or plugged in, etc. Somethine similar to how it determines how much storage space is available to a domain.
We do know browsers can and should aggressively kill unused service workers to optimize the device's performance.
Don't worry about breaking your application. If the service worker is dead and the user triggers it again the browser just spins up a fresh instance. This process is very quick and should not be noticable to your customer.
Why Chrome Displays The Warning Message
Chrome detects when DevTools are open and does not kill the service worker ass aggressively. The browser assumes a developer is using DevTools and might be debugging service worker's code. Killing the service worker would cause all sorts of hair pulling and trust me we do that enough as it is.
The past few versions of Chrome have added the "service worker termination by a timeout timer was canceled because devtools is attached" message to the work flow. This is done as a courtesy to help developers realize what they are debugging may not be exactly what the user would experience.
For developers the number one issue is relying on the persistence of global state. I am not an advocate of leaning heavy or even medium on global state as a value reference. I teach, always assume the service worker is being freshly instantiated.
This is not unique to service workers, I have seen abusive use of global state almost my entire career. Personally I see the MVVM pattern (think Angular) is the most abusive pattern and leads to large memory footprints and poor performance. Plus you must write more code (in my experience) than you would if you relied on hydrating what you need for the page.
The programming model is similar to how you should use when developing AWS Lambdas or Azure Functions. Write code that executes statically and assume nothing is preset before execution. Its OK to use some 'global' variables, but don't over use them.
As a developer you may experience scenarios where you think you are updating globally scoped values, but because the service worker is not terminated as you expected they are not. This can lead to wasted time troubleshooting why your new code is not performing as expected. You may need to explictly terminate the service worker in the Devtools.
I do this often as well as manually unregistering service workers because they get into jacked up states after I make several layers of changes during a development cycle (what I call when I sit down for a few hours with my headphones jamming and my mind focused).
This does not mean you should not create global variables in your service worker, it just means be smart about what you are declaring.
Service Worker is not responding
Another, related message you might see in the console is "service worker is not responding".
This is common if you are sitting on a break point for a long period of time. I have seen this message a few times, typically when I see some broken code and start down a set of rabbit trails updating the code or some other distraction interrupts my focus.
We have all been there.
I find it is best to kill the debug instance and sort of start fresh after making the changes anyway. So don't let this one freak you out either.
The "service worker termination by a timeout timer was canceled because devtools is attached" is a courtesy message to help developers know the service worker experience they are testing against may not reflect what a production user experiences. If you see this and you want to make sure your service worker performs as expected you should think about running the progressive web app without the Devtools open.
Of course you should always test as your real users would experience your applications. This means you should also test on real mobile devices, like a $100 phone from WalMart over a 3G network. But just closing the Devtools can be a good first pass to flesh out common issues.