![]()
<script> Tags Blocking DOM Rendering β Detailed Explanation
Step 1: Understanding How Browsers Render Webpages
When a browser loads a webpage, it follows these steps:
- Parse the HTML β Reads and builds the Document Object Model (DOM).
- Download and Apply CSS β Builds the CSS Object Model (CSSOM).
- Render the Page β Combines the DOM and CSSOM to display the page visually.
- 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?
- The browser starts parsing the HTML.
- It reaches the
<script>tag and stops rendering. - It downloads and executes
large-script.js. - 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?
| Attribute | Blocks Rendering? | Execution Order | Best Use Case |
|---|---|---|---|
| None | β Yes | In order of appearance | Small inline scripts, must execute immediately |
| defer | β No | After the entire DOM is loaded | Scripts that depend on the full HTML structure |
| async | β No | Immediately when downloaded | Independent scripts like analytics, ads |
π Rule of Thumb:
- Use
deferfor scripts that interact with the DOM. - Use
asyncfor scripts that donβt depend on the DOM (e.g., analytics, ads).
Step 6: Checking if Scripts Are Blocking Rendering
1. Use Chrome DevTools
- Right-click on the page β Inspect.
- Go to Performance tab.
- Click Record and reload the page.
- Look for Long Tasks in red bars (indicating scripts blocking rendering).
2. Use Lighthouse Audit
- Open Chrome DevTools.
- Go to Lighthouse.
- 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>, usingdefer, orasynccan prevent blocking. - Use
deferfor scripts that interact with the DOM. - Use
asyncfor 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!
