So I am in the process of migrating a MV2 extension which used persistent Background pages to MV3. In the Chrome migration guide [https://developer.chrome.com/docs/extensions/mv3/migrating_to_service_workers/#event_listeners] it says :
In order for Chrome to successfully dispatch events to the appropriate listeners, extensions must register listeners in the first turn of the event loop. The most straightforward way to achieve this is to move event registration to the top-level of your service worker script.
When a service worker is terminated, so are the event listeners associated with it. And since events are dispatched when a service worker starts, asynchronously registering events results in them being dropped because there's no listener registered when it is first spun up.
My question:
// background.js(service worker)
chrome.storage.local.get(["badgeText"], ({ badgeText }) => {
chrome.action.setBadgeText({ text: badgeText });
// Listener is registered asynchronously
// This is NOT guaranteed to work in Manifest V3/service workers! Dont do this
chrome.action.onClicked.addListener(handleActionClick);
});
Why do we have to register it like that ?
Because this is how event registration is implemented internally to let the browser know which types of events should wake up the worker:
addListener
for chrome
events, the API stores the function reference internally and tells the browser to remember this event name in the internal browser database.Whats the issue if we register after awaiting an asynchronous operation ?
When the background service worker script wasn't running before the event, it's started as described above and your belatedly registered listener won't be present in the internal API database, so it won't be called and this event will be lost for you.
Only when the background service worker script is already running before the event is fired, your belatedly registered listener will see the event.
If indeed
When a service worker is terminated, so are the event listeners associated with it
then how come an inactive service workers become active suddenly ,if event listeners are all terminated ?(I assume it isnt listening for events if event listeners are terminated .)
Indeed, when the background service worker script is terminated it's like closing of a tab, nothing survives inside, it doesn't listen to anything, there's no "it" anymore.
The wake-up is implemented by addListener
telling the browser to remember the event names and their filters (e.g. in webRequest of webNavigation) in the internal database of the browser process, which happens every time the background service worker script runs (but only in the first turn of the event loop). When an event matching the criteria occurs in the browser, the browser starts the extension's background service worker script and dispatches the event as described in the beginning of this answer.