MV3 message passing is significantly slower than MV2

555 views
Skip to first unread message

Thien Hoang

unread,
Jun 26, 2025, 10:51:49 AM6/26/25
to Chromium Extensions
Hello,

Our MV3 extension is currently using `chrome.tabs.sendMessage` to send messages from service worker to content script and `chrome.runtime.sendMessage` to send messages from content script to service worker. This works fine on Mac and high-end Windows computers, but when running on a low-end Windows computer, it is 10 times slower compared to MV2 for a message to go from one end to the other, even there is only one tab open.

Not just message passing, reading from IndexedDB is also significantly slower. Is there something about Service Worker that makes its execution lower priority or throttled?

Any leads will be appreciated.
Thien

woxxom

unread,
Jun 27, 2025, 2:56:18 AM6/27/25
to Chromium Extensions, Thien Hoang
Maybe your measurement includes the time to start the service worker (at least 50ms) while your MV2 background script was persistent? Otherwise it sounds like a bug, because the internal implementation of messaging should be the same.

Thien Hoang

unread,
Jun 27, 2025, 9:51:17 AM6/27/25
to Chromium Extensions, woxxom, Thien Hoang
The service worker is active the whole time, it just takes a lot of time for the Service Worker to do anything.

It's probably worth to mention that in my testing, I open 10 new tabs at the same time and Content Script is injected to each tab using `chrome.scripting.executeScript`. In this scenario, the MV3 extension not only runs slower, the page load is also slower. It feels as if the Service Worker ran on the same thread that handles page load, and when too much is going on, everything is slowed down; whereas in MV2 the background script ran more independently.

My initial post was about message passing, but there seems to be some fundamental problem that affects the overall performance. For example, the `chrome.webNavigation.onCompleted` event in MV2 is fired as soon as any tab finishes loading, in MV3 it is only fired when all tabs finish loading. I've switched to `chrome.webNavigation.onDOMContentLoaded` and the event is fired earlier now, but the loading time for all tabs is still much slower when the MV3 extension is running.

I'll update when I find more. Your insights are much appreciated in the meantime.

Thien

Oliver Dunk

unread,
Jun 27, 2025, 9:55:26 AM6/27/25
to Thien Hoang, Chromium Extensions, woxxom
Hi Thien,

Would you be able to share some specific numbers, in particular how long you are seeing `chrome.runtime.sendMessage` from a content script take when the service worker is already started?

It is hard without that to know if this is expected behavior or not, since of course it is not expected to be instant but it should be very fast.
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB


--
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 visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/74b97df5-fd33-46df-a288-205bd4fac6b9n%40chromium.org.
Message has been deleted
Message has been deleted

Thien Hoang

unread,
Jun 27, 2025, 11:04:33 AM6/27/25
to Chromium Extensions, Oliver Dunk, Chromium Extensions, woxxom, Thien Hoang
Hi Oliver,

In the testing below, only one tab is open, the content script from this tab sends 9 messages to service worker, asking the service worker to look up some keys in the Indexed DB (100 keys in total). The left console is content script, the right console is service worker. I'm simply measuring the time between the first message sent from Content Script and the last message received by Service Worker.

In MV2, this takes 225 ms.

SCR-20250627-opdj.png

In MV3, this takes 7483 ms.

SCR-20250627-opzu.png

I'm just opening one tab in this case for a clearer demonstration, this number gets much higher when more tabs are loading.

Thien

Message has been deleted

Thien Hoang

unread,
Jul 29, 2025, 12:00:25 PM7/29/25
to Chromium Extensions, Thien Hoang, Oliver Dunk, Chromium Extensions, woxxom
Apparently, moving content script from dynamic to static improved a lot. There was this function called "updateContentScript" found in DevTools Performance tab of service worker, which I assume is Chrome-internal because we don't have anything like that in our code; it kept running every time we did any operation in our extension. I supposed that if I switched to static content script, such calls wouldn't be necessary anymore, so I did, and it disappeared, messages got faster for single-tab test case.

However, if I load multiple tabs (6-7) at the same time, messages are still significantly delayed on both service worker and content script, service worker got slowed down significantly (promises take longer to resolve, read operations in IndexedDB became slower). When all tabs finish loading, the speed becomes normal again.

Simply put, I imagine that the MV3 service worker gets much less resource and priority (compared to MV2 background script), therefore all operations just take much more time. The effect gets worse when many tabs are loading. Although I can't find this issue documented anywhere, all testing results and feedback from our users showed a major slowdown after moving to MV3.

Can someone confirm my hypothesis above?

Oliver Dunk

unread,
Aug 4, 2025, 11:08:09 AM8/4/25
to Thien Hoang, Chromium Extensions, woxxom
Hi Thien,

Thanks for sharing the numbers (and sorry for the delayed response). Those are definitely interesting findings.

Apparently, moving content script from dynamic to static improved a lot. There was this function called "updateContentScript" found in DevTools Performance tab of service worker, which I assume is Chrome-internal because we don't have anything like that in our code; it kept running every time we did any operation in our extension.

Is your extension live on the store, or would you be able to share a simpler reproduction? I'm not aware of a function like that so I would be interested to look more closely. 

Simply put, I imagine that the MV3 service worker gets much less resource and priority (compared to MV2 background script), therefore all operations just take much more time. The effect gets worse when many tabs are loading. Although I can't find this issue documented anywhere, all testing results and feedback from our users showed a major slowdown after moving to MV3.

This is definitely not the intention, and what you are seeing is out of the ordinary.
Oliver Dunk | DevRel, Chrome Extensions | https://developer.chrome.com/ | London, GB

bruce

unread,
Aug 9, 2025, 11:41:27 AM8/9/25
to Chromium Extensions, Oliver Dunk, Chromium Extensions, woxxom, Thien Hoang
Related I believe: 

I have noticed that with MV3, too much message passing can lock Chrome. I was debugging some ephemeral scripts, so had them send data to the service worker console instead, and if I accidentally enabled this in too many functions, it would not just brick the extension, but Chrome. 

No clicks, no menus, no buttons response. All windows. Cannot even close Chrome. Only force kill. Also for my discovery case it was trickier to recover because I had debug set to resume on launch :(  

Seems a bit like a novel attack vector :)

Thien Hoang

unread,
Aug 11, 2025, 8:14:33 AM8/11/25
to Chromium Extensions, bruce, Oliver Dunk, Chromium Extensions, woxxom, Thien Hoang
Hi Oliver,

Our extension is unlisted and used in enterprise mode. I don't have a simpler extension to demonstrate the issue for now.

To clarify the slowness after switching to MV3: we noticed that in MV2, when we focus on a tab, the messages to/from that tab are passed much quicker. In MV3, no matter which tab is focused, messages are not passed until almost all tabs have finished loading. Is this expected?

On this topic, we also have this annoying problem where occasionally the content script and the service worker just couldn't pass messages to each other anymore. I'm not sure how this could happen in the first place and how to recover from this (other than refreshing the page).

image (12).png

I'll try to switch to port messaging to see if the messages are passed more quickly.

Thien
Message has been deleted

Peter Bloomfield

unread,
Aug 14, 2025, 12:36:21 PM8/14/25
to Chromium Extensions, Thien Hoang, bruce, Oliver Dunk, Chromium Extensions, woxxom
We've always found that the extensions we develop tend to run slower in mv3 than they did in mv2, sometimes by a significant amount. It's not just message passing, storage operations, or other calls into the extension API. It affects everything, including in-memory data processing. For example, you can write the simplest possible extension which just does some calculations and transformations on a big array, and measures the elapsed time using a high precision timer. Make it functionally identical between mv2 and mv3, and try running both several times in exactly the same environment. The times from mv3 are typically worse.

The difference isn't usually very significant on computers with a decent hardware specification. It becomes much more noticeable on lower-spec devices, such as those used by schools, which are our main customers. When the system is under load, the performance of an mv3 extension seems to degrade more than mv2. My guess is that the browser prioritises the performance of web-pages (including mv2 background pages) over the performance of other background tasks like service workers (including mv3 extensions).

The performance problems are particularly noticeable in our web filter extension as it uses the web request blocking API (onBeforeRequest). The nature of that API means the browser has to wait for a synchronous response from our event handler for every single web request. That means if our extension is running slowly then all browsing activity goes slowly as well. I wonder whether there's a feedback loop going on. Perhaps the browser detects that user-facing browsing activity is going slowly, and tries to compensate for it by throttling down the service worker. In our case, that actually makes the problem worse.
Message has been deleted

kg_17

unread,
Aug 15, 2025, 5:21:14 PM8/15/25
to Chromium Extensions, Peter Bloomfield, Thien Hoang, bruce, Oliver Dunk, Chromium Extensions, woxxom
Peter,

Just in case you are unaware, MV3 extension background service workers are placed in efficiency mode in Windows by default ( https://issuetracker.google.com/issues/367755343 ).  MV2 extensions were not placed in efficiency mode.  This is one reason why MV3 extensions perform slower in some cases.  
Reply all
Reply to author
Forward
0 new messages