Native image lazy-loading in WordPress

An image halfway down an article does not usually need the same treatment as the image introducing the page. That distinction is the useful part of lazy-loading. The aim is to let the first screen appear promptly while postponing some of the work further down.

It is tempting to treat this as a switch to enable everywhere. In a WordPress theme, I would start by looking at the HTML already being produced. Core may already be making the decision, and another plugin or script can complicate behaviour that was working reasonably well.

Start with the image WordPress already knows

For an image in the Media Library, use a native Image block or an attachment-aware theme function. WordPress’s attachment image function can supply dimensions and responsive image information from the attachment metadata. Rebuilding that output from a file URL alone discards useful context.

<?php
$image_id = get_post_thumbnail_id();

if ( $image_id ) {
    echo wp_get_attachment_image( $image_id, 'large' );
}

This example belongs in a PHP template and renders the current post’s featured image at a registered size. It deliberately leaves loading decisions to WordPress. The right size still depends on the actual layout; a small card and a full-width introduction do not need identical output.

Keep the first important image available

An image visible immediately, especially one that becomes the page’s largest visible element, should not be held back simply because a global rule says all images must be lazy. Check the rendered page at both a narrow and wide viewport before deciding which image has that role.

WordPress’s loading optimisation API manages attributes including loading, fetchpriority and decoding. It explicitly treats loading="lazy" and fetchpriority="high" as conflicting instructions. An exception should target a known image in a known context, rather than every image sharing a CSS class.

Give later images enough information

For an ordinary image outside WordPress’s attachment output, the relevant HTML can be as small as this. The filename and dimensions are illustrative; use the actual file and its intrinsic proportions.

<img
  src="article-detail.webp"
  alt="Close-up of the navigation sketch"
  width="1200"
  height="800"
  loading="lazy"
>

The native loading attribute lets the browser decide when an off-screen image is near enough to fetch. It does not promise that the request waits until the image is visible. Width and height also give the browser an aspect ratio before the download finishes, helping reserve the correct space.

Keep a real src rather than making the image depend on a script copying a value out of a data attribute. That keeps the markup understandable and avoids introducing a second loading mechanism without a specific need.

Check the page, not just the attribute

Use the network panel with its cache disabled, reload at the top, then scroll. Check that the first important image starts promptly, later images arrive in time, and the page does not move around as they appear. Repeat with a slower connection and the mobile layout. A successful screenshot alone does not show when a request began.

Lazy-loading does not make an oversized file smaller. Dimensions, compression and the browser’s selected responsive source still matter. I cover that separate part of the job in WebP images and the WordPress upload workflow.

A good result is fairly uneventful: the opening content appears without waiting for the whole gallery, and later images are ready when they are needed. There should be less loading machinery to maintain, not another layer to debug.

More about me