Networking and resource loading
How the browser discovers resources
Understand how the HTML parser and preload scanner discover stylesheets, scripts, images, fonts, and other dependencies.
As HTML arrives, the parser creates nodes. Every time it meets a tag that points at a URL, it hands that URL to the network layer and moves on.
Stylesheets, scripts, and images all expose their URL right in the markup:
<link rel="stylesheet" href="/styles.css">
<script src="/app.js" defer></script>
<img src="/hero.webp" alt="Mountain trail">
The parser sees href="/styles.css" and starts the download immediately. It does not wait for the rest of the document.
The preload scanner
There is a second reader of your HTML. Browsers run a preload scanner, a lightweight parser that looks ahead for obvious URLs while the main parser is stuck on blocking work, for example a classic script it must execute first.
This is why a stylesheet in the middle of the <head> can start downloading while a script above it is still running. The scanner found it early.
The scanner has a limit: it only sees what’s in the markup. It cannot discover a URL that JavaScript builds later. Take this code:
document.addEventListener('DOMContentLoaded', () => {
const img = document.createElement('img')
img.src = '/gallery/second.webp'
document.body.append(img)
})
The browser has to download, parse, and run the script before it even knows second.webp exists. A hero image inserted by a client-side render starts much later than one written in the initial HTML.
Check who started each request
Open the Network panel and enable the Initiator column. Parser-discovered resources point back to the document. Script-discovered requests show the JavaScript file and line that created them.
That column tells you at a glance which resources the browser found early and which ones it found late.
My advice: keep critical resources visible in the initial HTML when early discovery matters. And don’t add preload hints before checking whether normal markup already discovers the resource soon enough. We’ll look at preload in a later lesson.
Try this on your own project: load one image from HTML and create a second one in a DOMContentLoaded handler like the one above. Compare their start times and initiators in the Network panel. The gap is the cost of late discovery.
Lesson completed