Service worker wake-up vectors

1,519 views
Skip to first unread message

Ioannis Charalampidis

unread,
Sep 12, 2021, 8:24:38 AM9/12/21
to Chromium Extensions
Hi All,

Where can I find all possible events that are guaranteed to wake-up an MV3 service worker?

So far I know of:
  • Alarms (chrome.alarm)
  • GCM (chrome.gcm)
  • Web Push (coming as an 'push' event to the service worker, though not 100% sure how/if someone can programmatically subscribe there in the context of an extension - does anyone have pointers here please?)
I am also assuming that all the rest of the API listeners will always wake-up the worker, since it's crucial for the extension to deliver the intended behavior. To name a few:
  • Tab Events (chrome.tabs.onXXXX)
  • Window Event (chrome.windows.onXXXX)
  • Idle Events (chrome.idle.onXXXX)
  • Runtime Events (chrome.runtime.onXXXX)
  • etc.
Is this assumption correct? Are the event listeners of all the APIs guaranteed to wake-up the extension service worker? Are some event listeners not following this rule?

And what about ports established with `chrome.runtime.connect` ? Are they guaranteed to keep the worker awake if there is traffic?

Anu Kuruvilla

unread,
Sep 12, 2021, 10:17:00 AM9/12/21
to Ioannis Charalampidis, Chromium Extensions
We observed that runtime.connect keeps connection for 5 minutes irrespective of whether data traffic is there or not

--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/8ed86a9c-301a-4daa-89a0-b0b4def4f0e0n%40chromium.org.

wOxxOm

unread,
Sep 12, 2021, 10:36:36 AM9/12/21
to Chromium Extensions, icha...@bardeen.ai
All chrome API events must wake up the worker but there may be bugs. The only bug I know is webRequest, https://crbug.com/1024211 - this API was implemented in a way that never worked with non-persistent background pages (event pages) so it's still unclear how the extensions team will be able to fix it.

If the worker registers a `fetch` event then it'll also wake up when you open pages of the extension or get its own resources from such pages.

>  And what about ports established with `chrome.runtime.connect` ? Are they guaranteed to keep the worker awake if there is traffic?

Currently the service worker terminates any port after the five minute interval per Service Worker specification for ExtendableEvent regardless of its activity, see https://crbug.com/1152255. This is definitely a bug because there's no point in such a limit as an extension can trivially re-connect a new port and prolong the worker for another five minutes, indefinitely.

Note that for extensions that observe user activity keeping the background script alive is not detrimental to the browser's resource usage, on the contrary, it's much better than restarting the worker hundreds of times a day because each restart is an extremely heavy operation that stresses CPU, memory, disk, and wastes battery life. Unfortunately, the official documentation and other official communications still retain the generally false claims that a persistent background script is bad for performance and/or resource usage, but it's an understandable mistake as there apparently has never been a single person in the Chromium team who performed proper performance measurements in this area.

hrg...@gmail.com

unread,
Sep 12, 2021, 11:02:22 AM9/12/21
to Chromium Extensions, wOxxOm, icha...@bardeen.ai
There's also the special case of  chrome.runtime.connectNative which will keep the SW alive permanently. At least this is what I've read here in the forum from Simeon. It's not implemented yet, AFAIK.

Cuyler Stuwe

unread,
Sep 12, 2021, 11:04:32 AM9/12/21
to hrg...@gmail.com, Chromium Extensions, wOxxOm, icha...@bardeen.ai
It certainly doesn't at the moment. I didn't hear anyone say that it would. Is that actually true?

--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.

hrg...@gmail.com

unread,
Sep 12, 2021, 12:36:49 PM9/12/21
to Chromium Extensions, salem...@gmail.com, Chromium Extensions, wOxxOm, icha...@bardeen.ai, hrg...@gmail.com

Cuyler Stuwe

unread,
Sep 12, 2021, 12:48:45 PM9/12/21
to hrg...@gmail.com, Chromium Extensions, icha...@bardeen.ai, wOxxOm
Hmm. June is quite a while back… I wonder whether that’s still the case. Seems that WebSockets should be supported too, at the very least.

Ioannis Charalampidis

unread,
Sep 12, 2021, 6:37:05 PM9/12/21
to Chromium Extensions, salem...@gmail.com, Chromium Extensions, Ioannis Charalampidis, wOxxOm, hrg...@gmail.com
Thanks a lot for the feedback everyone, that's super helpful!

> Note that for extensions that observe user activity keeping the background script alive is not detrimental to the browser's resource usage, on the contrary, it's much better than restarting the worker hundreds of times a day because each restart is an extremely heavy operation that stresses CPU, memory, disk, and wastes battery life.

Wow, does it seriously get put to sleep and woken-up every single time? That sounds horrible... Isn't Chrome supposed to do some kind of optimization to keep the worker alive as much as possible?
And since we are on the topic, is there any official documentation regarding when a worker is put to sleep?

My naive guesstimate is that chrome will put the worker to sleep if there is no event activity for X minutes.
Could it then be converted into a persisting background worker if I am dispatching an alarm every minute? 😁

> Unfortunately, the official documentation and other official communications still retain the generally false claims that a persistent background script is bad for performance and/or resource usage, but it's an understandable mistake as there apparently has never been a single person in the Chromium team who performed proper performance measurements in this area.

Well, I see the good intentions behind MV3, but I don't see it being thoroughly thought. (and considering that Google is not lacking intellect, I am assuming there are business decisions behind it)

To be more precise, if your extension is not implementing any serious business logic (and therefore your service worker is small), the MV3 implementation makes total sense: instead of having a persistent JS VM running all the time, waking-up your worker just to handle an event sounds like a sensible way to reduce the resource footprint... and honestly, since the majority of the extensions are simple enough to fall into this category, I do see the value.

However, if you are implementing any kind of more complex logic you are more or less doomed: your service worker becomes too heavy for being constantly restarted, you have no capabilities for starting web workers, and you have to resort to ugly workarounds to deliver your functionality. This is too obvious to be a bad decision... (and considering how easy it is to run your business logic on GCE and interface with your extension using GCM (now FCM), it kind of gives you an idea of the intended future direction).

Obviously, extensions that are dealing with private data will never be able to migrate on the cloud, so they will be forced to use ugly workarounds, use native binaries, or simply retire...

From my PoV, since I am also developing something that falls under the last category, I would have been immensely happy with MV3 if:
  • The service worker state was persisted and restored by chrome between sleep cycles (that will greatly improve the worker start-up time)
    (Or simply introduce a permission that will allow the service worker to persist forever)
  • There was an API that would allow me to spin multiple Service Workers in the extension domain, in the same way I could spin Web Workers (this will improve the parallelization on heavyweight local tasks)
I am actually willing to invest the time to contribute these features to Chrome myself, but I have no idea about the contribution process there 😁

wOxxOm

unread,
Sep 13, 2021, 2:34:41 AM9/13/21
to Chromium Extensions, icha...@bardeen.ai, salem...@gmail.com, Chromium Extensions, wOxxOm, hrg...@gmail.com
> does it seriously get put to sleep and woken-up every single time? 

There's a delay, of course. The service worker's process is destroyed after 30 seconds since the last event that is allowed to prolong its lifetime such as the `chrome` API event. It means chrome.alarms won't help here as its interval is intentionally throttled to 1 minute since the last activation of the background script for web store extensions.

Inside the worker you can use ExtendableEvent's waitUntil() to prolong the service worker's life time by five minutes in the `activate` event handler, which will keep the worker alive as long as your extension is used again within this five-minute cycle. You can also use chrome.runtime ports to keep the worker alive indefinitely, as long as there's any connectable tab/frame around. More info and examples: https://stackoverflow.com/a/66618269.

> To be more precise, if your extension is not implementing any serious business logic (and therefore your service worker is small), the MV3 implementation makes total sense: instead of having a persistent JS VM running all the time, waking-up your worker just to handle an event sounds like a sensible way to reduce the resource footprint... and honestly, since the majority of the extensions are simple enough to fall into this category, I do see the value.

The idea itself indeed makes sense as a vector of optimization but it was implemented without proper investigation, the team simply claimed there's no need for persistent background script without any proof (well, there's no such proof anyway). This approach makes sense in case an extension is used infrequently. The problem is that many users (IMO at least 50% of all extension users) will have at least one extension that observes user activity and so it'll activate hundreds of times per day because users take some time to digest information after they switch the tab (chrome.tabs.onActivated) or navigate it (chrome.tabs.onUpdated, webNavigation, webRequest, chrome.runtime messaging) and that time usually exceeds the 30 seconds of the default service worker's lifetime.

> [If] the service worker state was persisted and restored by chrome between sleep cycles (that will greatly improve the worker start-up time)

You probably mean the state of the JS engine, which Chrome can't currently save/restore. Yes, it'd be nice. Something similar to hibernation in Windows that dumps RAM on disk. However, if you mean the state of the extension, then saving/restoring it won't generally help with this particular problem, which also consists of creating the extension worker's process - it takes at least ~50ms and another 1-1000ms to load/compile/run the actual background script - which stresses CPU/memory/disk/battery. Tip: don't use a huge background script, use a tiny event router script that dynamically loads the corresponding js file for this specific event (see comments 10 and 11 in https://crbug.com/1198822#10).

> API [...] to spin multiple Service Workers in the extension domain

If you mean concurrent service workers then IIRC I've seen this idea in the service worker's specification repository on github, but it was rejected due to the additional complexity that would be beneficial only in rare cases.

As for child web workers, currently a service worker can't create them per the specification, see https://crbug.com/1219164.

Ioannis Charalampidis

unread,
Sep 13, 2021, 3:41:10 AM9/13/21
to Chromium Extensions, wOxxOm, Ioannis Charalampidis, salem...@gmail.com, Chromium Extensions, hrg...@gmail.com
> You can also use chrome.runtime ports to keep the worker alive indefinitely, as long as there's any connectable tab/frame around

That's a cool trick! And this kind of proves your point: since such thing is possible even right now, why can't there be an official "background" permission  (or any other primitive) that will allow the service worker never to stop?

I am growing to like the permission idea, since it will make the developers think twice before submitting their extension for review (and therefore implicitly applying a filter that will force simple extensions to use the stoppable service worker implementation).

> You probably mean the state of the JS engine, which Chrome can't currently save/restore

Yeah, I am referring to the entire VM state (so code-loading and initialization is not costing anything).
Since there is a strong intention to disallow dynamic code execution, the process of hibernating the optimized code + the heap doesn't seem like an impossible task.

> Tip: don't use a huge background script, use a tiny event router script that dynamically loads the corresponding js file for this specific event

That's actually a good point... but even then, isn't the sheer amount of JS code that the compiler has to parse (eventually) adding-up to the same time as just loading one big bundle?
I could see this value on the UI, were the user progressively sees more components, but I don't think it makes much sense in a background script.

> As for child web workers, currently a service worker can't create them per the specification

Yeah I noticed, that's why I was curious if such thing can be added...
But while poking around, I just noticed this : https://github.com/w3c/ServiceWorker/issues/1529 so it seems there are some plans in that direction.

wOxxOm

unread,
Sep 13, 2021, 3:54:33 AM9/13/21
to Chromium Extensions, icha...@bardeen.ai, wOxxOm, salem...@gmail.com, Chromium Extensions, hrg...@gmail.com
> isn't the sheer amount of JS code that the compiler has to parse (eventually) adding-up to the same time as just loading one big bundle? I could see this value on the UI, were the user progressively sees more components, but I don't think it makes much sense in a background script.

The tip assumes the extension either a) does conditional work which can be off-loaded to a script loaded only when necessary or b) observes many events so each event can have a small/smaller js file that handles it.

Kibegwa A Kibegwa

unread,
Sep 13, 2021, 5:19:29 AM9/13/21
to Ioannis Charalampidis, Chromium Extensions
The phone is starting to work slowly not in normal speed,can I wait? Or something must be done?

--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
Reply all
Reply to author
Forward
0 new messages