DEV Community

Cover image for Mastering Script Tags: Using Async and Defer for Precise Script Control
Umair Syed
Umair Syed

Posted on

Mastering Script Tags: Using Async and Defer for Precise Script Control

In the world of web development, optimizing page load times is crucial. Two powerful attributes of the <script> tag – async and defer – can significantly impact your website's performance. Using these attributes without thoroughly understanding them can affect performance and lead to bugs. Let's start from the basics and learn what these attributes do and when to use them.

The Basics: How Scripts Load

By default, when a browser encounters a <script> tag, it:

  1. Pauses HTML parsing
  2. Downloads the script
  3. Executes the script
  4. Resumes HTML parsing

This process can slow down page rendering, especially for large scripts or slow connections. Additionally, it can lead to bugs if the script runs before certain HTML elements are fully loaded, which often happens if the script is not placed correctly in the document.

Async and Defer: A Double-Edged Sword

Async

<script async src="script.js"></script>
Enter fullscreen mode Exit fullscreen mode
  • What it does: Downloads the script asynchronously while HTML parsing continues.
  • When it executes: As soon as it's downloaded, pausing HTML parsing.
  • When it is used: Independent scripts that don't rely on other scripts or DOM content.
  • Caveat: Can execute out of order, potentially breaking dependencies.

Defer

<script defer src="script.js"></script>
Enter fullscreen mode Exit fullscreen mode
  • What it does: Downloads the script while HTML parsing continues.
  • When it executes: After HTML parsing is complete, but before the DOMContentLoaded event.
  • When it is used: Scripts that rely on DOM content or need to execute in a specific order.
  • Caveat: May delay execution of critical functionality.

Comparing Behaviors

Attribute Download Execution HTML Parsing Main Risk
None Blocks Immediate Paused Slow Initial Render
Async Parallel ASAP Paused when downloaded Race Conditions
Defer Parallel After HTML Continues Delayed Functionality

Order of Execution: Async, Defer, and Both

Understanding the order of execution for scripts with different attributes is crucial for managing dependencies and ensuring proper functionality. Here's how it works:

  1. Regular scripts (no async or defer):

    • Execute in the order they appear in the document.
    • Block HTML parsing until they're downloaded and executed.
  2. Async scripts:

    • Download in parallel and execute as soon as they're available.
    • No guaranteed order of execution; they run as soon as they're downloaded.
    • May execute before the DOM is fully loaded.
  3. Defer scripts:

    • Download in parallel but execute only after HTML parsing is complete.
    • Execute in the order they appear in the document.
    • Run before the DOMContentLoaded event.
  4. Scripts with both async and defer:

    • The async attribute takes precedence in modern browsers.
    • In older browsers that don't support async, they fall back to defer behavior.

Example Execution Order:

<script src="1.js"></script>
<script async src="2.js"></script>
<script async src="3.js"></script>
<script defer src="4.js"></script>
<script defer src="5.js"></script>
Enter fullscreen mode Exit fullscreen mode

Possible execution order:

  1. 1.js (blocks parsing)
  2. 3.js or 2.js (whichever downloads first)
  3. 2.js or 3.js (whichever downloads second)
  4. 4.js
  5. 5.js

Note that 2 and 3 could execute in any order or even before 1 if 1.js takes longer to download.

Best Practices

  1. Use async for independent scripts like analytics.
  2. Use defer for scripts that depend on DOM or other scripts.
  3. Place scripts in the <head> with async or defer to start downloading early.
  4. For critical scripts, consider inline scripts in the <head>.

Browser Support

Both async and defer are widely supported in modern browsers. For older browsers, consider using a script loader or placing scripts at the end of the <body>.

Top comments (0)