Back to Blog

Vyso Blog

Lazy Loading in the Modern Web: Best Practices with Vyso Images

Updated October 5, 2026
Vyso DAM Features & Innovations

Lazy loading helps when it delays images a visitor does not immediately need. Applied to a hero image or other critical content, it can make the page slower to show what matters.

The useful question is when the browser should fetch each image. Vyso can supply the requested image representation; the website or frontend framework decides how that URL appears in the page and whether loading should be deferred.

What lazy loading actually does

Image lazy loading delays fetching images that are not yet needed for the initial viewport. On a long article or product listing, it can avoid transferring distant images before the visitor approaches them. Some images may never need a transfer if the visitor leaves first.

It changes fetching time. It does not resize an image, select an encoding, change compression settings or make the CDN faster. Responsive images answer which representation the browser should choose. Lazy loading answers when fetching can be deferred.

Use native lazy loading first

The loading="lazy" attribute on <img> is widely supported in modern browsers. It is the default approach to consider for ordinary offscreen images in 2026. MDN documents the loading property and its browser availability.

<img
  src="/images/product.webp"
  loading="lazy"
  width="800"
  height="600"
  alt="Blue trail running shoe"
>

src exposes the real image URL. loading="lazy" declares that fetching can wait. width and height describe the image's dimensions so layout can reserve space, and alt supplies its alternative text.

This needs no page-authored JavaScript loader. A browser that does not support the attribute can ignore it and load the image from src normally. Add a custom implementation only for a requirement native loading cannot meet.

Lazy does not mean “fetch at the exact instant the image enters the viewport.” Browsers can request images before they become visible. The developer declares loading intent; the browser chooses the effective distance threshold and scheduling. web.dev explains browser-controlled lazy loading.

Choose lazy loading by image placement

Images well below the fold are usually good candidates: lower gallery items, later article illustrations, footer imagery and product-grid rows outside the initial viewport. Their absence should not prevent someone from using the initial screen.

Keep images likely to be visible immediately eager. This usually includes a hero, the likely Largest Contentful Paint image, necessary navigation imagery and images required for an important initial interaction. Placement depends on the rendered layout: a product row can be visible on a large screen and below the fold on a smaller one.

For a plain HTML image, omitting loading uses eager behavior. loading="eager" makes the intent explicit, which can be useful when a CMS or framework otherwise supplies lazy loading. Check the HTML it actually renders.

Image placementStarting policyWhat to verifyLikely visible immediatelyEagerInitial layout at relevant viewport sizesLikely LCP imageEager; consider high fetch priorityThe measured LCP element and its request timingClearly below the foldLazyIt arrives in time as the visitor scrollsHidden or interactive UIApplication-specificExpected interaction and the cost of loading ahead

Reserve image space under every policy. Loading intent and layout dimensions are separate decisions.

Protect LCP and use fetch priority selectively

Deferring offscreen images can reduce unnecessary competition for network resources. Deferring the LCP image does the opposite of what the initial screen needs: it can delay the image request and worsen Largest Contentful Paint.

Do not lazy-load the likely LCP image. Make its URL discoverable in the initial HTML where possible. Google's LCP guidance identifies lazy loading as a source of avoidable resource-load delay.

For an important hero that is likely to be the LCP element, a page can also supply a priority hint:

<img
  src="/images/hero.webp"
  loading="eager"
  fetchpriority="high"
  width="1200"
  height="800"
  alt="Runner 
following a rocky mountain trail"
>

loading="eager" prevents lazy deferral. fetchpriority="high" asks the browser to prioritize this image relative to other images. It is a hint, not a guaranteed scheduling command; MDN describes its relative-priority behavior.

Do not add high priority to every image or combine it with lazy loading for the critical hero. A high-priority hint does not cancel lazy deferral. Confirm the request's start time and priority in the browser's Network panel.

Reserve space with width, height and a predictable aspect ratio

A lazy-loaded image can still move nearby content when it appears. If the browser does not know how much space it needs, text and controls can shift after the image bytes arrive.

The 800 and 600 dimensions in the first example establish a 4:3 aspect ratio before loading. With responsive CSS such as max-width: 100%; height: auto, the displayed image can shrink while retaining that ratio. Use dimensions that match the delivered image, or reserve the intended layout box explicitly when its presentation differs.

A fixed crop or placeholder needs a consistent box too. A blurred placeholder does not establish layout stability unless the page reserves the final image's space. These are page-layout responsibilities, regardless of the image host.

web.dev's CLS guidance recommends image dimensions or reserved space and explains why shifts can occur after initial loading. Test while scrolling as well as during the first screen's load.

Responsive images and lazy loading solve different problems

An image can use responsive candidates and native lazy loading together:

<img
  src="/images/product-800.webp"
  srcset="
    /images/product-400.webp 400w,
    /images/product-800.webp 800w,
    /images/product-1200.webp 1200w
  "
  sizes="(max-width: 700px) 
100vw, 800px"
  loading="lazy"
  width="800"
  height="600"
  alt="Blue trail running shoe"
>

The frontend supplies srcset and sizes; the browser selects a candidate. loading expresses whether its fetch can be deferred. The example assumes the image occupies the full viewport width on smaller screens and an 800-pixel slot otherwise. Match sizes to the actual layout.

The MDN image-element reference documents these attributes. For the complete candidate-selection workflow, use responsive images from one source with Vyso.

Lazy loading does not fix oversized images

A 5000×4000 image is still oversized for a small product card when it finally loads. Deferral can postpone its transfer; it does not correct dimensions, encoding, compression or visible quality.

Request an appropriate representation independently of the loading policy. The image quality and performance guide covers dimensions and quality tradeoffs. The image-format guide covers encoding choices.

Caching is another separate layer. A cached image can still be lazy-loaded, and a lazy-loaded image can still require a network transfer. The CDN caching guide covers representation reuse and updates.

Keep lazy-loaded images crawlable

Google Search does not scroll or click through a page like a visitor. Its lazy-loading guidance recommends implementations that expose relevant content without requiring those user actions.

The native example keeps the actual URL in src. That differs from markup such as <img data-src="/images/product.webp" alt="Blue trail running shoe"> when custom JavaScript copies the URL into src only after a scroll or click event. A data-src attribute alone is not the image source.

Custom loading can be crawlable, but it must expose the resource during rendering without depending on an interaction Google does not perform. Structured data does not repair an image implementation that hides the actual resource.

Use Search Console's URL Inspection tool to check the rendered HTML and confirm that the actual image URL appears. Native lazy loading is a loading mechanism, not an indexing or ranking guarantee. The image SEO guide covers broader discovery and page-context requirements.

Use IntersectionObserver for a real custom requirement

IntersectionObserver reports changes in an element's intersection with the viewport or another container. It remains useful for custom reveal effects, visibility analytics, loading additional component logic or coordinating a special placeholder lifecycle.

It does not need to replace native image loading just for ordinary modern-browser support. A reveal animation can observe an image while the image itself continues to use loading="lazy".

A custom loader adds code, state, error handling and execution cost. Decide what happens if the script fails, an observer is disconnected too soon or an image request errors. Keep critical image URLs accessible without waiting for unnecessary application logic.

Treat carousels and hidden panels according to their interaction

An image in a tab, carousel or collapsed panel may be hidden initially but needed immediately after an action. Consider how likely the interaction is, whether adjacent slides should load ahead, whether hidden items exist in the DOM and how much media the component contains.

Hidden styling and horizontal layout can affect native loading behavior. Check the browser's requests instead of assuming that hidden means unfetched. Loading one likely next slide ahead can be a reasonable application choice; fetching an entire large gallery needs a different justification.

Test first paint and interaction separately. A page can load its initial screen quickly while making every slide change wait for an image. No single lazy-loading rule suits all of those states.

How Vyso images fit into the loading model

Vyso preserves source assets and supplies requested representations through explicit transformation chains or saved presets. The public delivery URL uses https://cdn.vyso.io/, followed by the transformation chain and asset key. The delivery documentation describes that convention.

For a 4:3 source large enough to produce an 800-pixel-wide image, this URL template requests a resized WebP representation:

<img
  src="https://cdn.vyso.io/
resize:width=800/
format:type=webp/ASSET_ID.jpg"
  loading="lazy"
  width="800"
  height="600"
  alt="Blue trail running shoe"
>

Replace ASSET_ID.jpg with the stored source's actual asset key. The final key identifies the source; format:type=webp explicitly requests the output encoding. Confirm the delivered dimensions and use appropriate alt text for the real image.

Vyso supplies the representation. The page supplies loading, fetchpriority, dimensions, responsive markup and placement. If this image becomes the hero, change the page's loading policy. Vyso does not infer its viewport position or choose lazy versus eager loading from the delivery URL.

Test the rendered page, not the attribute alone

Inspect the generated HTML, especially if a CMS or framework sets loading defaults. Identify the measured LCP element at relevant viewport sizes and check when its image request starts. Then scroll through the page and exercise galleries, tabs and panels while watching requests and layout movement.

Compare under consistent cache and network conditions. A warm-cache test can conceal a transfer delay, while an initial-load-only audit can miss shifts introduced later by lazy-loaded images. Use lab traces to diagnose behavior and available field data to assess actual visits.

The current Core Web Vitals are LCP for loading, INP for interaction responsiveness and CLS for visual stability. Lazy loading does not guarantee an improvement in any of them. For this change, pay particular attention to the LCP image's request and layout shifts when deferred images appear.

Lazy-loading checklist

  1. Identify the likely LCP image in the rendered layout.

  2. Keep critical initial-viewport images eager.

  3. Add loading="lazy" to suitable offscreen images.

  4. Reserve space with matching dimensions or a predictable layout box.

  5. Use srcset and sizes separately for responsive candidate selection.

  6. Keep actual image URLs discoverable without a scroll or click.

  7. Use custom JavaScript only for behavior native loading does not provide.

  8. Request appropriately sized and explicitly encoded Vyso representations.

  9. Test LCP, scrolling, layout stability and interactive media under realistic conditions.

Defer images that are not immediately useful and keep critical images eager. Let the page control loading while Vyso supplies the representation it needs.

Keep going

Make the media library less work.

See how Vyso brings search, enrichment, cleanup, and delivery into one product.

Start free