developer.chrome.com
developer.chrome.com copied to clipboard
Describe the behaviors of extension service workers in more detail
Is your feature request related to a problem? Please describe. The current extensions documentation for service workers does not adequately cover their features, capabilities, behaviors, and limitations.
Describe the solution you'd like Revise or rewrite this article to address topics including
- Basics / overview
- The service worker lifecycle
- Event-based
- Shuts down when idle
- Forcibly terminated after 5 minutes
- Extended lifetimes for native messaging ports
- Scoped service workers
- Can't access
chromeglobal - Can handle network requests for registered subpath
- Can't access
- The service worker lifecycle
- Event listener requirements
- Must be registered on the first turn of the event loop
- Divergence from the open web
- How extension service worker installation and update process
- Extension platform handles SW registration and update - devs don't need to (shouldn't) use
navigator.serviceworker.register()
- Extension platform handles SW registration and update - devs don't need to (shouldn't) use
- Devs don't have to install & update the SW manually (can't, actually)
fetchevent handler(?)- Note: I think I saw some unexpected behavior here. Possibly related to WAR? Needs to investigation.
- How extension service worker installation and update process
- Loading multiple files
- Classic scripts use
importScripts() - Module scripts use
importstatements - Note: dynamic
import()maybe??? - Techniques to minimize startup time
- Wrap code that don't necessarily need to be executed on startup in a function
- Classic scripts use
- Debugging extension service workers
- Performance analysis (workarounds)
- Behavior differences for unpacked extensions
runtime.reload()will pick changes from disk, may require SW to restart- Note: Need to investigate impact of iframed extension pages.
- "the current implementation of extension ServiceWorker … updates every 5-6 minutes" (per @guest271314)
Devs don't have to install & update the SW manually (can't, actually)
What is meant here? Yes, the ServiceWorker can be uppdated manually.
Extended lifetimes for native messaging ports
Has this https://github.com/GoogleChrome/developer.chrome.com/issues/2688 been fixed? Or are you just compounding a qualified claim?
Extended lifetimes for native messaging ports
That language does not look accurate.
Native Messaging ports do not have a lifetime.
Did you mena extending the active state of MV3 ServiceWorker when/while Native Messaging port is open?
What is meant here? Yes, the ServiceWorker can be uppdated manually.
When I last looked into this I seem to recall Chrome throwing an error that started something to the effect that that this operation is not allowed. Do you happen to have a demo handy, @guest271314?
Has this #2688 been fixed? Or are you just compounding a qualified claim?
There has been doing progress in the relevant Chromium issue, but more broadly our documentation primarily focuses on how we intend for the platform to behave. In this case the underlined bug has not been fully resolved (and I expect to include a note to that effect) but we still need to communicate what developers should expect.
That language does not look accurate. …
Did you mena extending the active state of MV3 ServiceWorker when/while Native Messaging port is open?
That bulleted list was a rough outline of the article content that I sketched out over a few minutes as I prepared the issue.
As you guessed, I was referring to extending the service workers lifetime rather than commenting on the native messaging port’s lifetime.
chrome.runtime.reload() unless you mean something else by
(can't, actually)
I would be careful with language re ServiceWorker being active/non-active. As per specification it is not intended to be active persistently. However, when you make claims that infer developers in the field can make MV3 ServiceWorker persistent, that should work without caveats or further explanation; else the false claims are just compunded when put to the test in the field.
https://github.com/mdn/content/issues/12370#issuecomment-1020220649
The service worker is not supposed to stay alive, and attempts to make it stay alive will be buggy.
Shared workers however do stay alive.
If you think extensions should be able to use shared workers, that's something to propose to extension folks.
chrome.runtime.reload() unless you mean something else by
(can't, actually)
I meant something else. I was referring to the way that developers register and update service workers on the open web. That pattern does not apply to extensions because extensions use a different installation and update model. In extensions, the browser is responsible for registering and updating an extension's service worker.
chrome.runtime.reload() unless you mean something else by
(can't, actually)
I meant something else. I was referring to the way that developers register and update service workers on the open web. That pattern does not apply to extensions because extensions use a different installation and update model. In extensions, the browser is responsible for registering and updating an extension's service worker.
I think you should make it clear that you are referring to Chrome Web Store or other third-party installation methods.
In Developer mode we install unpacked extensions and have total control over updating and modifying the extension and ServiceWorker.
Your language appears to be entirely scoped towards Chrome Web Store extensions.
In extensions, the browser is responsible for registering and updating an extension's service worker.
I still don't think that is entirely correct. A developer can update their unpacked extension at any time. In the case of an extension the "update" is simply reloading the extension; whether changes are made to the source code or not.
Technically, the current implementation of extension ServiceWorker on Chromium/Chrome updates every 5-6 minutes.
Your language appears to be entirely scoped towards Chrome Web Store extensions.
Signed .crx packages are the only officially supported distribution mechanism for extensions. Loading an unpacked extension is intended as a developer capability and should not be used by the average user. Documentation on developer.chrome.com should reflect this perspective.
That said, I agree that we should provide more guidance for developers regarding the differences between running packed and unpacked extensions. I've added a top level bullet tentatively titled "Behavior differences for unpacked extensions" to the outline to cover this information.
Loading an unpacked extension is intended as a developer capability and should not be used by the average user. Documentation on developer.chrome.com should reflect this perspective.
I don't think that is a valid perspective. Why should users trust Chrome Web Store and not their own local installation?
Techniques to minimize startup time Wrap code that don't necessarily need to be executed on startup in a function
The title is great, but it's much more complicated.
-
Even with a trivial extension there's the overhead to start the worker, at least 50ms, which may exceed the time spent in the background script by such a great margin that any optimization of JS is essentially moot.
-
Postponing won't help reducing the potentially huge load/preparse/parse/compile time before the script even runs. In many extensions it may easily take half a second for a moderate bundle on an average notebook.
-
It's often impossible to postpone the code e.g. if it's used to rehydrate the state from db/websocket/whatever. There is a limit to what you can achieve by reworking the architecture of the storage or the entire extension and the latter is not always possible due to the lack of a necessary API in Chrome e.g. extensions like Stylus or DarkReader can't rely on chrome.scripting.registerContentScripts as it can't register a dynamically constructed CSS string, so they have to read all the styles and compile their matching rules to find out which of them to apply to the network request that woke the SW. It takes 200-500ms from the moment the navigation occurred (including 50ms of the SW spin-up time) depending on the amount and complexity of the styles. Obviously too long to be usable for fast modern SPA sites that use SW caching.
To reiterate, none of this matters for simple extensions that take much less than 50ms to initialize after SW started as measured in devtools timeline/profiler for the SW context from the moment their SW script is getting loaded from disk.
Here's some impactful solutions for extensions with a huge background script:
-
Don't put the code in SW context, duh, simple as that. Many advanced web developers mistakenly treat the background script as a "back-end" API server and just put almost everything there. The solution would be to try extracting the parts used only by the popup or the options or another visible page - the things that don't have to run after the view is closed. Split the things that need to run longer, there shouldn't be a lot of them usually.
-
Use dynamically loaded modules. It's unnecessarily complicated though:
- importScripts can only work in classic mode
- MV3 still doesn't have dynamic import() in SW
- to use importScripts dynamically one needs to duplicate it in
self.onstallevent per the SW specification to make sure the remote code is cached (which is entirely irrelevant for extensions as they are local and yet this quirk is being enforced thus crippling developer experience). FWIW, the same restriction will apply to the dynamic import in SW when it's added to the web platform. - no plugin for webpack/rollup/parcel/react etc. that uses the double-importScripts "trick" which means all this jumping through the hoops is for a few enthusiasts.
@jpmedley Should we close this issue? Seems like these topics were addressed in the service worker collection?
I think it's safe to close it. I'm going to verify this list against our whole doc set because I don't think we covered it in quite the way Simeon outlined it. I'll open a new ticket with anything that's missing.