Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: Is there any way to detect when all async scripts have loaded?

If you use plain script tags on an HTML page, rendering is blocked until the script has been downloaded and parsed. To avoid that, for faster page display, you can add the 'async' attribute, which tells the browser to continue processing down the page without waiting for that script. However, that inherently means that other javascript that refers to anything in that script will probably crash, because the objects it requires don't exist yet.

As far as I know, there's no allScriptsLoaded event you can tie into, so I'm looking for ways to simulate one.

I'm aware of the following strategies to defer running other code until an async script is available:

  • For a single script, use their 'onload' event or attribute. However, there's no built-in way I know of to tell when ALL scripts have loaded if there's more than one.
  • Run all dependent code in onload event handlers attached to the window. However, those wait for all images too, not just all scripts, so the run later than would be ideal.
  • Use a loader library to load all scripts; those typically provide for a callback to run when everything has loaded. Downside (besides needing a library to do this, which has to load early), is that all code has to wrapped in a (typically anonymous) function that you pass into the loader library. That's as opposed to just creating a function that runs when my mythical allScriptsLoaded fires.

Am I missing something, or is that the state of the art?

like image 470
enigment Avatar asked Sep 03 '15 18:09

enigment


People also ask

Are all the JavaScript in a page loading asynchronously?

With async, external JavaScript files are downloaded asynchronously, allowing the parser to continue rendering the page. As soon as the download is finished, the browser runs the script.

Is script tag async by default?

Dynamic scripts behave as “async” by default. This can be changed if we explicitly set script. async=false . Then scripts will be executed in the document order, just like defer .

What is the purpose of async in this code script async src Myscript JS script?

The async attribute is a boolean attribute. When present, it specifies that the script will be executed asynchronously as soon as it is available. Note: The async attribute is only for external scripts (and should only be used if the src attribute is present).

How does async script tag work?

If the async attribute is set, the script is downloaded in parallel to parsing the page, and executed as soon as it is available. The parsing of the page is interrupted once the script is downloaded completely, and then the script is executed, before the parsing of the rest of the page continues.


1 Answers

The best you could hope for would be to know if there are any outstanding async calls (XMLHttpRequest, setTimeout, setInterval, SetImmediate, process.nextTick, Promise), and wait for there to not be one. However, that is an implementation detail that is lost to the underlying native code--javascript only has its own event loop, and async calls are passed off to the native code, if I understand it correctly. On top of that, you don't have access to the event loop. You can only insert, you can't read or control flow (unless you're in io.js and feeling frisky).

The way to simulate one would be to track your script calls yourself, and call after all script are complete. (i.e., track every time you insert a relevant script into the event loop.)

But yeah, the DOM doesn't provide a NoAsyncPending global or something, which is what you'd really require.

like image 66
Kyle Baker Avatar answered Nov 14 '22 22:11

Kyle Baker