MV3 service workers: Running a function once at the start

1,199 views
Skip to first unread message

ComputerWhiz

unread,
Jan 14, 2022, 2:00:42 PM1/14/22
to Chromium Extensions
A while ago, I ported my extension from Firefox to Chrome. With MV3 just around the corner, I want to start migrating my extension from MV2 to MV3. It's been a bit of a learning curve, mainly because background scripts are replaced by service workers, which I am not familiar with.

Previously, when I wanted a function to run when the extension is started up (either for first install or when the browser is started), I could just put the function call in the background script and it would run, since background scripts are persistent.

For what I can tell, doing that with a service worker will cause the function to run each time the service workers starts again, after having been terminated because it was idle. That's obviously not what I want to happen.

Do I need to register onInstall and onStartup listeners to trigger the function?

wOxxOm

unread,
Jan 15, 2022, 10:05:39 AM1/15/22
to Chromium Extensions, ComputerWhiz
Yes, you would need an onStartup listener. BTW, there's nothing conceptually new in service workers: in case of an extension it's just a non-persistent background page script without DOM and other `window`-specific stuff.

avm99963

unread,
Jan 15, 2022, 10:20:54 AM1/15/22
to Chromium Extensions, wOxxOm, ComputerWhiz
I wonder whether the onStartup listener will fire if an extension is disabled when Chrome starts up and is later on enabled from chrome://extensions, given that onStartup is fired when the Chrome profile starts up, not when the extension starts up.

In one of my extension I have to account for this case, and I can't find any way of doing this.

Cheers :-)

wOxxOm

unread,
Jan 15, 2022, 10:35:45 AM1/15/22
to Chromium Extensions, avm99963, wOxxOm, ComputerWhiz
You can probably use chrome.storage.session as it's cleared when the extension is disabled so just write something there in onStartup.

wOxxOm

unread,
Jan 15, 2022, 10:37:08 AM1/15/22
to Chromium Extensions, wOxxOm, avm99963, ComputerWhiz
...and if onStartup doesn't fire you can just check chrome.storage.session every time at the script's start.

avm99963

unread,
Jan 15, 2022, 12:22:16 PM1/15/22
to Chromium Extensions, wOxxOm, avm99963, ComputerWhiz
That's clever, thanks wOxxOm!

https://crbug.com/1185226#c49 seems to indicate your solution would work wonderfully for all edge cases :)

hrg...@gmail.com

unread,
Jan 15, 2022, 2:00:24 PM1/15/22
to Chromium Extensions, avm99963, wOxxOm, ComputerWhiz
A disabled extension behaves identical to an extension that's not installed at all.
i.e. it does absolutely nothing.

The only difference between disabling and uninstalling is that disabling an extension does not delete any data from permanent storages such as chrome.storage.local or window.localStorage.

Additionally, the Chrome Web Store includes disabled extensions in the count of "users" publicly visible in the store.

Cuyler Stuwe

unread,
Jan 15, 2022, 2:01:07 PM1/15/22
to avm99963, Chromium Extensions, ComputerWhiz, wOxxOm
Uh, hey avm... onStartup (unfortunately) does NOT actually run on profile startup (wish it did!), but instead on browser startup. Wish we did actually have an event listener for opening a specific profile! I have multiple browser profiles where I have different instances of the same extension (one for dev, one for staging, one for prod-preview, one for CWS-deployed-prod). First thing it does in onStartup is open a minimized window that we're pretending is the "background page" for APIs where we absolutely need one but MV3 doesn't provide. When I start Chrome (to the profile-selector page), ALL of them fire their listener callbacks. I end up with 4 minimized windows -- one per profile. Maybe this is platform/configuration-specific? This is the behavior I encounter across three different Macs at least, running default Chrome without any special flags/etc.

--
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/10339903-b4a7-4093-8079-eb3de131ca7dn%40chromium.org.

Cuyler Stuwe

unread,
Jan 15, 2022, 2:03:43 PM1/15/22
to hrg...@gmail.com, Chromium Extensions, avm99963, wOxxOm, ComputerWhiz
And what's worse about the onStartup thing is also not only that it runs on browser (rather than profile) startup, but that there are a lot of situations where users think they've "closed" their Chrome browsers, but it continues to run in the background. In my default Chrome configuration with more than one profile installed, closing the last Chrome window keeps Chrome running in the background, so that the next click of the icon brings up the profile-launcher window. This doesn't fire any additional onStartup listeners.

--
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.

avm99963

unread,
Jan 15, 2022, 2:15:54 PM1/15/22
to Chromium Extensions, salem...@gmail.com, Chromium Extensions, avm99963, wOxxOm, ComputerWhiz, hrg...@gmail.com
Thanks salem...@ for the detailed explanation, it really helps!

I said it runs on profile startup since that's what I understood from reading the docs:[1]

> Fired when a profile that has this extension installed first starts up.

I didn't realize this meant it fired at the same time for all profiles. I should definitely do some actual tests to see how onStartup behaves in my Mac.

Cheers :-)

Cuyler Stuwe

unread,
Jan 15, 2022, 2:17:43 PM1/15/22
to avm99963, Chromium Extensions, wOxxOm, ComputerWhiz, hrg...@gmail.com
Oh, yeah... Uh... Don't trust the docs. Lol. They're often wrong for Chrome extensions, and have been so especially since the advent of MV3. Last I checked, a lot of the things there about the manifest, for example, were still either wrong or nonfunctional.

Cuyler Stuwe

unread,
Jan 15, 2022, 2:26:12 PM1/15/22
to avm99963, Chromium Extensions, wOxxOm, ComputerWhiz, hrg...@gmail.com
With regard to enable/disable, there is actually a listener you can register for that, and I just double-checked to make sure it still works as expected in MV3:

chrome.management.onEnabled.addListener(async extensionInfoForUpdatedExtension => {
    const ourExtensionInfo = await chrome.management.getSelf();
    if(extensionInfoForUpdatedExtension.id === ourExtensionInfo.id) {
        // TODO: Whatever you want to do after update
    }
});

Unfortunately, however, this requires including the fairly-powerful management permission in your manifest. Would be nice if they added a runtime listener that just the extension listen for its own enable event.

Cuyler Stuwe

unread,
Jan 15, 2022, 2:27:07 PM1/15/22
to avm99963, Chromium Extensions, wOxxOm, ComputerWhiz, hrg...@gmail.com
TODO Comment says "update"... meant to say "enable". Too many crossed threads in brain. 😅

avm99963

unread,
Jan 15, 2022, 2:42:25 PM1/15/22
to Chromium Extensions, salem...@gmail.com, Chromium Extensions, wOxxOm, ComputerWhiz, hrg...@gmail.com, avm99963
With regards to the docs, I think they have gotten much better over time thanks to its maintainers. And the fact they have been open sourced is great, because we can contribute fixes if we detect them.

Thanks for the example! For my use case chrome.storage.session seems to work better, but making that listener for your own extension available in chrome.runtime would definitely help in other cases since requesting the management permission is too much. I see the addition to chrome.runtime has been discussed here: https://crbug.com/388231.

Jackie Han

unread,
Jan 26, 2022, 5:29:15 AM1/26/22
to avm99963, Chromium Extensions, salem...@gmail.com, wOxxOm, ComputerWhiz, hrg...@gmail.com
About chrome.runtime.onInstalled vs chrome.runtime.onStartup: 
onInstalled event: fired when extension install or update, don't fired when browser startup
onStartup event: fired when browser startup, don't fired when extension install or update

If you want to do something when extension startup(including install, update or browser startup), you need to register both two listeners.

ComputerWhiz

unread,
Jan 26, 2022, 8:58:15 AM1/26/22
to Chromium Extensions, Jackie Han, Chromium Extensions, salem...@gmail.com, wOxxOm, ComputerWhiz, hrg...@gmail.com, avm99963
Unfortunately, neither of those calls fire when an extension goes from disabled to enabled, as was mentioned above. There's also issues with the onInstalled not firing if the extension is disabled. Therefore, if there's any storage migration that needs to be done on an update, for example, you're kind of out of luck when the user enables the add-on again.

The chrome.storage.session is an ok workaround, but it's still very much a workaround to fix an issue that no one making Manifest V3 bothered to think about.

Jackie Han

unread,
Jan 26, 2022, 9:19:56 AM1/26/22
to ComputerWhiz, Chromium Extensions, salem...@gmail.com, wOxxOm, hrg...@gmail.com, avm99963
Yes, onEnable is not covered in the current extension api. Hope the issue will be fixed.

Another workaround is checking states every time when service worker wake up before doing anything.

PS: chrome.storage.session only works on MV3

Jackie Han

unread,
Jan 26, 2022, 9:58:17 AM1/26/22
to ComputerWhiz, Chromium Extensions, salem...@gmail.com, wOxxOm, hrg...@gmail.com, avm99963
I remember someone saying that a disabled extension equals an uninstalled extension but keeping the storage. It is not exactly. I know there is at least one exception, if the extension created alarms, when re-enable this extension(even re-start browser) the alarms are still there, don't need to re-create when onEnabled/onStartup.

hrg...@gmail.com

unread,
Jan 26, 2022, 2:53:29 PM1/26/22
to Chromium Extensions, Jackie Han, Chromium Extensions, salem...@gmail.com, wOxxOm, hrg...@gmail.com, avm99963, ComputerWhiz

I remember someone saying that a disabled extension equals an uninstalled extension but keeping the storage. It is not exactly. I know there is at least one exception, if the extension created alarms, when re-enable this extension(even re-start browser) the alarms are still there, don't need to re-create when onEnabled/onStartup.

 I said that. Thanks for complementing the info.

To summarize, the following changes made by an extension persist when the extension is disabled.
  • chrome.alarms  
  • chrome.storage.local
  • window.localStorage
  • IndexedDB

If anyone knows of any other, please add it to the list.

Jackie Han

unread,
Jan 26, 2022, 3:30:19 PM1/26/22
to hrg...@gmail.com, Chromium Extensions, salem...@gmail.com, wOxxOm, avm99963, ComputerWhiz
chrome.storage, window.localStorage and IndexedDB
All of these can be classified as "storage". So another storage "Cache Storage"  is also persistent.

chrome.alarms' behavior, I guess related to its implementation, may be a bug but it is a useful good bug.

avm99963

unread,
Jan 27, 2022, 10:49:57 AM1/27/22
to Chromium Extensions, Jackie Han, Chromium Extensions, salem...@gmail.com, wOxxOm, avm99963, ComputerWhiz, hrg...@gmail.com
In my case I found it much simpler to create the alarm each time the service worker spins up if it doesn't exist yet (see this snippet).

hrg...@: add to that list chrome.storage.sync :)

hrg...@gmail.com

unread,
Jan 27, 2022, 11:06:00 AM1/27/22
to Chromium Extensions, avm99963, Jackie Han, Chromium Extensions, salem...@gmail.com, wOxxOm, ComputerWhiz, hrg...@gmail.com
 
hrg...@: add to that list chrome.storage.sync 

 The data in chrome.storage.sync is associated to a Google account, not to an extension. Disabling or uninstalling an extension has no effect on it, as that data is not retained by the browser.

Adrià Vilanova Martínez

unread,
Jan 27, 2022, 1:30:02 PM1/27/22
to hrg...@gmail.com, Chromium Extensions, Jackie Han, salem...@gmail.com, wOxxOm, ComputerWhiz
Only if the browser is being synced, otherwise it just behaves like chrome.storage.local. I was just being a little too picky ;)

hrg...@gmail.com

unread,
Jan 27, 2022, 1:43:57 PM1/27/22
to Chromium Extensions, avm99963, Chromium Extensions, Jackie Han, salem...@gmail.com, wOxxOm, ComputerWhiz, hrg...@gmail.com
You are right. chrome.storage.sync uses a local cache that is synced once there's connectivity (and if sync is enabled).
This cache is also retained when the extension is disabled.

Reply all
Reply to author
Forward
0 new messages