-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A multi-tab broadcast version of chrome.tabs.sendMessage #722
Comments
I would be in favor of a |
This is the primary goal. Serialization cost can be disproportionally exorbitant.
That would correspond to the implied meaning of "broadcast", but it would also reduce usability of this API. An unreliable workaround would be for the content script to send a new message with some kind of I see two solutions:
|
See https://github.com/w3c/webextensions/blob/main/_minutes/2024-11-21-wecg.md (merged from #726) for the discussion during today's meeting. At the start of the meeting I noted that I'd like to avoid broadcast semantics to enable optimizations, that refers to the discussion in #293, specifically #293 (comment). I can also see some use cases for intentional broadcast semantics, and am willing to consider supporting that. For use cases that really need broadcast semantics, broadcasting once is more efficient than JS->internal serialization followed by IPC (which also incurs serialization) and dispatch overhead. IMO the default behavior should be to not have responses. The reason for that is that maintaining responses in a general way is very expensive: the browser's main process has to wait for all content processes to respond before returning to the extension. And each content process would have to maintain internal state to keep alive the broadcast message until the extension contexts within have responded (asynchronously). This is what we already do with runtime.onMessage, and expensive. If you have compelling use cases for needing response support, please state them. |
The use case is to ensure that all tabs got the data. See my comment above where I described why the workaround is problematic and suggested two solutions:
The key aspect of the proposal is not broadcasting per se, but having a version of Promise.all + chrome.tabs.query + chrome.tabs.sendMessage that removes the redundant serialization/IPC while retaining the ability to track the overall result. Your idea is essentially a huge step further. It is certainly useful in some cases, so maybe it would make sense to add both chrome.tabs.broadcast (ideally with onBroadcastResponse event) and chrome.tabs.sendMessageToTabs. |
Just a nit: Does this have to be a dedicated method with custom behavior?
Why not just extend sendMessage() to accept While I agree that there could be better APIs for this, I don't think they're strictly related to multi-tab broadcasts (i.e. if you want to introduce a better messaging API, it could apply to tabs and runtime too) FWIW |
These are my reasons for a dedicated method:
|
We've implemented our own awaitable broadcast wrapper/behavior in PixieBrix. We've seen most usage for compliance/governance/auditing use cases. For example:
We currently warn if a message is being broadcast to more than 20 tabs (we picked the number as a heuristic based on observation 2+ years ago) Sometimes we can determine via querying URLs, but often for SPAs you have to check the actual content of the page. Prior to MV3 we also relied on retrieving information across tabs via broadcast. But since then, session storage has become the most effective/performant way to share data across tabs on an ongoing basis |
The problem I'm solving is efficiency when sending the same message to a lot of tabs as the extension may lock up the background script for many seconds and won't be able to process user activity during that time.
+ API roundtrip
Workarounds?
The extension can throttle the process by issuing 1-10 requests in one JS event loop task, but how many extension authors would bother? I'd say less than 1%. Anyway, it won't eliminate the redundancy of the entire process (serializing + sending the data to the browser process which handles the extension API).
Broadcasting a Blob (in Firefox) or Blob URL (in Chrome) and fetching it in the recipient would still need the redundant calls to the sendMessage API, which will take at least 1ms and even that is problematic when there are many tabs, see the table above.
This is a problem that should be solved at the platform level.
Something like this:
The result may be an array with one element per tab from the first frame to respond (similarly to chrome.tabs.sendMessage):
A weaker solution would be to accept an array of tabIds in the existing
chrome.tabs.sendMessage([1,2,3], message, options)
, but it would limitoptions.frameId
to just0
or null/undefined/unspecified and it would change the result to an array, which is not how the API works currently (the type of the result doesn't change depending on the argument).The text was updated successfully, but these errors were encountered: