Image Load Lab

Guides Browser Behaviour Tested Oct 18, 2026 Chrome 155 · slow 4G · 6 methods

When Does Chrome Request an Image? Six Ways to Reference It, Timed

An img tag in the HTML was requested at 173 ms. The same image as a CSS background or inserted by a script waited for the stylesheet until 345 to 370 ms, and a data-src swap until 1,290 ms.

An image can only start downloading once the browser knows it exists. Put an <img> tag in the HTML and Chrome’s preload scanner finds it while the page is still arriving. Reference the same file from CSS or a script, and the browser has to get further into building the page first. How much later does the request start for each common way of referencing an image? We put the same image on one page six ways and timed each request.

The test

One local test page referenced the same 36 KB CC0 JPEG six times, each with a different query string so that every reference was a separate request:

  • an <img> tag in the HTML;
  • a CSS background in an inline style attribute;
  • a CSS background in an external stylesheet linked in the <head>;
  • an image created by an inline script;
  • an image created by an external script;
  • an <img> whose data-src is copied to src on the load event, a pattern used by older lazy-loading scripts.

We loaded the page five times in Chrome 155.0.8059.82 on a throttled profile (150 ms latency, 1.6 Mbit/s, CPU slowed four times). For each image, we recorded when its request started, measured from the start of the HTML request, along with its initial priority. See our methodology.

Results

Bar chart: an img tag in the HTML was requested 173 ms after the page request; images referenced from CSS or inserted by scripts started at 345 to 370 ms; an image whose data-src was swapped on the load event started at 1,290 ms
Median time from the HTML request to the start of the image request for six ways of referencing the same image. Chart generated from the linked CSV.
Chrome 155.0.8059.82, desktop viewport, local server; the same 36 KB JPEG with a different query string per method
Image referenced by Request starts Download finished Initial priority
<img> in the HTML 173 ms 619 ms Medium
background in a style attribute 345 ms 1,251 ms Low
background in an external stylesheet 346 ms 1,271 ms Low
inserted by an inline script 366 ms 1,282 ms Low
inserted by an external script 370 ms 1,286 ms Low
data-src swapped on the load event 1,290 ms 1,667 ms Low

The <img> in the HTML was requested first, 173 ms after the page request, as soon as the first bytes of HTML arrived. It was also the only image that started at Medium priority, and it finished at 619 ms.

Everything else waited for the stylesheet. The two CSS backgrounds and the two script-created images all started between 345 and 370 ms. That is just after the small external stylesheet finished downloading, at about 340 ms. The browser needs the finished stylesheet before it can work out styles and run scripts, so even a background in an inline style attribute waited. These four images also started at Low priority and shared the connection, finishing at 1.25 to 1.29 seconds.

The data-src pattern was by far the latest: 1,290 ms, because it waits until every other resource on the page has loaded. On a real page with more images, fonts and scripts, that wait would be longer still.

What this means

  • Put important images in the HTML as <img> or <picture>. In this test, that alone made the request start about 170 ms earlier than any other method, and finish twice as soon.
  • Every render-blocking stylesheet delays CSS backgrounds and script-inserted images. Our stylesheet was tiny and still set the start time for four of the six images. A larger or slower stylesheet would push them later.
  • If a hero must be a CSS background, preload it with <link rel="preload" as="image" fetchpriority="high">, as tested in our preload and fetchpriority guide. Our responsive background guide covers image-set() as well.
  • Avoid lazy-loading scripts that wait for the load event, and never use them on images in the first screen. Native loading="lazy" needs no script; we compared it with JavaScript libraries in our lazy-loading methods test.
  • Lighthouse checks this for the LCP image. Its “LCP request discovery” insight flags a hero that is not in the initial HTML, as shown in our Lighthouse discovery test.

How to check your own page

Open Chrome DevTools, go to the Network panel, choose a slow throttling profile and reload. Add the “Initiator” and “Priority” columns, then sort by the Waterfall column. Images found by the preload scanner list the HTML document as their initiator and start right after it. Images listed with a stylesheet or a script as initiator were discovered later, and their bars start further to the right. Our DevTools image audit guide walks through the panel in more detail.

Practical conclusion

An <img> in the HTML was requested 173 ms after the page request. The same image as a CSS background or inserted by a script was requested at 345–370 ms, after the stylesheet had loaded and at Low priority. Swapping data-src on the load event delayed it to 1,290 ms. Keep the images that matter in the HTML.

Limitations

One simple page on a local HTTP/1.1 server with a small, fast stylesheet. Five loads, Chrome only. On real pages, the gaps depend on how many stylesheets and scripts come first and how large they are.

Data and files

Download image-discovery.csv (6 rows, 0.3 KB) · Method: testing methodology. Photo: image credits.

Client Hints on Image Requests: What Chrome Sends

Chrome 155 sent DPR, width and network hints with image requests only after Accept-CH, and to another origin only with Permissions-Policy delegation. Width was in device pixels.

Browser Behaviour 4 min read

Video Poster Images and LCP: Same as an img?

A video poster was discovered as early as an img, got the same priority and counted as the LCP element with the same timing, 1,316 ms against 1,320 ms. It cannot use srcset.

Browser Behaviour 3 min read