Browser Execution Process - How Browsers Run JS

Learn exactly how browsers parse, compile, and execute JavaScript, including the critical rendering path!

Introduction

What happens from when a browser receives HTML/CSS/JS to when you see the page? Let's break down the entire browser execution process step by step!

What You Will Learn

  • The Critical Rendering Path
  • How browsers parse HTML
  • How browsers parse and execute JS
  • Layout (Reflow) and Paint
  • How to optimize this process

Prerequisites

The Critical Rendering Path

Here are the steps!

graph LR
    A[HTML Received] --> B[Parse HTML DOM]
    C[CSS Received] --> D[Parse CSS CSSOM]
    B --> E[Combine DOM + CSSOM]
    D --> E
    E --> F[Render Tree]
    F --> G[Layout Reflow Calculate positions/sizes]
    G --> H[Paint Pixels to screen]

Step 1: Parsing HTML to DOM

The browser starts parsing HTML to build the Document Object Model (DOM)!

<!DOCTYPE html>
<html>
  <head><title>Hi</title></head>
  <body><p>Hello!</p></body>
</html>

DOM Tree:

html
├── head
│   └── title
│       └── "Hi"
└── body
    └── p
        └── "Hello!"

Step 2: Parsing CSS to CSSOM

Similarly, browser parses CSS into CSS Object Model (CSSOM)!

body { font-size: 16px; }
p { color: blue; }

CSSOM Tree:

body (font-size: 16px)
└── p (color: blue)

Step 3: JavaScript Execution - The Parser-Blocker!

JavaScript execution is parser-blocking and render-blocking! When the HTML parser hits a <script> tag:

  1. It stops parsing HTML
  2. It downloads the JS file (if external)
  3. It executes the JS (which can modify DOM/CSSOM!)
  4. Then continues parsing!

Why? Because JS can modify the DOM!

<p>First!</p>
<script>
  document.write('<p>JS inserted!</p>');
</script>
<p>Second!</p>

Step 4: Render Tree

Combine DOM and CSSOM to make the Render Tree - only visible elements! (No <head>, display: none elements)

Step 5: Layout (Reflow)

The browser calculates exact positions and sizes of every element!

Step 6: Paint

The browser actually paints pixels to the screen - colors, images, text, shadows, etc.

How to Optimize

  1. Put <script> at end of <body>: Let HTML/CSS load first!
  2. Use async/defer on scripts:
    <script async src="analytics.js"></script> <!-- Runs when downloaded, doesn't block -->
    <script defer src="app.js"></script>   <!-- Runs after HTML is parsed -->
    
  3. Minify and compress files: Smaller files = faster download!
  4. Inline critical CSS: Avoid render-blocking requests!
  5. Avoid layout thrashing: Don't read layout then write repeatedly!

Visualizing the Whole Process

graph TB
    subgraph "Network"
        A1[HTML Request]
        A2[CSS Request]
        A3[JS Request]
    end

    subgraph "Parsing"
        B1[Parse HTML DOM]
        B2[Parse CSS CSSOM]
    end

    subgraph "Execution"
        C1[Execute JS]
    end

    subgraph "Rendering"
        D1[Render Tree]
        D2[Layout Reflow]
        D3[Paint]
    end

    A1 --> B1
    A2 --> B2
    A3 --> C1
    B1 --> D1
    B2 --> D1
    C1 --> D1
    D1 --> D2
    D2 --> D3
    D3 --> E[Page Visible!]

Code Examples: Bad vs Good

Bad (Script in Head, Blocking)

<!DOCTYPE html>
<html>
<head>
  <!-- BAD! Blocks HTML/CSS parsing! -->
  <script src="app.js"></script>
  <link rel="stylesheet" href="styles.css">
</head>
<body>...</body>
</html>

Good (Script at End, Defer)

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  ...
  <!-- GOOD! At end, or use defer! -->
  <script src="app.js"></script>
</body>
</html>

Industry Use Cases

  • E-commerce sites: Speed is crucial! Slow pages lose sales!
  • SPAs (React/Vue): Need to optimize loading and re-rendering!
  • News sites: Lots of content, need to load fast!

Best Practices

  1. Use defer: For scripts that need DOM, execute after HTML parsed
  2. Use async: For independent scripts (like analytics)
  3. Avoid document.write(): It can erase page if used after load
  4. Use CDNs: Serve static files faster
  5. Optimize images: Largest assets usually!

Common Mistakes

  1. Too many render-blocking scripts/styles: Head full of <script> and <link>!
  2. Layout thrashing: Reading and writing layout properties in a loop!
  3. Giant JS bundles: Split them with code splitting!

Performance Notes

Every millisecond counts! Use Lighthouse in Chrome DevTools to audit performance!

Security Notes

  • Only load trusted scripts!
  • Use integrity hash for external scripts: <script integrity="sha256-..." src="...">
  • Content Security Policy (CSP) headers prevent XSS!

SEO Notes

Fast pages rank better! Optimize the critical rendering path for better SEO!

FAQs

Q: Why is JS render-blocking? A: Because JS can modify the DOM/CSSOM! Browser needs to run it first to get correct page!

Q: What's the difference between async and defer? A: Async runs as soon as downloaded (order not guaranteed), defer runs after HTML parsed (order preserved)!

Q: What is layout thrashing? A: Reading then writing layout properties repeatedly, causing browser to recalculate layout many times!

Summary

The browser execution process goes from network → parsing → JS execution → render tree → layout → paint! Optimize this for fast, smooth pages!

Related Articles

Previous Tutorial

Client Side vs Server Side JavaScript

Next Tutorial

Let's write our first JS program! → First JavaScript Program