Asynchronous Loading: async vs defer and Performance
Asynchronous loading fetches resources without blocking the page. How async and defer scripts, import() and lazy images work, and where they go wrong.
What is asynchronous loading?
Asynchronous loading means fetching a resource without stopping the browser from doing other work, such as parsing HTML or rendering. On the web it covers async and defer scripts, dynamic import(), lazy-loaded images and fetch requests. The page stays responsive while the resource arrives and is used once it is ready.
async vs defer
A classic script without either attribute is fetched and executed right away, and the browser stops parsing the page while that happens. async and defer both download the script in parallel with parsing. They differ in when it runs.
- async: runs as soon as it has downloaded, which can pause parsing, and gives no guarantee of order between scripts.
- defer: runs after the document has been parsed, before
DOMContentLoaded, and in the order the scripts appear in the page. - type="module": deferred by default, so
deferhas no effect on it.
Both attributes only work on scripts with a src; they do nothing on inline scripts. If both are set, async wins. Source: MDN, the script element.
Example
<!-- classic script, blocks parsing -->
<script src="app.js"></script>
<!-- downloads in parallel, runs when ready, any order -->
<script async src="analytics.js"></script>
<!-- downloads in parallel, runs after parsing, in order -->
<script defer src="app.js"></script>
<!-- module scripts are deferred by default -->
<script type="module" src="main.js"></script>A common split: defer for your own app code, which depends on the DOM and on other scripts, and async for independent third-party scripts such as analytics.
Other forms of asynchronous loading
- Dynamic import:
import()loads an ES module on demand and returns a promise. It is the basis of code splitting, where a chunk loads only when needed. - Lazy images and iframes:
loading="lazy"defers off-screen resources until the user scrolls near them. See lazy loading. - Data requests:
fetchand XHR calls that fill in the page after it first renders.
Common mistakes
- async on scripts that depend on each other. Order is not guaranteed, so a plugin can run before its library.
- Lazy-loading the hero image. The largest element above the fold is usually what Largest Contentful Paint measures, so deferring it delays the metric. Lazy-load what starts off-screen.
- Blocking scripts in the head. They hold up the critical rendering path. Defer them unless the first paint needs them.
- Content that appears late and shifts the layout. Reserve space for asynchronously loaded content.
- No error handling. A failed
import()orfetchrejects its promise; handle it or the feature silently never appears.
Asynchronous loading, testing and monitoring
Async loading improves what the user sees first, but it moves work rather than removing it. The scripts still download and execute, so measure the result in the browser with DOM-ready and Core Web Vitals timings, not only server response times. Our guide to JavaScript performance shows how async, defer and code splitting affect main-thread work, and page speed monitoring tracks the effect of each change on a schedule.
FAQ about asynchronous loading
What is the difference between async and defer?
Both download the script without blocking the parser. async runs it as soon as it arrives, in no guaranteed order. defer runs it after parsing finishes, before DOMContentLoaded, in document order.
Which should I use?
Use defer for scripts that need the DOM or depend on each other. Use async for independent scripts, such as analytics, that can run whenever they arrive.
Do async and defer work on inline scripts?
No. They have no effect without a src attribute. Module scripts are deferred by default.
Does asynchronous loading make a page faster?
It usually improves how soon the page renders and becomes usable, because the parser is not held up. The total work is the same, so check the effect with real measurements.
Is lazy loading the same as asynchronous loading?
Lazy loading is one kind of it: a resource is fetched only when needed, for example when an image nears the viewport. Async scripts are fetched immediately, just without blocking the page.
Related terms
Related LoadFocus Tools
Put this concept into practice with LoadFocus, the same platform that powers everything you just read about.