Image Compressor

Why Image Loading Order Affects Performance More Than File Size

Compressing images is necessary but not sufficient. When images load matters as much as how large they are. Here's why loading order determines real-world page speed.

· 6 min read

Most image optimization advice focuses on file size: compress more, use WebP, reduce dimensions. This is necessary and correct. But file size isn’t the only variable that determines how fast images reach users.

Two pages can have identical total image payload sizes and wildly different performance scores, because one loads images in an order that serves the user’s perception first, and the other doesn’t.

How Browsers Load Images

When the browser parses an HTML document, it builds a list of resources to fetch—CSS, JavaScript, fonts, images. It assigns these resources priorities based on their relationship to what the user currently sees.

Images in the initial viewport get higher priority than images below the fold. Images in <link rel="preload"> tags get very high priority. Images with loading="lazy" get low priority and don’t load until they’re close to the viewport.

The challenge: the browser doesn’t always know which image matters most without hints from the developer. And even with correct prioritization, several common mistakes cause low-priority resources to block high-priority images.

The LCP Image Problem

Largest Contentful Paint (LCP) measures when the largest visible element in the viewport finishes loading. For most websites, that’s the hero image. Google uses LCP as a Core Web Vitals metric.

A slow LCP means users see an incomplete page—typically a blank space where the hero image belongs—while the browser is still loading other resources. Everything else on the page can be instantaneous; if the hero image is slow, the page feels slow.

File size is one factor. But a 100KB hero image can still produce a slow LCP if:

  1. It’s discovered late. The browser can’t start loading an image until it knows the image exists. If the hero image is loaded via CSS (background-image) or injected by JavaScript, the browser can’t discover it until the CSS or JS is parsed and executed—which may be seconds after the HTML arrives. An <img> tag in the HTML is discovered immediately.

  2. It competes with higher-priority blocking resources. Render-blocking CSS or JavaScript in the <head> delays everything. While the browser is blocked executing a synchronous script, your hero image is waiting.

  3. Missing fetchpriority="high" on the most important image. By default, browsers treat all images with similar priority. Explicitly telling the browser which image is most important via fetchpriority="high" on the hero image <img> tag causes it to be fetched before other images. This is a single attribute that can meaningfully improve LCP scores without changing file size.

The Lazy Loading Anti-Pattern

loading="lazy" is excellent—for images below the fold. A common mistake is applying it globally, including to above-the-fold images.

When loading="lazy" is on the hero image:

  • The browser defers loading until the image is near the viewport
  • “Near the viewport” for the initial page load means the image is technically already in the viewport
  • But the deferral introduces a delay before loading even starts
  • LCP scores suffer

The correct pattern:

  • Hero image and any content visible on initial load: no lazy loading (or explicitly loading="eager")
  • Everything below the fold: loading="lazy"

This sounds obvious, but it breaks in practice when:

  • A CSS framework applies lazy loading globally to all images
  • A WordPress or CMS plugin enables lazy loading for “all images” as a performance optimization
  • A developer copies the loading="lazy" attribute without thinking about placement

Preloading Critical Images

For hero images—especially those delivered from a CDN or image transformation service where the URL may be dynamic—a <link rel="preload"> in the <head> tells the browser to start fetching the image before the HTML is fully parsed:

<link
  rel="preload"
  as="image"
  href="/images/hero.webp"
  imagesrcset="/images/hero-400.webp 400w, /images/hero-800.webp 800w, /images/hero-1200.webp 1200w"
  imagesizes="100vw"
/>

This is especially valuable for hero images loaded via <picture> with multiple format options, where the browser needs to evaluate srcset before it can start downloading. A preload link bypasses this evaluation step.

Don’t preload more than one or two images—preloading too many resources competes with itself and other critical assets.

Below-the-Fold Images Loading Too Early

The inverse problem also exists. Pages with many images that are all loading eagerly (even images 1,500px below the fold) block bandwidth that should be going to LCP and initial-viewport content.

loading="lazy" on below-fold images defers them until they’re near the viewport. Bandwidth that would have gone to those images is now available for visible content, which loads faster.

For image-heavy pages (photography galleries, product listings, long articles with many inline images), lazy loading below-fold images can reduce initial page weight significantly without any change to actual file sizes.

Responsive Images and Wasted Downloads

Another loading-order adjacent problem: serving large images to small screens. If your <img> tag doesn’t use srcset and sizes, the browser downloads the largest version of every image on every device.

A user on a 390px-wide phone downloading a 2400px hero image is downloading ~6× the pixels they need. With srcset:

<img
  src="/images/hero-800.jpg"
  srcset="/images/hero-400.jpg 400w, /images/hero-800.jpg 800w, /images/hero-1200.jpg 1200w"
  sizes="100vw"
  alt="Hero image"
/>

The browser picks the right size. A 390px phone downloads the 400w version; a 1440px desktop downloads the 1200w version. This reduces actual bytes downloaded without changing the visual quality.

The Actual Priority Order

For a typical landing page, the correct image loading strategy is:

  1. Preload the hero image (if it’s in a <picture> or delivered from a CDN with variable URLs)
  2. fetchpriority="high" on the hero <img> element
  3. No lazy loading on any image in the initial viewport
  4. loading="lazy" on all images below the fold
  5. Correct srcset and sizes on all images to avoid oversized downloads on small viewports

These five steps cost nothing in additional download time and often produce LCP improvements of 500ms–2s on real devices—more than most compression optimizations deliver on their own.

File Size Still Matters

None of this replaces compression. A 3MB hero image with fetchpriority="high" still loads slowly on a mobile connection. The loading order optimizations make the most of whatever payload you’re serving—they don’t substitute for keeping that payload small.

The correct mental model: compress images to the smallest size that looks good, then apply loading order best practices to serve visible content first. Both layers of optimization are necessary; neither alone is sufficient.


Start with the payload: compress your images with the free Image Compressor, then apply loading order best practices in your HTML.

Try the Image Compressor — Free

No account needed · 100% private · Runs entirely in your browser