Closed Bug 1506464 Opened 6 years ago Closed 6 years ago

browser.runtime.onInstalled does not fire for async scripts

Categories

(WebExtensions :: Untriaged, defect)

63 Branch
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED INVALID

People

(Reporter: 5i13ghzt462u, Assigned: robwu)

Details

User Agent: Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0 Steps to reproduce: 1. Create a new add-on. 2. Use a background.html. 3. Use the following HTML: <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <script src="./upgrade.js" charset="utf-8" defer></script> </head> <body> </body> </html> (The defer is the default I know, but it's just there to highlight it. We'll come back to it later.) 4. Create the mentioned ./upgrade.js and put the (nearly) official example from MDN in there (I've just commented out the cat gif part as it was annoying, the console is fine for seeing the result.): function handleInstalled(details) { console.error(details); // browser.tabs.create({ // url: "http://chilloutandwatchsomecatgifs.com/" // }); } browser.runtime.onInstalled.addListener(handleInstalled); 5. Verify everything works and the function is executed when you load the add-on via about:debugging. 6. Now change "defer" to "async" and try to verify it again as in step 5. Actual results: Now the function is not fired. They generally do not seem to get fired for async scripts. Also in modules, which you have to include with this background.html workaround (see https://bugzilla.mozilla.org/show_bug.cgi?id=1394303), they do not fire. Expected results: It should fire everywhere and always.
Product: Firefox → WebExtensions
Flags: needinfo?(rob)
The onInstalled event is fired when the background page is ready (at DOMContentLoaded). Therefore it is expected that scripts with the "defer" attribute can observe the event, but scripts with "async" cannot. If you want to catch the onInstalled event, use a script without the async attribute.
Assignee: nobody → rob
Status: UNCONFIRMED → RESOLVED
Closed: 6 years ago
Flags: needinfo?(rob)
Resolution: --- → INVALID

Sorry for the late reply, but this still does not make sense to me.
AFAIK the order in which the events/things happen is this:
async scripts start running -> DOMContentLoaded + onInstalled -> deferred script start

So if I add an onInstalled listener in my async script to wait for the event, then I am just faster than any deferred scripts and it should actually be the same as if I load my own script later.

Actually, it would make more sense to me when the deferred could have problems, because DOMContentLoaded and thus onInstalled fires before they get started, but apparently they don't have.

Flags: needinfo?(rob)

I think that you've either mixed up the meaning of async or defer, or don't understand what these do.

From MDN: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script

async For classic scripts, if the async attribute is present, then the classic script will be fetched in parallel to parsing and evaluated as soon as it is available.
defer This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded.

In other words, defer is guaranteed to run before DOMContentLoaded, whereas async is run "as soon as it is available", which may be before DOMContentLoaded, but potentially also afterwards.

You can easily test the expected behavior by loading scripts with and without defer / async, and delaying the completion of the requests for script/HTML.

  • Load order = defer, async, HTML gives execution order = async, defer, DOMContentLoaded.
  • Load order = async, defer, HTML gives execution order = async, defer, DOMContentLoaded.
  • Load order = HTML, async, defer gives execution order = async, defer, DOMContentLoaded.
  • Load order = HTML, defer, async gives execution order = defer, DOMContentLoaded, async.

Results obtained in Firefox Nightly 76.0a1 buildID 20200319193622, with nc (netcat) to manually control the order of responses.

Flags: needinfo?(rob)

Okay thanks for the detailed answer, so it is indeed "just" that async may (in, I guess, really not many cases though) run later than defer. That makes sense though, as "unintuitive" this behaviour seems to me, anyway.

You need to log in before you can comment on or make changes to this bug.