Helpful information ...
Lazy loading images: when to defer, when not to
Lazy Loading Images: When to Defer Them, and When Not To
Use loading="lazy" for every image that isn't visible in the initial view of the page. For the hero image or any other LCP element, skip this setting — instead, signal priority to the browser with fetchpriority="high" and <link rel="preload">. On top of that, always set width and height, or an aspect-ratio, on every image, to prevent layout shifting while it loads.
In short:
- For critical images, such as hero elements, it's recommended to use
fetchpriority="high"and<link rel="preload">instead of lazy loading, to avoid hurting LCP.- By default, WordPress has automatically added the
loading="lazy"attribute to images in content since 2020; on hero images, it needs to be manually excluded via code.- Using lazy loading reduces bandwidth usage and speeds up the initial page render, but it can hurt visibility metrics if applied to key images.
- The simplest way to implement lazy loading is with the
loading="lazy"attribute on<img>; for finer control, the Intersection Observer API is useful.- To test lazy loading's impact on page speed, Lighthouse or PageSpeed Insights are recommended, comparing LCP and Cumulative Layout Shift values in particular.
Table of Contents
- What image lazy loading is, and how the browser decides when to load one
- The benefits and limits of lazy loading
- How to implement it: the native attribute, Intersection Observer, or JS libraries
- Common lazy loading mistakes and how to fix them
- Advanced practices: fetchpriority, preload, and CDN
- How WordPress and other CMSs handle lazy loading
- How to test lazy loading's impact on Core Web Vitals
- Moxy-web's experience optimizing images and site speed
- Perspective: when the native solution is enough, and when to call in an expert
- Moxy-web's offering: implementing, testing, and maintaining image optimizations
- Sources
- Frequently asked questions
What image lazy loading is, and how the browser decides when to load one
Lazy loading means the browser postpones loading non-critical resources — mainly images outside the visible area — until the user actually needs them. Instead of pulling in all fifty images on a page at once during load, the ones further down only get downloaded once the user scrolls close enough to reach them.
There's a simple native attribute for this, supported by every modern browser:
loading="lazy"on an<img>or<iframe>element tells the browser to decide on its own when an image is close enough to the visible area to load.- The browser uses internal logic similar to the Intersection Observer principle, tracking an element's distance from the edge of the screen and triggering the load before the user actually sees the image.
- The advantage of the native approach over JavaScript libraries is that there's no extra script for the browser to download and run before lazy loading even starts working.
The result is less work for the browser and simpler code for the developer.
The benefits and limits of lazy loading

Bandwidth savings are greatest when a page has a lot of images below the fold. The average page's weight grew from roughly 250 KB to 900 KB on desktop between 2011 and 2019, and from 100 KB to 850 KB on mobile. Without lazy loading, all that weight would load on the very first visit, even if the user never scrolls to the bottom.
That said, lazy loading isn't without risk:
- It speeds up the initial page render, since the browser spends less bandwidth on images the user might never actually see.
- It can hurt Largest Contentful Paint (LCP) if accidentally applied to an image that's part of the first screen.
- It's not suited to hero images, main banners, or any element visible the moment the page loads.
The line between benefit and harm, then, comes down to where an image sits on the page, not the technique itself.
How to implement it: the native attribute, Intersection Observer, or JS libraries
For most modern sites, a single attribute is enough. For special cases, there are two additional routes.

1. The native loading="lazy" for standard cases
<img src="image.jpg" loading="lazy" width="800" height="600" alt="Image description">
This is enough for nine out of ten cases. Chrome's own testing shows that on 4G networks, 97.5% of lazy-loaded images fully load within 10 milliseconds of becoming visible, meaning the user practically never notices any delay.
2. Intersection Observer for finer control
When you need custom logic — loading an image 300 pixels before it enters the viewport, say, or loading a CSS background-image, which the native attribute doesn't cover — the Intersection Observer API is the tool to reach for. This approach takes a few lines of JavaScript, but gives the developer full control over the loading threshold.
3. Libraries like lazysizes or yall.js for older cases
For older browsers without native attribute support, or for special elements like a video's poster, libraries such as lazysizes or yall.js are used, which also build on the Intersection Observer principle under the hood.
For responsive images, lazy loading works seamlessly alongside srcset and sizes:
<img srcset="small.jpg 480w, large.jpg 1080w"
sizes="auto"
loading="lazy"
width="1080" height="720"
src="large.jpg" alt="Responsive image">
This lets the browser choose the right image size based on screen width, while also only loading it once that makes sense.
Common lazy loading mistakes and how to fix them
The most common mistake is applying loading="lazy" to an image that's an LCP candidate — the largest visible element in the initial page view. In testing, the median LCP on pages that misused lazy loading was 3,546 milliseconds, compared to 2,922 milliseconds on pages without this mistake. The difference comes from the browser discovering the hero image too late, since it's waiting to assess its visibility first.
Other typical pitfalls:
- A missing
widthandheight(oraspect-ratio) causes Cumulative Layout Shift, since the browser doesn't reserve space for the image in advance. - Carousels and sliders often hide the first image behind a CSS color, which confuses the lazy loading logic and causes the image not to load in time.
- Fast scrolling on long pages can briefly show empty space if the loading threshold is set too close to the visible area.
Pro tip: Manually check every hero element. If an image is the first thing a user sees, loading="lazy" simply doesn't belong there, no matter how tidy the code looks.
Advanced practices: fetchpriority, preload, and CDN
For images that are LCP candidates, combining fetchpriority="high" with <link rel="preload"> often delivers the most reliable results. This explicitly tells the browser to treat this image as a priority, instead of waiting for the standard resource-ranking process.
<link rel="preload" as="image" href="hero.jpg" fetchpriority="high">
<img src="hero.jpg" fetchpriority="high" width="1200" height="600" alt="Main image">
A few additional techniques worth knowing:
- The
sizes="auto"attribute, combined withsrcsetandloading="lazy", helps the browser choose the right image size only after the layout has been calculated, which prevents downloading oversized files. - A good CDN and a properly configured cache reduce the delay in displaying an image, since the file is served from a server geographically closer to the user.
- Lazy loading
<iframe>elements, such as embedded YouTube videos, can save over 500 KiB on the initial page load.
For a broader picture of how these techniques interact with image format and compression, see this guide to optimizing web images for faster sales.
How WordPress and other CMSs handle lazy loading
WordPress Core has built lazy loading into the system's core and adds loading="lazy" to images in post content by default. The system does this server-side, when generating the HTML, before the page even reaches the browser.
For content editors and developers, this has a few practical implications:
- The default setting is good for most images within the body of an article, since they're rarely part of the first screen.
- An image block acting as a featured image or hero element needs to be manually excluded from lazy loading, otherwise WordPress will add the attribute to it regardless.
- This exclusion is typically set through a filter in the theme's or a plugin's code, not through the user interface, so it's worth involving a developer for critical pages.
The same precaution applies to other content management systems that automatically add the loading attribute to every image in galleries or post listings.
How to test lazy loading's impact on Core Web Vitals
A feeling that the implementation worked isn't enough until you confirm it with measurement.
- Run Lighthouse or PageSpeed Insights before and after the change, and compare the LCP, CLS, and INP values.
- Open the Network tab in your browser's developer tools and check that below-the-fold images actually load only as you scroll, not all at once.
- Repeat the test in production, since local testing often hides issues with real network traffic and CDN caching.
- After every change, keep monitoring the data for a few more days to catch any regression among real users.
You'll find a detailed measurement process in the guide to a Core Web Vitals audit for developers and marketers.
Moxy-web's experience optimizing images and site speed
The company builds websites, online stores, and applications, treating loading speed as a key part of every project. This involves using the latest technologies and integrations, tailored to each individual client.
-
The company's technical content also covers the broader topic of image optimization for faster sales, including server-side caching in WordPress.
-
The approach is based on developing custom code rather than using pre-built platforms, which allows lazy loading to be precisely configured to the site's actual layout.
Perspective: when the native solution is enough, and when to call in an expert
For a simple blog or brochure site, native loading="lazy" is entirely sufficient. For an online store or landing page, where LCP is directly tied to sales, an incorrect setting costs more than a professional review would.
— Ziga
Moxy-web's offering: implementing, testing, and maintaining image optimizations
Since the difference between correctly and incorrectly configured lazy loading often comes down to a single attribute — yet can mean the difference between a fast and a slow sales page — many businesses prefer to hand this off to someone who works with code every day. When building websites, stores, and applications, image optimization and a Core Web Vitals audit are built directly into the project, with the code developed without relying on pre-made templates, allowing for precise adjustments to each individual layout. The service can also include hosting, domain registration, and regular maintenance, so site speed doesn't degrade with future updates. Loading speed directly affects traffic and conversions, as also confirmed by an analysis of the link between site speed and sales. If you'd like to see how a speed audit and an overhaul of your image settings would affect your site, check out the offering on the Moxy-web homepage and ask for a project assessment.
Sources
Frequently asked questions
Does lazy loading slow down image loading?
No — quite the opposite, it speeds up the initial page render, since the browser doesn't transfer images that aren't immediately visible. The delay in loading them later is negligible, since on 4G networks, 97.5% of lazy-loaded images load within 10 milliseconds of becoming visible.
Why shouldn't I use loading="lazy" on a hero image?
Because the browser then discovers the image too late, hurting LCP. Testing shows the median LCP with lazy loading misapplied was 3,546 milliseconds, compared to 2,922 milliseconds with the correct setting.
Does WordPress apply lazy loading automatically?
Yes — WordPress Core has added the loading="lazy" attribute to images in post content by default since 2020. For hero images, this setting needs to be manually turned off through theme or plugin code.
What should I use instead of lazy loading for critical images?
For LCP images, use a combination of fetchpriority="high" and <link rel="preload">, which tells the browser to load the image as a priority. This approach works better than the browser's default behavior with no extra instructions.
How do I check whether lazy loading is hurting my site?
Run Lighthouse or PageSpeed Insights before and after the change, and compare the LCP and CLS values. For help interpreting the results, technical support and maintenance services that include speed reviews are available.
Recommended