<Script> tags blocking DOM rendering

Loading

<script> Tags Blocking DOM Rendering – Detailed Explanation


Step 1: Understanding How Browsers Render Webpages

When a browser loads a webpage, it follows these steps:

  1. Parse the HTML – Reads and builds the Document Object Model (DOM).
  2. Download and Apply CSS – Builds the CSS Object Model (CSSOM).
  3. Render the Page – Combines the DOM and CSSOM to display the page visually.
  4. Execute JavaScript – Runs any <script> tags in the document.

🚨 Problem: By default, <script> tags block the rendering process because the browser pauses DOM parsing until the script is downloaded and executed.


Step 2: How <script> Tags Block Rendering

When the browser encounters a <script> tag in the HTML, it pauses parsing until the script is downloaded, compiled, and executed.

Example of a Blocking Script

<!DOCTYPE html>
<html>
<head>
    <title>Blocking Script Example</title>
    <script src="large-script.js"></script>
</head>
<body>
    <h1>Hello, World!</h1>
</body>
</html>

What Happens?

  1. The browser starts parsing the HTML.
  2. It reaches the <script> tag and stops rendering.
  3. It downloads and executes large-script.js.
  4. Only after execution is complete does the browser resume parsing the rest of the HTML.

🚨 This can slow down page rendering, especially if the script is large or hosted on a slow server.


Step 3: Proof That Scripts Block Rendering

Let’s add a delay in a script to see how it affects page rendering.

Example: Delayed Script Blocking Rendering

<!DOCTYPE html>
<html>
<head>
    <title>Script Blocking Example</title>
    <script>
        // Simulating a long script execution time
        let start = Date.now();
        while (Date.now() - start < 5000) {} // Blocks for 5 seconds
    </script>
</head>
<body>
    <h1>This text appears after the script runs.</h1>
</body>
</html>

Expected Behavior

  • The page freezes for 5 seconds before displaying the <h1> text.
  • This happens because the script blocks HTML parsing.

Step 4: How to Prevent <script> from Blocking Rendering

βœ… Solution 1: Place Scripts at the End of <body>

Instead of putting scripts in <head>, place them just before the closing </body>.

Example:

<!DOCTYPE html>
<html>
<head>
    <title>Non-blocking Script</title>
</head>
<body>
    <h1>Page Content Loads First</h1>
    <script src="large-script.js"></script>
</body>
</html>

βœ… Now, the browser renders the <h1> first and loads the script afterward.


βœ… Solution 2: Use the defer Attribute

The defer attribute ensures scripts are downloaded in parallel but executed only after the DOM is fully loaded.

Example:

<!DOCTYPE html>
<html>
<head>
    <title>Using Defer</title>
    <script src="large-script.js" defer></script>
</head>
<body>
    <h1>Page Loads Without Delay</h1>
</body>
</html>

How defer Works

  • The browser downloads the script while parsing HTML.
  • The script executes only after the full HTML document is loaded.
  • βœ… Does NOT block rendering.

βœ… Solution 3: Use the async Attribute

The async attribute allows scripts to download and execute independently, without waiting for the DOM.

Example:

<!DOCTYPE html>
<html>
<head>
    <title>Using Async</title>
    <script src="large-script.js" async></script>
</head>
<body>
    <h1>Page May Load Before Script</h1>
</body>
</html>

How async Works

  • The script downloads in parallel while HTML is parsing.
  • As soon as the script is ready, it executes immediately.
  • 🚨 If execution happens before the DOM is ready, scripts modifying the DOM might fail.

Step 5: defer vs. async – When to Use Which?

AttributeBlocks Rendering?Execution OrderBest Use Case
Noneβœ… YesIn order of appearanceSmall inline scripts, must execute immediately
defer❌ NoAfter the entire DOM is loadedScripts that depend on the full HTML structure
async❌ NoImmediately when downloadedIndependent scripts like analytics, ads

πŸš€ Rule of Thumb:

  • Use defer for scripts that interact with the DOM.
  • Use async for scripts that don’t depend on the DOM (e.g., analytics, ads).

Step 6: Checking if Scripts Are Blocking Rendering

1. Use Chrome DevTools

  1. Right-click on the page β†’ Inspect.
  2. Go to Performance tab.
  3. Click Record and reload the page.
  4. Look for Long Tasks in red bars (indicating scripts blocking rendering).

2. Use Lighthouse Audit

  1. Open Chrome DevTools.
  2. Go to Lighthouse.
  3. Run an audit and check for Render-blocking resources.

Step 7: Additional Performance Optimization Tips

  • Minify JavaScript – Reduce script file size.
  • Load scripts from a CDN – Faster delivery.
  • Use lazy loading – Load scripts only when needed.
  • Reduce unused JavaScript – Only include necessary functions.

Final Thoughts

  • <script> blocks DOM rendering by default.
  • Placing scripts before </body>, using defer, or async can prevent blocking.
  • Use defer for scripts that interact with the DOM.
  • Use async for independent scripts like analytics.
  • Test performance using Chrome DevTools and Lighthouse.

By following these best practices, you can ensure faster page loads and improved user experience!

Leave a Reply

Your email address will not be published. Required fields are marked *