What is Lazy Loading?

Lazy loading delays images, iframes and scripts until the user scrolls near them. Learn loading="lazy", Intersection Observer and the LCP trap.

What is lazy loading?

Lazy loading is a technique that delays loading a resource until it is needed, usually until the user scrolls close to it. Images, iframes and chunks of JavaScript that start off-screen are fetched later instead of up front, so the browser has less to download before the visible part of the page is ready.

How lazy loading works

Images and iframes: the loading attribute

Adding loading="lazy" to an <img> or <iframe> tells the browser to defer it until the element is near the viewport. The browser decides how near, and you cannot change that distance. Image lazy loading works in Chrome 77, Edge 79, Firefox 75 and Safari 15.4 or later; a browser that does not know the attribute ignores it and loads the image normally (source: web.dev).

<img src="team.jpg" loading="lazy" alt="Our team" width="800" height="600">

Always set width and height. Without them the browser cannot reserve space, and the page jumps when the image arrives, which raises your Cumulative Layout Shift. See image size for how to pick the dimensions.

JavaScript: Intersection Observer and dynamic import()

For anything the attribute does not cover, such as a video player or a heavy widget, an Intersection Observer reports when an element enters or leaves the viewport, and your code starts the work at that moment (see MDN on lazy loading). A rootMargin starts the load a little before the element is visible, so users rarely see an empty box.

const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      entry.target.src = entry.target.dataset.src;
      observer.unobserve(entry.target);
    }
  });
}, { rootMargin: '200px' });
document.querySelectorAll('img[data-src]').forEach((img) => observer.observe(img));

In a single-page app, dynamic import() does the same for code: a route's bundle is only downloaded when the user navigates there, which keeps the first download small.

const Settings = () => import('./Settings.js');

Example: a long article page

An article has one hero image and fifteen images further down, plus an embedded video. Only the hero image needs to be there for the first view. Leave the hero eager (the default) and mark the other fifteen images and the video iframe with loading="lazy". A reader who stops after the intro never downloads them; a reader who scrolls gets each one just before it appears.

Common lazy loading mistakes

  • Lazy-loading the hero or LCP image. Images likely to be in view on load should not be lazy, because the browser delays fetching exactly the element your Largest Contentful Paint is waiting for (web.dev gives the same advice).
  • No width and height. Layout shifts as each image lands.
  • Lazy-loading everything. The first screen should load as normal; defer only what is below it.
  • Hiding important content behind scroll-triggered scripts. Keep body text in the initial HTML and lazy-load media, not copy.
  • Starting too late. A zero margin means users scroll into blank space and wait. Start loading slightly early.
  • Thinking it removes work. Lazy loading postpones the download. A slow script that runs later is still slow.

Lazy loading, testing and monitoring

Lazy-loaded files are requested on scroll, so a test that never scrolls never fetches them. A page speed audit can therefore look lighter than what a reader who scrolls the whole page actually downloads. For the general speed picture, 10 steps to improve website speed and why image optimization matters cover the wider checklist.

To see the effect on real metrics, check LCP and CLS for your page with the free Core Web Vitals checker, which reads Chrome UX Report field data. To keep watching it after a release, LoadFocus page speed monitoring runs scheduled Lighthouse audits and alerts you when a metric moves.

FAQ: Lazy loading

Should I add loading="lazy" to every image?

No. Images at the top of the page, especially the one that is your Largest Contentful Paint element, should load normally. Use lazy loading for images below the first screen.

Does lazy loading help or hurt SEO?

It helps when it only defers images and iframes below the fold, because the page gets faster. It hurts when you hide text or links that must be indexed behind a script that waits for a scroll. Keep important content in the initial HTML.

What is the difference between lazy loading and code splitting?

Code splitting is a build step that cuts your JavaScript into separate files. Lazy loading is the runtime choice to download one of those files only when it is needed. Bundlers do the first, dynamic import() does the second.

Can I lazy-load CSS background images?

Not with the loading attribute, which only applies to images and iframes. Use a real img element when you can, or use an Intersection Observer to set the background when the element nears the viewport.

Which browsers support loading="lazy"?

Chrome 77, Edge 79, Firefox 75 and Safari 15.4 and later support it for images. Others ignore the attribute and load the image right away, so nothing breaks.

How fast is your website?

Elevate its speed and SEO seamlessly with our Free Speed Test.

Free Website Speed Test

Analyze your website's load speed and improve its performance with our free page speed checker.