The fold & the hero
"The fold" is a term borrowed from newspaper layout: it is the lowest point on the page that is visible without scrolling. Anything above the fold is seen immediately on page load; anything below it is only seen if the user scrolls down. For web performance, the fold is the boundary that determines which resources are truly urgent.
The hero image — the large, prominent image at the top of a page — sits above the fold by definition. It is almost always the browser's Largest Contentful Paint (LCP) element: the largest visible item that the browser renders during initial page load. Google's Core Web Vitals framework targets an LCP under 2.5 seconds; a slow-loading hero directly worsens that score and the user experience that goes with it.
The practical rule: prioritize above-the-fold images (especially the hero) so the browser fetches them as early as possible, and deprioritize everything below the fold so those fetches don't compete with the hero for bandwidth. The attributes in the following sections give you the controls to do exactly that.
Lazy loading
By default, the browser begins fetching every <img> it encounters
in the HTML as soon as it parses the page — even images hundreds of pixels below
the fold that the user may never reach. This eagerness consumes bandwidth that
could have gone to the hero or other critical resources.
loading="lazy" defers the fetch until the image is near the viewport
(the browser decides the exact threshold, typically a few hundred pixels away).
loading="eager" is the explicit form of the default: fetch immediately,
regardless of position. Use lazy on below-the-fold content images;
use eager (or omit the attribute) on above-the-fold images.
Always include width and height alongside
loading="lazy". Without them, the browser cannot reserve space for the
image before it loads, causing Cumulative Layout Shift (CLS) as the image arrives
and pushes content down.
decoding & fetchpriority
These two attributes give you finer control over when the browser decodes image data and how aggressively it pursues a fetch.
decoding="async"
Decoding a compressed image (JPEG, WebP, AVIF) requires CPU work. By default, the
browser may perform this work synchronously on the main thread, blocking rendering
while it finishes. decoding="async" moves the decode off the main
thread, so rendering can continue while the image is being decoded.
Use decoding="async" on non-critical images — anything below the fold
or secondary in importance. Do not use it on the LCP hero.
Async decoding can delay when the hero is painted, which directly hurts your LCP
score. For the hero, omit the attribute (or use the explicit
decoding="sync") so the browser decodes it as fast as possible on
the path to first paint.
fetchpriority
The browser's network scheduler treats most images with the same priority. When
images are competing for bandwidth on initial load, that equal treatment can mean
the hero waits behind below-the-fold images. The fetchpriority
attribute lets you intervene:
fetchpriority="high"— move this image to the front of the network queue. Use on the LCP hero, at most once per page.fetchpriority="low"— treat this image as non-urgent, even if it is technically in the viewport.fetchpriority="auto"— the default; let the browser decide.
Marking more than one image high cancels out the benefit — if
everything is urgent, nothing is. Use it precisely and sparingly.
Combined above-vs-below-fold example
This is the correct pattern for a page with a hero followed by content images.
The hero gets fetchpriority="high" and loading="eager"
(the default), but no decoding="async". Content images
below the fold get loading="lazy", decoding="async",
and fetchpriority="low".
fetchpriority="high", loading="eager", no async decoding
loading="lazy", decoding="async", fetchpriority="low"Quick-reference: which attributes to use where
- Every image:
alt,width,height - Above-the-fold hero:
fetchpriority="high",loading="eager"(default) — omitdecoding="async" - Below-the-fold content:
loading="lazy",decoding="async", optionallyfetchpriority="low" - All non-hero images:
decoding="async"
Preload
Even with fetchpriority="high", the browser cannot start fetching a
hero image until it has parsed the HTML far enough to encounter the
<img> tag. For large pages with significant HTML before the
hero, that can introduce measurable delay.
A <link rel="preload"> in the document <head>
tells the browser to begin fetching a resource before it would otherwise discover it.
For images, the key attributes are as="image" (required) and an
optional media attribute to scope the preload to specific viewport
conditions — useful when your hero changes between mobile and desktop.
LQIP / lowsrc — perceived performance
Objective load time matters, but so does perceived load time — how fast the page feels to the user. The Low-Quality Image Placeholder (LQIP) technique addresses this: instead of showing an empty space while the full image loads, you immediately show a tiny, blurry version of it. As the full image arrives, it fades in over the placeholder. The layout does not shift; something meaningful is visible from the very first frame.
Historical context: lowsrc
The HTML 3.2 lowsrc attribute was the original implementation: you
pointed lowsrc at a small, low-resolution version of the image and
src at the full version. Browsers would display lowsrc
immediately and swap to src when it finished loading. The attribute
was never standardised and modern browsers have dropped support for it entirely.
Modern LQIP approaches
Today's LQIP implementations use one of two strategies:
-
Inline Base64 placeholder + CSS blur. Generate a tiny version
of the image (e.g. 20×13 px), base64-encode it, and embed it in the
srcor as a CSSbackground-image. Apply a CSS blur filter to make the pixelation invisible. Swap to the fullsrconce loaded via JavaScript. - CSS background colour or gradient. Extract the dominant colour from the image and use it as a plain background while the image loads. Simpler but less smooth than a blurry preview.