14.2 defer and async Attributes: Concept and Basic Use
When you include external JavaScript via the <script> tag, by default the browser stops parsing HTML until the script is fetched and executed. This blocking behavior can hurt performance. The defer and async attributes on <script> tags allow scripts to load without blocking HTML parsing, improving page load speed and user experience.
1. Default Script Loading Behavior
- Browser parses HTML sequentially.
- Upon encountering
<script src='…'>, parsing pauses. - Script is fetched, compiled, and executed immediately.
- After execution, HTML parsing resumes.
2. The async Attribute
Adding async tells the browser to download the script file in parallel with HTML parsing. Once downloaded, the script is executed immediately, potentially before HTML parsing is complete.
Characteristics:
- Downloads in parallel.
- Executes as soon as ready (order among multiple async scripts is not guaranteed).
- May interrupt HTML parsing when execution begins.
Basic example:
<section> <!-- HTML is still being parsed while script downloads --> <script src='analytics.js' async></script> <p>Content visible while analytics.js loads.</p> </section>
3. The defer Attribute
Adding defer also downloads the script in parallel, but delays execution until after the entire HTML document is parsed. This ensures scripts run in the order they appear and after parsing finishes.
Characteristics:
- Downloads in parallel.
- Executes in document order.
- Executes only after HTML parsing completes (
DOMContentLoadedfires after deferred scripts run).
Basic example:
<section> <!-- HTML parsing continues while scripts download --> <script src='utils.js' defer></script> <script src='main.js' defer></script> <div>Page content</div> </section>
4. defer vs async: Side-by-Side Comparison
| Feature | async | defer |
|---|---|---|
| Download | Parallel with HTML | Parallel with HTML |
| Execution timing | Immediately when ready | After HTML parsing |
| Execution order | Unpredictable | Guaranteed order |
| Blocking | Blocks when executed | Non-blocking until after parse |
| Use case | Independent scripts (analytics, ads) | Scripts depending on DOM or order |
5. When to Use Which?
- Use
asyncfor third-party scripts that don’t depend on others (analytics, A/B testing, ads). - Use
deferfor your own scripts that may depend on DOM structure or on each other (UI initialization, libraries). - If script must run immediately as soon as fetched and doesn’t touch DOM,
asyncis fine.
6. Deep Details and Best Practices
- Only external scripts (
src='…') support these attributes; inline scripts ignore them. - If both attributes are present,
asynctakes precedence overdefer. deferscripts are executed in the order they appear, even if later downloads finish first.- Browsers guarantee
deferexecution beforeDOMContentLoaded, allowing DOM-ready code without extra listeners. - Dynamic script insertion (
document.createElement('script')):asyncdefaults to true; you must explicitly setdeferif desired. - Edge cases: Some older browsers treat
deferlike blocking scripts if placed in<head>. Modern browsers reliably implement spec. - In ES modules (
type='module'), scripts are deferred by default. Avoid mixingdeferwith modules.
7. Advanced Example: Combining defer, async, and module
<!-- Place in <head> for optimal loading --> <script src='polyfills.js' defer></script> <!-- needed first in order --> <script src='vendor.js' defer></script> <!-- library code --> <script type='module' src='app.js'></script> <!-- module scripts are deferred by default --> <script src='ads.js' async></script> <!-- independent ads code -->
By leveraging defer and async, you can optimize page load, reduce blocking, and ensure scripts execute in the correct order or as soon as possible. Choose wisely based on dependencies and desired execution timing.
Leave a Reply
You must be logged in to post a comment.