<script src="..."></script> : the browser must wait for the script to download and complete its execution before continuing to process the rest of the page.
This leads to two important problems:
- Scripts cannot access DOM elements below them, scripts cannot add handlers to them, etc.
- If there is a clunky script at the top of the page, it “blocks the page”. The user cannot see the content of the page until the script is downloaded and executed.
That’s not a big deal for people using high-speed connections, who won’t experience this lag. But there are still many parts of the world where people use slow networks, especially mobile networks in some areas.
Fortunately, there are
<script> features that can solve this problem.
<!doctype html> <body> <p>...content before script...</p> <script defer src="https://zhanzhbkzzz.com/test.js"></script> <!-- The following is immediately visible --> <p>...The defer application example...</p> </body>
in other words:
deferScripts with features do not block the page.
- Scripts with
deferproperties always wait until the DOM has been parsed, but are
DOMContentLoadedexecuted before events.
The following example will explain what the second sentence means:
<p>...content before scripts...</p> <script> document.addEventListener('DOMContentLoaded', () => alert("DOM ready after defer!")); </script> <script defer src="https://bkzzz.com/test.js"></script> <p>...The contents of the script are immediately displayed...</p>
- The page content is displayed immediately.
DOMContentLoadedThe event handler waits for
deferthe script with the attribute to finish executing. It will only be triggered after the script is downloaded and its execution has ended.
defer attributes maintain their relative order, just like regular scripts.
Suppose, we have two
defer scripts with characteristics:
test1.js before and
<script defer src="https://bkzzz.com/test1.js"></script> <script defer src="https://bkzzz.com/test2.js"></script>
The browser scans the page for scripts and downloads them in parallel to improve performance. So in the example above, the two scripts are downloaded in parallel.
test2.js may be downloaded first.
defer addition to telling the browser “don’t block the page”, features also ensure the relative order of script execution. Even if
test2.js it is loaded first, it
test1.js will not be executed until the end of execution.
defer Features are only available for external scripts . If the
<script> script doesn’t
src, the attribute is ignored
defer and has no effect for inline scripts.
async Features are
defer somewhat similar. It also enables scripts not to block the page. However, there are important differences in behavior.
async Features mean that scripts are completely self-contained:
- Browsers don’t
asyncblock with scripts (and
- Other scripts don’t wait for
asyncscripts to load to finish, and similarly,
asyncscripts don’t wait for other scripts.
DOMContentLoadedand async scripts don’t wait for each other:
DOMContentLoadedMay happen before the async script (if the async script doesn’t load until the page is done)
DOMContentLoadedCan also happen after an async script (if the async script is short, or loaded from the HTTP cache)
In other words, the
async script loads in the background and runs when it is ready. The DOM and other scripts don’t wait for them, and they don’t wait for anything else.
async A script is a completely separate script that is executed when the load is complete.
async will not execute in script order, whoever loads first will execute it first.
Loading asynchronously is great when we’re integrating independent third-party scripts into the page: counters, ads, etc., because they don’t depend on our script, and our script shouldn’t wait for them:
<!-- Google Analytics Scripts are typically embedded in pages like this --> <script async src="https://google-analytics.com/analytics.js"></script>
defer have one thing in common: loading such a script will not block the rendering of the page. Therefore, users can immediately read and understand the page content.
However, there are also some essential differences between them:
|Load priority order . The order of scripts in the document does not matter – the ones loaded first are executed first||irrelevant. Possibly loaded and executed before the document is loaded. This can happen if the script is small or from a cache and the document is long enough.|
|Document order (their order in the document)||Executed after the document has been loaded and parsed (and waited if needed), i.e. |
In actual development,
defer used for scripts that require the entire DOM, and/or when the relative execution order of scripts is important.
async For stand-alone scripts, such as counters or advertisements, where the relative execution order of these scripts does not matter.