Back
Web Fundamentals

Script Loading: async vs defer

Web Fundamentals
Build & Deployment: Monorepo, CI/CD, Strategies & Release SafetyState Management: Choosing the Right SolutionRedux: Predictable State Container (RTK + RTK Query)React Query (TanStack Query): Server State CachingData Fetching Patterns: REST, GraphQL, tRPC & Real-timeGraphQL Fundamentals for Frontend: Shape, Caching, and TradeoffsgRPC-Web Fundamentals: Browser Constraints and Proxy ModelCaching Strategies: Client, Server & EdgeData Normalization: Organizing State for PerformanceAPI Design Best Practices: Pagination, Errors, Versioning & Type SafetyAPI Versioning Strategies for Frontend CompatibilityPagination: Offset vs Cursor-BasedRate Limiting & API Resilience: Retries, Backoff, Jitter, IdempotencyHow Frontend Developers Can Handle Millions of API Requests Without Crashing EverythingBrowser Storage: Cookies, SessionStorage, LocalStorage, IndexedDBReal-time Communication: WebSockets, SSE & PollingWebRTC: Real-Time Communication in the BrowserCore Web Vitals: LCP, INP & CLSPerformance Optimization Trade-offsCritical Resource Prioritization: Optimize Loading OrderCode Splitting: Optimize Bundle Size with Dynamic ImportsTree Shaking: Eliminate Dead Code from Your BundleLazy Loading: Load Resources On-DemandResource Hints: Preload, Prefetch & PreconnectText Compression: Gzip and BrotliImage & Video Optimization: Modern Formats & TechniquesAdaptive Loading: Optimize for Device & NetworkList Virtualization: Render Large Lists EfficientlyWeb Workers vs Main Thread: Offloading Heavy WorkMemory Leaks in Frontend Apps: Detection & PreventionManaging Third-Party Scripts: Optimization StrategiesHow CDNs Work: Edge Delivery, Caching & PerformanceHTTP Caching Deep Dive: Cache-Control, ETag & RevalidationService Workers & Offline Strategy: Cache First, Network First & Update LifecyclePWA Fundamentals: Manifest, Installability & Offline UXCritical Rendering PathScript Loading: async vs deferEvent Loop: Understanding JavaScript Execution ModelJavaScript Module Systems: CJS vs ESM vs UMDDynamic Module Loading: import() FunctionImport on Interaction: Load When User InteractsImport on Visibility: Lazy Loading with IntersectionObserverBrowser Rendering Pipeline & Layout ThrashingRendering Strategies: CSR vs SSR vs SSG vs ISRStreaming SSR: Progressive HTML StreamingIslands Architecture: Independent Component HydrationReact Server Components: Zero-JS Server RenderingFramework Reactivity: React, Vue, Svelte & SolidHTTP/1.1 vs HTTP/2 vs HTTP/3 (QUIC) for Frontend PerformanceDNS Resolution: Path, TTL, Caching & Frontend ImpactCross-Site Scripting (XSS) AttacksCross-Site Request Forgery (CSRF) AttacksCORS Explained: Cross-Origin Resource SharingCORS Preflight in Practice: Credentials, Simple Requests & MisconfigurationsContent Security Policy (CSP)Why is HTTPS Secure? Understanding TLS/SSLAuthorization Best PracticesCookie Security & Session Hardening: SameSite, HttpOnly, Secure
easyRendering & Browser Architecture

Script Loading: async vs defer

TL;DRRegular script blocks parsing • async = parallel + immediate execution (unordered) • defer = parallel + after parsing (ordered)
Very High Signal
Google
Meta
Atlassian
Netflix
30-Second Answerstart every interview with this

Script loading attributes control parser blocking, download behavior, and execution timing. A plain <script> blocks HTML parsing. async downloads in parallel and executes as soon as ready (no order guarantee). defer downloads in parallel and executes after HTML parsing completes, in document order. type=module scripts are deferred by default.

The HTML parser is the main builder. A regular script stops the entire crew until it finishes. async workers arrive independently and start working the moment they show up. defer workers arrive early but wait politely until the main structure (HTML) is complete before starting, in the order they were hired.

Parser encounters <script>
Regular: Block & Execute
async: Download parallel → Execute ASAP
defer: Download parallel → Execute after parse (ordered)
type=module: Behaves like defer by default

1Regular Script (No Attribute)

Blocks HTML parsing completely. The browser fetches and executes the script immediately before continuing to parse the rest of the document. Use only when you truly need blocking behavior.

index.htmlhtml
<script src="app.js"></script>   <!-- parser-blocking -->

2The async Attribute

Downloads in parallel while parsing continues. Executes as soon as the script is ready — order is not guaranteed. Can still interrupt parsing when it runs. Best for independent scripts like analytics or ads.

index.htmlhtml
<script async src="analytics.js"></script>

3The defer Attribute

Downloads in parallel. Execution is delayed until HTML parsing is complete. Multiple defer scripts execute in document order. Ideal default for most application code that needs the DOM or predictable ordering.

index.htmlhtml
<script defer src="vendor.js"></script>
<script defer src="app.js"></script>

4Module Scripts (type=module)

Modern ES modules are deferred by default. They download in parallel and execute after parsing. Adding async makes them execute as soon as ready (like classic async). defer attribute has no additional effect.

index.htmlhtml
<script type="module" src="app.js"></script>
<!-- async module -->
<script type="module" async src="utils.js"></script>
PropertyRegular <script>asyncdefer
BehaviorBlocks HTML parsingNon-blocking downloadNon-blocking download
Best ForCritical inline config or rare blocking needsAnalytics, ads, independent third-party scriptsApplication code, vendor libraries, DOM-dependent scripts
Dom ReadyNo guaranteeMay run before DOM is parsedYes (DOM is fully parsed)
Execution TimingImmediately after downloadAs soon as downloadedAfter HTML parsing completes
Order GuaranteedYes (document order)NoYes (document order)

Regular <script>

Behavior

Blocks HTML parsing

Best For

Critical inline config or rare blocking needs

Dom Ready

No guarantee

Execution Timing

Immediately after download

Order Guaranteed

Yes (document order)

async

Behavior

Non-blocking download

Best For

Analytics, ads, independent third-party scripts

Dom Ready

May run before DOM is parsed

Execution Timing

As soon as downloaded

Order Guaranteed

No

defer

Behavior

Non-blocking download

Best For

Application code, vendor libraries, DOM-dependent scripts

Dom Ready

Yes (DOM is fully parsed)

Execution Timing

After HTML parsing completes

Order Guaranteed

Yes (document order)

Common questions

  • ›“What is the difference between async and defer?”
  • ›“When would you use async vs defer scripts?”
  • ›“How do script attributes affect the Critical Rendering Path?”
  • ›“Explain script loading behavior for type=module”

What interviewers look for

  • Clear understanding of parser-blocking vs non-blocking
  • Knowledge of execution order and DOM readiness
  • Ability to choose the right attribute based on use case
  • Awareness that modules are deferred by default

Short answer (60 sec)

Regular scripts block parsing. async downloads in parallel and runs as soon as ready (unordered). defer downloads in parallel and runs after parsing in document order. Use defer for most app scripts and async for independent third-party code.

Detailed answer (senior level)

The key differences are parser blocking, execution timing, and ordering. A plain script stops the parser. async scripts can execute before parsing finishes and have no order guarantee. defer scripts preserve order and run after the DOM is parsed (before DOMContentLoaded). Module scripts behave like defer by default. Senior answers also mention how these affect First Contentful Paint and DOMContentLoaded timing.

  • Using async for dependent scripts (order not guaranteed)
  • Forgetting that async scripts can run before the DOM is parsed
  • Adding defer to type=module scripts (already deferred)
  • Using blocking scripts for non-critical third-party code
  • Assuming all scripts wait for the DOM
Key Takeaways
  • ✓defer is the safest default for most application JavaScript
  • ✓async is ideal for independent scripts (analytics, ads)
  • ✓Regular scripts should be used sparingly — only when blocking is required
  • ✓type=module scripts are deferred by default
  • ✓Choose based on: Do you need order? Do you need the DOM? Is the script independent?
Previous TopicCritical Rendering PathNext Topic Event Loop: Understanding JavaScript Execution Model

On this page