Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

218
Views
How to guarantee that deferred JS scripts have executed?

On my website I use javascript modules, which according to MDN are deferred by default. I have some additional javascript which can only safely execute once these modules have loaded and executed. MDN indicates here that deferred script execution is guaranteed to have occurred by the time the DOMContentLoaded event has fired. Further, it is suggested here that you can also account for the case where this event has already fired like so:

function doSomething() {
  console.info('DOM loaded');
}

if (document.readyState === 'loading') {  // Loading hasn't finished yet
  document.addEventListener('DOMContentLoaded', doSomething);
} else {  // `DOMContentLoaded` has already fired
  doSomething();
}

The block above seems to be what I'm looking for. But documentation elsewhere on MDN leaves me unsure as to whether this is really correct. For instance, why does the readystate check above look for loading rather than loading OR interactive? The documentation on readystate says that loading is followed by interactive, and that in the interactive state " sub-resources such as scripts, images, stylesheets and frames are still loading."

So it seems to me that there is an inconsistency here. Either the suggested readystate check is not sufficient to guarantee that DOMContentLoaded has fired, or DOMContentLoaded is not sufficient to guarantee that deferred scripts have completed.

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

When readyState is at least interactive, that means that the document has been fully parsed, and that all the elements in the source HTML now exist in the DOM.

Usually, people implementing this solution are doing so because they're trying to attach listeners to elements, and need to wait for all elements to exist in the DOM - and so all they need to do is check document.readyState === 'loading'.

If you also want to wait for <script type="module"> scripts to run, that's a different problem, with a different solution.

The best way by far would be to have a single entry point for your app's in a module, so that you don't have to worry about loading order at all - it'll just work.

If you really have to determine when all module scripts have run from a non-module script (which I wouldn't recommend), you'd have to iterate over them and listen to their load events.

// run this at the end of the body -
// once all script tags exist, but before they've run
Promise.all(
  [...document.querySelectorAll('script[type="module"]')]
    .map(script => new Promise(
      resolve => script.addEventListener('load', resolve)
    ))
)
  .then(() => {
    // all module scripts are loaded
   })

But that's quite convoluted and probably isn't a good approach.

If you listen to the load event for the window instead, you'll also be waiting for all other resources to load as well (images and stylesheets and such) which isn't desirable.

about 4 years ago · Juan Pablo Isaza Report

0

 import "other-module";
 // module is guaranteed to be loaded here

By importing the module one can guarantee that it is loaded before the module the import is in runs.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!