Here's the thing, the main concern at this time is to ensure the content script in the MAIN world can be present before any other code runs in the page, so definitely at document_start.
As for the async storage environment, I understand there is currently no way around it in MV3, nor any intention of changing that any time soon.
For this reason I would be OK with working around the limitation by ensuring the MAIN world script has all the barebones logic to intercept everything it MIGHT need, pending dynamic settings/instructions that are received shortly after asynchronously, as long as it won't be too late.
One example of an extremely important use case in favor of the ability to pass dynamic content with static script is to pass a secret key to the script that will run in the MAIN world, which is then used to validate communications with the ISOLATED content script and/or service worker.
On one hand, I could easily just inject the content script in MAIN world, signal the ISOLATED script (or service worker) the script is ready, then send the information that it needs back. On the other hand, at that time it is already so late that most time sensitive features lost their ability to intercept any primary code events in time.
I am quite surprised that this already exists for executeScript (args parameter), but it was never implemented for registerContentScripts.
The proposed workaround that requires enabling developer mode is simply not acceptable because this is not a personal use extension. I have recently resume work on an extension on Firefox, and I am trying to find out if it can be ported to Chrome again:
Although I've been successful in dropping the requirement for the deprecated webRequestBlocking in Chrome MV3 within my current extension code (all of it is in my local dev env, not online), I am now struggling with making something as simple as injecting the content script in the web page with dynamic data work.
I definitely require MAIN world for this extension to work, but I also require it to be able to read extension dynamic data in a time sensitive matter since most features depend on intercepting and modifying page content (dom, code) at early stages.
Another way I explored to work around all of these limitations was to 2 the injection in 2 stages:
- First stage: Immediately inject the static code at document_start (this can even be done by the manifest rules instead of using
registerContentScripts)
- Second stage: The service worker obtains the dynamic data (user settings, etc.) and then sends it to the page using
executeScript, OR, with an ISOLATED content script, do something similar but using events to pass the data instead of
executeScript, which a content script does not have access to if I understand correctly.
However, in any of these workarounds I am always sacrificing a secret key, so any communications between host-privileged host would be open to interception. Although the risk of that happening from the target webpage is pretty much none, the concern is with any other extensions that might be running on the user's page.