Kodokon kodokon.com

Loading performance: defer, async, preload, and prefetch

Order your scripts' execution with defer and async, then steer the network with preload, preconnect, and prefetch.

10 min · 3 questions

Open this lesson in Kodokon

A classic <script src> blocks HTML parsing: the browser stops, downloads, executes, then resumes. Two attributes change the game. defer downloads in parallel with parsing and executes scripts in document order, just before DOMContentLoaded: it is the default choice for your application code, which may depend on the DOM and on other scripts. async also downloads in parallel but executes as soon as the file arrives, with no guaranteed order: reserve it for standalone scripts like analytics, which depend on nothing.

HTML
<script src="/js/analytics.js" async></script>
<script src="/js/vendor.js" defer></script>
<script src="/js/app.js" defer></script>
vendor.js will always run before app.js

The browser only discovers some critical resources very late: a font referenced inside a CSS file, an image loaded in JavaScript. <link rel="preload"> fixes that late discovery by declaring the resource right in the <head>, with the mandatory as attribute so the browser applies the right priority and the right cache. Textbook case: webfonts, which are otherwise requested only after the CSS has been downloaded and parsed.

HTML
<link rel="preload" as="font" type="font/woff2"
      href="/fonts/inter-var.woff2" crossorigin>
<link rel="preload" as="image"
      href="/img/hero-1600.jpg" fetchpriority="high">
Early discovery of a font and the LCP image

Last family: the low-priority network hints. <link rel="preconnect"> establishes the full connection in advance (DNS, TCP, TLS) to a third-party origin you will definitely use: up to 300 ms saved on the first request. dns-prefetch is its lightweight cousin (DNS resolution only), useful as a fallback for less certain origins. And prefetch downloads, during idle time, a resource meant for the next navigation: the checkout page from the cart, for instance. The trade-off is clear: preload serves the current page, prefetch bets on the next one.

HTML
<link rel="preconnect"
      href="https://api.example.com">
<link rel="dns-prefetch"
      href="https://cdn.example.com">
<link rel="prefetch" href="/checkout.html">
Early connections and a bet on the next navigation

Knowledge check

Make sure you remember the key points of this lesson.

  1. What guarantee does defer offer that async does not?
    • Downloading in parallel with HTML parsing
    • Execution in document order, before DOMContentLoaded
    • Execution before any rendering of the page
  2. Why is crossorigin required on a same-origin font preload?
    • Fonts are always requested in CORS mode; without it, the file is downloaded twice
    • It is a security requirement of the WOFF2 format
    • Without it, the preload is blocked by the default CSP
  3. What is the proper use of rel="prefetch"?
    • Speeding up a critical resource on the current page
    • Downloading, at low priority, a likely resource for the next navigation
    • Forcing a file into permanent caching