MV3: Failed to send SharedArrayBuffer to Offscreen Document

319 views
Skip to first unread message

Svyatoslav Alekseev

unread,
Mar 19, 2025, 10:41:15 AM3/19/25
to Chromium Extensions
In Chrome Extensions v3, the object pointing to SAB comes empty or does not come at all (invisible error). In MV2, everything worked with specified CORS between the background page and workers. Is there a working way to share raw binary data buffer between service_worker and chrome.offscreen?
---------------------
manifest.json:
----
{"name":"SharedArrayBuffer",
"short_name":"SAB",
"version": "3.0.0.0",
"manifest_version":3,
"cross_origin_embedder_policy":{"value": "require-corp"},
"cross_origin_opener_policy":{"value": "same-origin"},
"minimum_chrome_version":"120.0",
"background": {"service_worker": "sw.js"},
"permissions":["offscreen"],
"host_permissions":["<all_urls>"]
}
------------------
sw.js
----
chrome.offscreen.createDocument({url:chrome.runtime.getURL('offscreen.html'),reasons: ['WORKERS'],justification:'wtf',});
const BT=new BroadcastChannel('BT');BT.onmessage=e=>{console.log(e.data)}
chrome.runtime.onMessage.addListener((m)=>{console.log(m)});
async function MC(){
const mc=new MessageChannel();doc=(await clients.matchAll({includeUncontrolled:true})).find(c=>c.url.endsWith('/offscreen.html'));
doc.postMessage('ping',[mc.port2]);
mc.port1.onmessage=e=>{console.log(e.data)}
}
setTimeout(MC,99);

--------------
offscreen.html
---
<!DOCTYPE HTML>
<html><head><meta charset=utf-8><title></title><script src=offscreen.js></script></head></html>
------------------
offscreen.js
---
console.log(crossOriginIsolated);
const SAB=new SharedArrayBuffer(12),U32A=new Uint32Array(SAB),BT=new BroadcastChannel('BT');
BT.postMessage('TEST0');BT.postMessage(SAB);
chrome.runtime.sendMessage('TEST1');chrome.runtime.sendMessage(SAB);
navigator.serviceWorker.onmessage=e=>{
e.ports[0].postMessage('TEST2');e.ports[0].postMessage(SAB);
}

woxxom

unread,
Mar 19, 2025, 8:53:08 PM3/19/25
to Chromium Extensions, Svyatoslav Alekseev
99ms may be insufficient, instead you should "await" on createDocument, see also a complete example for Blob in https://stackoverflow.com/a/77427098

Svyatoslav Alekseev

unread,
Mar 22, 2025, 6:32:40 AM3/22/25
to Chromium Extensions, woxxom
I added the line to my example
const blob = new Blob(['foo']);e.ports[0].postMessage(blob); as linked in your example.
Passing Blob works, SharedArrayBuffer does not. Apparently it is impossible to pass SAB between backgound and offscreen. But after many years of such answers, no one has yet received an answer with a working example or from the development team. I just need to know, if it is impossible, then I will accept the fact that I will have to rework the MV2 extension for MV3 for a few more months, it is a trifle compared to the 10 months I have already spent. Is it possible to tag or invite the programmer responsible for this functionality to the conversation?

четверг, 20 марта 2025 г. в 03:53:08 UTC+3, woxxom:

Svyatoslav Alekseev

unread,
Mar 22, 2025, 8:24:46 AM3/22/25
to Chromium Extensions, woxxom
A reward of $100 USA (most likely in crypto) to the first (before the end of the month) to write a working example of an extension with SAB transfer for general use between servise_worker and offscreen document. Should not violate Chrome Web Store rules and not sandbox, tab parsing API should work.
Publish the code here, to receive the reward write to svyatal...@gmail.com

суббота, 22 марта 2025 г. в 13:32:40 UTC+3, Svyatoslav Alekseev:

Svyatoslav Alekseev

unread,
Mar 22, 2025, 8:27:33 AM3/22/25
to Chromium Extensions, Svyatoslav Alekseev, woxxom
svyataleseev88 @ gmail.com

суббота, 22 марта 2025 г. в 15:24:46 UTC+3, Svyatoslav Alekseev:

Mythical 5th

unread,
Mar 22, 2025, 11:30:43 AM3/22/25
to Chromium Extensions, Svyatoslav Alekseev, woxxom
The docs state that sendMessage() lets you send a one-time JSON-serializable message. It can't even send a true Date object, so it's not a surprise to see it not send your SAB.

Since you'd not included runtime.connect() in your code example I tried that and got the same result. However, it does send the Uint32Array (serialized), and is designed to be used as "a reusable long-lived message passing channel," so it might work for you and be the least bad option.



offscreen:
const SAB = new SharedArrayBuffer(12),
  U32A = new Uint32Array(SAB);

console.log("sab", SAB, "u32a", U32A);

chrome.runtime.onConnect.addListener(port =>
{
  port.postMessage({a: SAB, b: new Date(), c: U32A});
});


sw:
chrome.offscreen.createDocument({
  url: chrome.runtime.getURL('offscreen.html'),
  reasons: ['WORKERS'],
  justification: 'wtf'
}, () =>
{
  const messagePort = chrome.runtime.connect();
  messagePort.onMessage.addListener(msg =>
  {
    console.log("msg", msg)
  });
});

al

unread,
Mar 22, 2025, 12:14:20 PM3/22/25
to Chromium Extensions, Mythical 5th, Svyatoslav Alekseev, woxxom

In addition to what Mythical 5th said about serialization, if I were you, I would assume it's not supported. 
Looking at the short doc, the bottom section seems to indicate that crossOriginIsolation isn't fully implemented in Service Workers. 
The bug tracker it links is labelled as fixed, but it looks like some commenters don't believe it is. There are also some emails of the devs that worked on that issue (do what you will with that info, I wouldn't myself).

Regardless, it doesn't seem like an Extension service worker can be crossOrigin isolated, given, even with the manifest keys present, it still returns false when checking. 
Meaning, even if your Offscreen doc is isolated (which, with the keys present, it is), so long as the SW isn't, you can't share the SAB, using something like postMessage.

Since an MV2 Background Page is just that, a page, rather than an SW, it works fine. 

That's what I got from gleaming MDN and Chrome dev docs anyway. As I said up top, I'd just assume it's not supported, at least unless the DevRel folk say otherwise.

Svyatoslav Alekseev

unread,
Mar 22, 2025, 12:48:57 PM3/22/25
to Chromium Extensions, Mythical 5th, Svyatoslav Alekseev, woxxom
Unfortunately, SAB is required to pause the Worker (opened via offscreen) that is busy with continuous calculations, because service_worker and offscreen-worker are working on stages of one task and the costs (timer pause) for listening and sending messages will take 30% of the speed. Continuous calculations cannot even be paused without SAB. Only SharredArrayBuffer can be used as a simple if() (with a value from another thread) for continuous calculations. I just can't believe that MV3 developers forgot about 8 years of parallelism, but I can already guess, because offscreen works on the same core with the background script. At the same time, SAB works in offscreen and its Worker, but I have a huge array in memory stored in service_worker that is needed for the tabs API to work and again a stalemate (like in chess). $100 is still waiting for its hero.
суббота, 22 марта 2025 г. в 18:30:43 UTC+3, Mythical 5th:

Svyatoslav Alekseev

unread,
Mar 22, 2025, 12:55:35 PM3/22/25
to Chromium Extensions, al, Mythical 5th, Svyatoslav Alekseev, woxxom
You have confirmed my fears even more. The MV3 developers have abandoned 8 years of concurrency gains. However, I have noticed that SAB works in offscreen and the Workers it spawned. I would have liked to have known this 10 months ago when I started migrating to MV3. Now I have a huge amount of work to redo. $100 is still waiting for its hero, but after your reply I am almost certain there is no solution.
суббота, 22 марта 2025 г. в 19:14:20 UTC+3, al:

woxxom

unread,
Mar 22, 2025, 6:50:44 PM3/22/25
to Chromium Extensions, Svyatoslav Alekseev, al, Mythical 5th, woxxom
> sendMessage() lets you send a one-time JSON-serializable message. It can't even send a true Date object, so it's not a surprise to see it not send your SAB.

This has nothing to do with the problem, because the author uses Web platform messaging, which supports SAB.
The problem is either a bug in Chrome or an intended requirement to enable COOP/COEP, which can be done in manifest.json if I remember correctly, try googling.

Mythical 5th

unread,
Mar 23, 2025, 8:19:06 AM3/23/25
to Chromium Extensions, woxxom, Svyatoslav Alekseev, al, Mythical 5th
He tried sendMessage
chrome.runtime.sendMessage('TEST1');chrome.runtime.sendMessage(SAB);

Message has been deleted

Svyatoslav Alekseev

unread,
Mar 27, 2025, 11:02:11 AM3/27/25
to Chromium Extensions
I created a regression report:
https://issues.chromium.org/issues/406662639
воскресенье, 23 марта 2025 г. в 15:19:06 UTC+3, Mythical 5th:

woxxom

unread,
Mar 27, 2025, 10:57:00 PM3/27/25
to Chromium Extensions, Svyatoslav Alekseev
Looks like it was closed by accident by some random chromium developer. If it's not re-opened in a couple of days, consider making a new report and attach  your extension in a zip file, not as text.

al

unread,
6:45 AM (6 hours ago) 6:45 AM
to Chromium Extensions
Hoping to seek advice from Google folk - any work or plans to do so, happening in this area?
Similar to the author, I'd like to use SABs and messaging between my SW and whatever other context that's appropriate to facilitate the transfer of large swaths of binary data. 

For instance, transferring a tabCapture (ordinary weight @ ~700KB) takes ~250ms. Those numbers will vary of course, but I'd naively think that postMessage + SAB would be a lot quicker.
Even with unpacking the dataURL, etc, etc.

So specifically, enabling postMessage transfer to/from the SW.
And (my additional q) if it'll be transferrable to/from an isolated content script environment.

Oliver Dunk

unread,
6:54 AM (6 hours ago) 6:54 AM
to al, Chromium Extensions
I'm not sure why this was closed - I've moved it to an extensions component and re-opened it.

Given the limited activity on this one I'm not sure it is something we will prioritize soon. That said, we are interested in improving extension messaging in general, for example supporting structured clone and eventually maybe even transferables (though how to do this is less clear) in the extension messaging APIs. That may be another solution to your use case. I don't have a timeline for that, but with the other changes we have been focused on about to ship it may be something we can start to make early related changes for.
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/f5d7d8c1-161b-49db-820a-e9a59450b37en%40chromium.org.

al

unread,
7:03 AM (6 hours ago) 7:03 AM
to Chromium Extensions, Oliver Dunk, Chromium Extensions, al
Thanks Oliver. 

Definitely looking forward to those changes, and I saw the structure clone discussion which is certainly promising as well.

Thanks for the update. 

woxxom

unread,
9:40 AM (3 hours ago) 9:40 AM
to Chromium Extensions, al, Oliver Dunk, Chromium Extensions
Until SAB is fixed you can already use the web platform messaging via navigator.serviceWorker and Blob which being a handle is sent instantly. Accessing the actual data would take time of course but it'll still be like 10x faster than the current JSON-based extension messaging anyway.
Reply all
Reply to author
Forward
0 new messages