Defer vs Async

Defer ans Async
42
11/08/2026

Understanding async & defer

How HTML script loading attributes alter parser blocking, background network fetches, and DOM execution order—explained through interactive timeline simulations and live execution logs.

<script src=”…”> Default / Sync

Blocks HTML Parsing

HTML parsing stops immediately. The browser fetches the script over the network and executes it before resuming HTML parsing.

<script async src=”…”> Asynchronous

Fetches Parallel, Interrupts Parse

Downloads in background while HTML parses. As soon as download finishes, HTML parsing pauses to execute the script immediately.

<script defer src=”…”> Deferred

Fetches Parallel, Executes Last

Downloads in background without blocking parsing. Executes in document order after HTML parsing is completely finished.

Interactive Thread Visualizer

Browser Execution Timeline

Time: 0 ms
Speed:
HTML Parsing
Parser Blocked
Network Fetch (Script Download)
JS Execution
DOMContentLoaded Event
Main Thread: HTML Parser Parsing HTML…
Network & JS Execution Thread Idle
i
Timeline Initialized

Click “Play Simulation” or drag the slider to observe how the browser parses HTML nodes and schedules JavaScript execution.

Architectural Comparison

Side-by-Side Behavior Matrix

A comprehensive breakdown of network lifecycle, DOM blocking, execution ordering, and document readiness guarantees.

Feature / BehaviorStandard <script><script async><script defer>
HTML Parsing During Fetch❌ Blocked (Paused)✓ Unblocked (Parallel)✓ Unblocked (Parallel)
HTML Parsing During Execution❌ Blocked (Paused)❌ Blocked (Interrupts DOM)✓ Unblocked (After HTML Parse)
Execution Order Guaranteed?✓ Yes (Document Order)❌ No (First Downloaded First)✓ Yes (Document Order)
DOMContentLoaded Blocked?Yes (Waiting for script)Only if script executes beforehandGuaranteed before event
DOM Elements Guaranteed Ready?❌ Only elements above tag❌ Not guaranteed✓ Fully constructed DOM ready
Primary Purpose & Use Cases Legacy scripts or critical inline initialization required before rendering. Independent 3rd-party trackers, ads, analytics (Google Analytics, Sentry). Main application code, UI frameworks, scripts dependent on DOM or other modules.
Practical Recommendation Engine

Which attribute should you use?

Answer 3 simple questions to receive a tailored script loading strategy.

STEP 1
STEP 2
STEP 3
Recommended Strategy <script defer src=”app.js”></script>

Use defer in the <head>

Since your script interacts with DOM elements and relies on execution order, defer is ideal. It downloads in parallel without blocking HTML parsing, guarantees DOM readiness, and maintains script order.

<script defer src="main.js"></script>
Live Browser Console Simulation

DevTools Execution Sandbox

HTML Document Markup index.html
<!DOCTYPE html>
<html>
<head>
  <script defer src="analytics.js"></script>
  <script defer src="app.js"></script>
</head>
<body>
  <h1 id="title">Hello World</h1>
</body>
</html>
Browser Console Logs
[Console cleared. Click “Simulate Page Load” above]
Deep-Dive Knowledge

Edge Cases & Modern Rules

Important nuances involving inline scripts, ES modules, dynamic injection, and Web Vitals impact.

01

Inline Scripts Ignore async & defer

Applying async or defer to inline script tags (without a src attribute) is ignored by modern browsers. Inline scripts always execute synchronously and block the HTML parser unless declared as type="module".

02

ES Modules Default to defer Automatically

When using <script type="module" src="...">, the browser automatically applies defer behavior by default! Module scripts download in parallel and defer execution until HTML parsing completes. You can explicitly add async to execute a module as soon as it arrives.

03

Dynamic Scripts (document.createElement) Default to async

Scripts created via JavaScript (document.createElement('script')) automatically have script.async = true set by the spec! If you need ordered execution for dynamically inserted scripts, you must explicitly set script.async = false.

04

Impact on Core Web Vitals (INP, LCP, FCP)

Replacing render-blocking standard scripts with defer directly improves First Contentful Paint (FCP) and Largest Contentful Paint (LCP) by preventing parser pause. Offloading non-critical scripts to async reduces main thread jank and improves Interaction to Next Paint (INP).

\n`, logs: [ { delay: 0, text: '🌐 [0ms] HTML Parser started reading document', color: '#A8A296' }, { delay: 120, text: '🛑 [120ms] Parser BLOCKED by \n`, logs: [ { delay: 0, text: '🌐 [0ms] HTML Parser started reading document', color: '#A8A296' }, { delay: 50, text: '🚀 [50ms] Background fetch initiated for analytics.js & ads-tracker.js', color: '#A8A296' }, { delay: 180, text: '🏗️ [180ms] HTML parsing continues smoothly to 60%', color: '#88C090' }, { delay: 240, text: '⚡ [240ms] ads-tracker.js finished download first -> EXECUTED IMMEDIATELY!', color: '#88C090' }, { delay: 380, text: '⚡ [380ms] analytics.js finished download -> EXECUTED IMMEDIATELY!', color: '#88C090' }, { delay: 450, text: '📄 [450ms] HTML parsing complete -> DOMContentLoaded fired', color: '#81A1C1' } ] },defer: { code: `\n\n\n \n`, logs: [ { delay: 0, text: '🌐 [0ms] HTML Parser started reading document', color: '#A8A296' }, { delay: 40, text: '🚀 [40ms] Background fetches started for vendor-lib.js & app-main.js', color: '#A8A296' }, { delay: 200, text: '🏗️ [200ms] HTML parsing completed 100% uninterrupted! Full DOM ready.', color: '#81A1C1' }, { delay: 280, text: '📦 [280ms] Download ready. Executing deferred script 1: vendor-lib.js', color: '#81A1C1' }, { delay: 360, text: '🚀 [360ms] Executing deferred script 2: app-main.js (Document order preserved)', color: '#81A1C1' }, { delay: 400, text: '📄 [400ms] DOMContentLoaded event fired!', color: '#88C090' } ] },mixed: { code: `\n\n\n \n`, logs: [ { delay: 0, text: '🌐 [0ms] HTML Parser started reading document', color: '#A8A296' }, { delay: 30, text: '🚀 [30ms] Both scripts fetching in parallel background threads', color: '#A8A296' }, { delay: 180, text: '⚡ [180ms] google-analytics.js (async) fetched -> Executed in background', color: '#88C090' }, { delay: 250, text: '🏗️ [250ms] HTML Parser reaches end of body (DOM Tree built)', color: '#81A1C1' }, { delay: 320, text: '⚡ [320ms] react-app.js (defer) executed safely with full DOM context', color: '#81A1C1' }, { delay: 350, text: '📄 [350ms] DOMContentLoaded fired -> App initialized successfully', color: '#88C090' } ] } };let sandboxTimeoutIds = [];function initSandbox() { const presetSelect = document.getElementById('sandbox-preset'); const runBtn = document.getElementById('sandbox-run-btn'); const clearBtn = document.getElementById('sandbox-clear-btn');presetSelect?.addEventListener('change', () => { updateSandboxCodeView(presetSelect.value); });runBtn?.addEventListener('click', () => { runSandboxSimulation(presetSelect.value); });clearBtn?.addEventListener('click', clearSandboxConsole);updateSandboxCodeView('defer'); }function updateSandboxCodeView(presetKey) { const codeView = document.getElementById('sandbox-code-view'); const preset = SANDBOX_PRESETS[presetKey] || SANDBOX_PRESETS.defer; if (codeView) { codeView.textContent = preset.code; } }function clearSandboxConsole() { sandboxTimeoutIds.forEach(id => clearTimeout(id)); sandboxTimeoutIds = []; const consoleOutput = document.getElementById('sandbox-console-output'); if (consoleOutput) { consoleOutput.innerHTML = '
[Console cleared. Click "Simulate Page Load" above]
'; } }function runSandboxSimulation(presetKey) { clearSandboxConsole(); const consoleOutput = document.getElementById('sandbox-console-output'); if (!consoleOutput) return;consoleOutput.innerHTML = ''; const preset = SANDBOX_PRESETS[presetKey] || SANDBOX_PRESETS.defer;preset.logs.forEach(log => { const timeoutId = window.setTimeout(() => { const logDiv = document.createElement('div'); logDiv.style.color = log.color; logDiv.className = 'font-mono-code text-xs leading-relaxed transition-all duration-150'; logDiv.innerText = log.text; consoleOutput.appendChild(logDiv); consoleOutput.scrollTop = consoleOutput.scrollHeight; }, log.delay);sandboxTimeoutIds.push(timeoutId); }); }// Initialize on load document.addEventListener('DOMContentLoaded', () => { initSimulator(); initWizard(); initSandbox(); });
Advertisement
Continue Reading Below
Related SEO Topics