murattunalı.

Using lazy loading correctly.

Lazy loading means a resource is not downloaded until the user approaches it — and applied in the wrong place, it breaks performance instead of improving it.

The idea is simple and correct: there is no point downloading an image the user will never see. If a long page holds twenty images and the user sees only the first three, seventeen downloads were wasted — in bandwidth and in main-thread time alike.

Modern browsers offer this with a single attribute; no extra library needed. But exactly that ease produces the most common mistake: applying the attribute to all images in bulk.

Never on a resource in the viewport

The rule is one sentence: no resource inside the viewport gets lazy-loaded. The reason ties directly to LCP — lazy loading delays the browser’s discovery of the resource and the start of its request. If an image in the viewport is needed immediately anyway, delaying it is a net loss.

The hero image is almost always the LCP element, and lazy-loading it directly stretches LCP. This is a measurable, repeatable regression — and the clearest example of a well-intentioned optimization slowing a site down.

  1. The image in the viewport — NO lazy loading. Raise its priority if needed.
  2. Just below the viewport — borderline; the browser already starts loading a certain distance ahead.
  3. Images deep in the page — lazy loading YES; the biggest gain is here.
  4. Embedded frames — video players, maps, social boxes. Definitely yes; these are the heaviest resources.
  5. Background images — the attribute does not work; a separate technique is needed.

The fourth item is the largest single win on most sites. An embedded video player brings hundreds of kilobytes of script with it, and that cost is paid even if the user never plays the video. Loading the player only on click can halve the page weight.

Size reservation is mandatory

Every lazy-loaded resource is a layout shift candidate: when it arrives it starts occupying space and pushes everything below it. Lazy loading and size declaration are therefore an inseparable pair — one must not be applied without the other.

For images the fix is writing the width and height attributes; the browser computes the aspect ratio from the two and reserves the right space even in a responsive layout. For embedded frames, a container must be given a ratio.

On this site the live preview videos are built exactly this way: the videos are not preloaded, their place is reserved with a poster frame, and with the reduced motion preference on, the video never loads. All three behaviors are measured separately in the verification suite.

Lazy loading and size declaration are an inseparable pair; one is not applied without the other.

Content visibility

Beyond images, there is a win for the page’s sections that sit entirely off-screen: the browser can be instructed to defer their layout and painting. On long pages this shortens the first paint markedly.

The same trap applies here: if the space the deferred section will occupy is not declared, the layout changes when the user scrolls there. Giving an estimated size closes that risk.

There is also an accessibility dimension, and it gets missed: deferred content may not be found by in-page search. When the user searches a word with the browser’s find function, text in a not-yet-rendered section is not found. On long documents that is a real usability loss, and it limits where the technique should be applied.

How early to load

Lazy loading does not mean “wait until visible”; browsers start loading a certain distance ahead. Otherwise the user scrolls into a blank area and the image arrives late — the most complained-about side effect of lazy loading.

The browser’s default lookahead distance varies with connection speed and is usually reasonable. When manual control is needed, a custom distance can be defined with an observer — but before changing the default, measure whether there really is a problem.

The practical test: scroll the page at normal speed and check whether the images are ready in place. If you see blank areas, the distance should grow; if you never see one, loading probably starts too early and the savings evaporate.

A measurement note: lazy loading’s gain should be measured in total bytes, not by looking at the first-load value in page weight reports. The first load always looks good — the real question is what the total is when the user scrolls the page to its end.

Auditing: seeing what is lazy

Seeing whether lazy loading is applied correctly on a site takes a few minutes. In the browser’s network panel, check which images download when the page opens; if images outside the viewport are on the list, lazy loading is not working.

The reverse check matters more: if the images inside the viewport are NOT on the list, lazy loading was applied to them by mistake and LCP is suffering. That is the typical result of bulk application — and it never shows in reports.

The third check is the embedded frames: if a video player or map script comes down at page open, that resource has not been lazified. These are usually the heaviest items, and the biggest win sits there.

These three checks can turn into an audit list and be automated: the list of resources downloading at page open is extracted and compared with the expected list. When an unexpected resource comes down, the test goes red.

One closing principle: lazy loading is a decision, not a default. The right place between “lazify everything” and “lazify nothing” depends on which of the page’s resources sit in the viewport, and that is determined per page template. No performance setting applied in bulk beats a decision made by measurement.

A practical checklist

Turning this page into an audit step, here is what to check in the lazy loading setup. The list is kept short because long lists do not get walked; six items fit in one sitting.

  1. Is it applied to images in the viewport — if so, it must be REMOVED.
  2. Is the hero image high priority?
  3. Are the deep images lazy — if not, the biggest gain is there.
  4. Are the embedded frames lazy — video, map, social box.
  5. Is every lazy resource’s space reserved?
  6. Do blank areas appear while scrolling — if so, the lookahead distance should grow.

The first and third items are each other’s opposites, and both must be checked: lazy loading applied in the wrong place breaks LCP; lazy loading not applied burns bandwidth.

SOURCES