Skip to content
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

extension.getBackgroundPage, runtime.getBackgroundPage, and serviceWorkers #295

Closed
carlosjeurissen opened this issue Oct 17, 2022 · 16 comments
Labels
spec clarification Needs clarification when specified

Comments

@carlosjeurissen
Copy link
Contributor

carlosjeurissen commented Oct 17, 2022

Currently extensions have two ways of getting the globalThis / window object of background pages. Being the synchronousextension.getBackgroundPage and the asynchronous runtime.getBackgroundPage.

As mentioned by #170 (comment), there are use cases in which getting the window object of the background page can be useful.

With these APIs, there are a few things we need to discuss.

  1. First of all, do we want to keep supporting these APIs in general.
  2. extension.getBackgroundPage and runtime.getBackgroundPage do pretty much the same. It makes sense to deprecate and later on remove on of them.
  3. Do we want to support getting the globalThis of serviceWorker background scripts?
  4. Do we want to support getting the globalThis of limited event pages in mv3?
  5. Should we consider renaming the API to something like runtime.getBackgroundContext() to be more independent of the type of background scripting.

Some of these decisions can be different across browsers. You can imagine runtime.getBackgroundContext() to return a promise which rejects if a browser does not want to expose the globalThis object of background scripts.

@carlosjeurissen carlosjeurissen added spec clarification Needs clarification when specified agenda Discuss in future meetings labels Oct 17, 2022
@hanguokai
Copy link
Member

In my opinion:

extension.getBackgroundPage: it makes sense for the persistent background page in MV2.

runtime.getBackgroundPage: it makes sense for the event background page in MV2. The doc says "If the background page is an event page, the system will ensure it is loaded before calling the callback."

For service worker in MV3, I don't think it makes sense, since service worker has its own life cycle.

@muzuiget
Copy link

chrome.runtime.getBackgroundPage will throw an error on MV3 service worker.

So I think this API should remove from the MV3 document.

@tophf
Copy link

tophf commented Oct 18, 2022

First of all, do we want to keep supporting these APIs in general
Do we want to support getting the globalThis of #134 in mv3?

Yes. It allows instantaneous transfer of huge data, which even with deepCopy (to avoid "dead objects" in Firefox) is orders of magnitude faster than structuredClone + messaging. It also supports direct invocation of globally exposed functions/classes. Lots of extensions use this feature.

extension.getBackgroundPage and runtime.getBackgroundPage do pretty much the same. It makes sense to deprecate and later on remove one of them.

Both are necessary. The first one is synchronous, which is very important when doing the work before the next paint frame to avoid flicker. It can be used meaningfully with an event page as long as it's already started. The second one is asynchronous, it wakes up an event page if necessary and currently it takes at least one JS task even if the event page is already running, i.e. it always happens after the next paint frame. It means that in order for the async one to replace the sync one it must be able to resolve within the microtask phase of the current JS task in case the background page is already started.

I don't think renaming makes sense because 1) a limited event page is still a background page and 2) there's no way to get the context of a worker as it runs in a different physical thread - if this will ever change it'll be for the entire JS platform in the future like the Atomics thing or whatever.

@carlosjeurissen
Copy link
Contributor Author

Thanks all for the replies. Adding to this, seems extension.getBackgroundPage used to work in Safari 15 with serviceWorkers. The changelog of Safari 16 (https://developer.apple.com/documentation/safari-release-notes/safari-16-release-notes) mentions: "Service workers are no longer returned from extension.getBackgroundPage and extension.getViews.".

@xeenon
Copy link
Collaborator

xeenon commented Oct 24, 2022

Yes, it was a bug they were returned in Safari 15.4. It was fixed in Safari 16 to better match Chrome.

@xeenon
Copy link
Collaborator

xeenon commented Oct 24, 2022

I don't think it makes sense to support getting the globalThis of the service worker since multi-threading makes it likely unsafe to do so — the service worker is usually on a background thread, while page contexts are only main thread. (Except in Safari, the service worker is on the main thread too, but that is an implementation detail that could change.)

@xeenon
Copy link
Collaborator

xeenon commented Oct 24, 2022

I'm in favor of deprecating and eventually removing the getBackgroundPage and getViews APIs. This would allow extensions to use multiple processes and get better performance and crash isolation (if the popup view hangs or crashes it currently will block/crash the background page since they share a process for these APIs.)

@xeenon xeenon added the neutral: safari Not opposed or supportive from Safari label Oct 24, 2022
@tophf
Copy link

tophf commented Oct 24, 2022

This would allow extensions to use multiple processes

I doubt this happens in the next 20-30 years though. Same-origin documents always run in the same physical process for many reasons, but even if we disregard them all, the complexity of implementing such multi-process architecture for extensions would contradict the trend set in ManifestV3 which is to make extensions less powerful, less capable, less complicated internally, reuse the web platform more, including its restrictions.

@xeenon
Copy link
Collaborator

xeenon commented Oct 25, 2022

Same-origin documents always run in the same physical process for many reasons

Not in WebKit at least. It is process-per-view currently, unless there is a window opener relationship to the other page/view.

The web platform is deeply multi-process and async today. These are some of the only sync APIs in the extension platform, and they are holding it back.

@tophf
Copy link

tophf commented Oct 25, 2022

Huh, Safari is awesome :-) Indeed, I was thinking about the opener thing as the primary use case for synchronous access, so if we want to get rid of getBackgroundPage in the future it would make sense to provide an alternative opt-in for extensions, like the opener thing in the web platform.

@xeenon
Copy link
Collaborator

xeenon commented Oct 25, 2022

Under the hood Safari is just using the same window opener linking in WebKit to keep the each extension's pages in the same process. If these APIs went away, we could stop doing that and each extension page would get a separate process.

@tophf
Copy link

tophf commented Oct 25, 2022

Yeah, and I think extensions should be able to control this behavior via some mechanism similar to the opener.

@carlosjeurissen
Copy link
Contributor Author

The web platform is deeply multi-process and async today. These are some of the only sync APIs in the extension platform, and they are holding it back.

Under the hood Safari is just using the same window opener linking in WebKit to keep the each extension's pages in the same process. If these APIs went away, we could stop doing that and each extension page would get a separate process.

@xeenon would it make a difference between the async runtime.getBackgroundPage and the sync extension.getBackgroundPage?

@tophf can you elaborate a bit more on the imporance of extension.getBackgroundPage synchronous nature?

@tophf
Copy link

tophf commented Oct 26, 2022

I already outlined it in my comment above. There may be more use cases in the wild, of course.

Here's another/similar one: https://crbug.com/1165667

@xeenon
Copy link
Collaborator

xeenon commented Oct 27, 2022

@xeenon would it make a difference between the async runtime.getBackgroundPage and the sync extension.getBackgroundPage?

No, that still requires the pages to be in the same process since the JS window object needs to exist in the caller's process.

@xeenon xeenon added the next manifest version Consider for the next manifest version label Oct 27, 2022
@carlosjeurissen carlosjeurissen removed agenda Discuss in future meetings next manifest version Consider for the next manifest version neutral: safari Not opposed or supportive from Safari labels Oct 27, 2022
@carlosjeurissen
Copy link
Contributor Author

carlosjeurissen commented Oct 27, 2022

During the 2022-10-27 meeting it was concluded extension.getBackgroundPage, runtime.getBackgroundPage will not be supported in serviceWorkers due to the fact they run in different processes.

In addition, it was concluded both extension.getBackgroundPage and runtime.getBackgroundPage have their own use-cases and will both be kept for mv2 and mv3 if the browsers support a limited event page.

@dotproto volunteered to create a separate issue discussing if these two APIs will be kept in a future manifest version.

Since the issue does not have a clear direct proposal, I have removed the browser-specific support labels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
spec clarification Needs clarification when specified
Projects
None yet
Development

No branches or pull requests

5 participants