The Heaviest Thing on Your Page Is Probably an Image

When we open any web page, we see text, buttons, animations, and maybe some videos. But the heaviest thing on that page is almost always an image. It is not a video, it is not a font, it is not a JavaScript bundle. It is an image file.

You can try opening browser DevTools on any website, go to the Network tab, filter by Img, and sort by file size. Chances are you’ll find something surprising: a handful of image files dwarfing everything else on the page. The JavaScript, the CSS, the fonts, all of it combined often weighs less than a single hero photograph.

This is not an accident. According to the HTTP Archive’s 2025 Web Almanach, the median desktop page now weighs 2.9 MB and has been growing by roughly 7 to 8 percent every year. Images account for over 1 MB of that, more than JavaScript in raw bytes, despite JavaScript getting all the performance attention. On mobile, where connections are slower and CPUs are weaker, the same images arrive with the same byte count.

Most developers have felt this problem. A page that loads instantly on a local dev server with a fast machine and a wired connection behaves very differently for a user on a mid-range phone, on 4G, in a country where network latency is high. The gap between “it works fine for me” and “it’s too slow for real users” is often explained entirely by images.

What’s less obvious is that compression is only half the answer. Sometimes it’s not even the more important half.


There Are Two Completely Different Ways an Image Can Be Too Big

When developers think about image optimization, they usually think about compression: run the file through a tool, reduce the quality setting, make the bytes smaller. That is a legitimate and important technique. But it is not where the biggest savings come from on most sites.

The two problems are distinct and need to be tackled in the right order:

1: The image is the wrong size for its container

The dimensions of the image file are much larger than the dimensions of the element it renders in. This is the most common problem, and it is the one that causes the most waste. I have seen cases where “developers” (mean designers) were sending 2,400 pixels of image to a browser element that will render it at 600 pixels wide. The browser downloads all 2,400 pixels, decodes all 2,400 pixels into memory, and then scales the image down for display. The extra pixels were never shown to the user. They were wasted entirely.

2: The image is the right size but encoded inefficiently

The dimensions are appropriate, but the file format is outdated (a JPEG from 2012), the quality setting is set at 100 “just to be safe”, or the file has never been compressed since it came out of a camera or design tool.

Both problems waste bandwidth. The first problem wastes far more of it, and it affects every single visitor to your site regardless of their device or connection speed.

Sizing first, compression second

The correct order is always to serve the right dimensions, then compress those dimensions efficiently. Compressing a 2,400px image that should be 400px wide still delivers five times more pixels than the browser will ever use. No amount of compression fixes that.


The Sizing Problem in Real Numbers

Let’s make this concrete, because the numbers are striking enough to change how you think about this permanently.

Take a photograph downloaded from Unsplash or exported from a camera. A typical DSLR shoots at around 7,000 by 4,700 pixels and produces a JPEG of roughly 4 to 5 MB. A photographer might export that file and a developer might drop it straight into a project as a hero image or a blog post illustration.

That image will be displayed at a maximum of around 1,200 to 1,400 pixels wide on most desktop layouts, and at 375 to 430 pixels wide on a typical mobile phone screen. The gap between the original and what actually gets rendered on mobile is not small.

Resizing that 7,000-pixel image down to 1,266 pixels wide (appropriate for a retina desktop display) reduces the file size from 4.3 MB to 495 KB. That is an 89% reduction before any compression has been applied at all. Before you touch a quality slider. Before you change the format. Just by matching the image dimensions to the container it will actually be displayed in.

Now apply compression on top of that correctly-sized image: a JPEG at quality 75 brings it to around 161 KB. The cumulative saving from sizing correctly and then compressing is roughly 96% off the original file size.

That is the order of magnitude of waste happening every day on sites where images come straight from design tools or stock libraries without any resizing step.

Loading diagram...

What “Optimization” Actually Covers

Image optimization is an umbrella term for several related but distinct problems. Treating it as “just compression” is why so many sites still have bad image performance even after someone has officially “optimized” the images.

Here is what the full picture looks like:

Dimensions. Is the image the right number of pixels for the space it occupies? A sidebar image that renders at 300px wide should not be served at 2,000px wide.

Responsive sizing. Different devices have different screens. A desktop user and a mobile user visiting the same page should receive images sized for their respective viewports, not the same file. This is what HTML’s srcset and sizes attributes solve.

Format. Is the image using a modern, efficient format? JPEG is universal but inefficient. WebP produces the same visual quality at roughly 30% smaller file sizes. AVIF pushes that to 50% smaller. Choosing the right format is the second lever after getting the dimensions right.

Compression. For lossy formats, the quality setting controls how aggressively the encoder discards data. Tuning this correctly (not too high, not too low) is compression in the traditional sense.

Loading strategy. When does the image download? Images below the fold should not block the initial page load. The loading="lazy" attribute tells the browser to defer those downloads. The hero image, by contrast, should be treated as a priority resource, not as something to lazy-load.

Delivery. Where do the images come from, and how fast does the CDN serving them respond? This is outside the scope of this series, but even perfectly-optimised images can be slow if served from a distant origin with no caching.

This series addresses all of the above except delivery, building from the fundamentals of format choice all the way to a full client-side optimization pipeline in Svelte 5.


Why This Keeps Happening

If oversized images are such a common and expensive problem, why do they persist? The answer is mostly friction, not ignorance.

A designer exports a hero image from Figma at 2x for retina screens and sends it to the developer. It looks great. The developer drops it into static/. It still looks great in development. Nobody flags it during review. It ships.

A content editor uploads a photograph for a blog post. The CMS accepts it and stores it. Nobody has configured automatic resizing. The full 5MB original gets served to every visitor.

A developer adds a new section to a marketing page, copies an image URL from the brand asset library, and pastes it into an <img> tag. The library image is 4,000 pixels wide. The section is 800 pixels wide. Nobody checked.

None of these people were being careless. They were doing their jobs correctly within the system they had. The problem is that the default state of most web publishing workflows is to serve whatever image the creator uploaded, at whatever dimensions it was created, to every device that visits the page.

Optimization requires deliberate intervention. Without a tool, a process, or a framework that makes the right thing the default, the wrong thing happens automatically.

The Chrome DevTools audit that reveals this instantly

Open DevTools on any web page and run a Lighthouse audit (DevTools → Lighthouse → Performance). Look for two specific entries in the Opportunities section: “Properly size images” and “Serve images in next-gen formats”. These two audits alone reveal most of the image waste on a typical site. Lighthouse shows the estimated savings in kilobytes and load time for each image it flags, making the problem impossible to ignore.


The Mobile Gap Makes This Urgent

Everything above is more severe on mobile, and mobile is where the majority of web traffic comes from.

A 2,400px hero image displayed in a 390px mobile viewport is transmitting more than 37 times more pixels than the browser will render. All of those extra bytes are downloaded over a mobile connection, decoded by a weaker CPU, and then discarded. The user’s battery, data plan, and time are all spent on pixels that were never visible.

Google has used mobile-first indexing since 2019, which means the mobile version of your page determines your search ranking. Image performance problems that only appear on mobile (failed Largest Contentful Paint scores, slow first contentful paint, high cumulative layout shift) directly affect where your page appears in search results, not just how fast it loads.

The practical implication is that image sizing must be solved on a per-breakpoint basis, not by picking one “medium” resolution and hoping for the best. A correctly-sized image for a desktop hero and a correctly-sized image for a mobile hero are different files. Serving both correctly is exactly what srcset and the <picture> element exist to do.


What This Series Builds Toward

The first few lessons are about foundations: understanding formats (Lesson 1), understanding the tooling (Lesson 2), and building a first working compressor (Lesson 3). The dimension and responsive sizing problems are addressed directly in Lessons 7 and 8, where you will build the ResponsiveImage and LazyImage components that handle correct sizing across all breakpoints.

By the end of the series, you will have:

  • A mental model for what format to use and why, for every type of image
  • A client-side compression pipeline that processes images in the browser with no server cost
  • Components that serve correctly-sized images to every device using srcset, sizes, and the <picture> element
  • A loading strategy that prioritises above-fold images and defers everything else
  • Passing Lighthouse audits for image-related opportunities

The goal is not to make image handling feel complicated. It is to make the right choices the automatic ones, so the default state of your SvelteKit application is “images are handled correctly” rather than “images are whatever the content editor uploaded last Tuesday.”


Key Takeaways

  • Images account for over 1 MB of the 2.9 MB median desktop page weight in 2025; they are the heaviest resource type by bytes, heavier than JavaScript.
  • Oversized images (wrong dimensions for their container) are often a bigger problem than uncompressed images. Resizing a 4.3 MB DSLR photo to its actual display dimensions reduces file size by 89% before any compression is applied.
  • Image optimization covers six distinct problems: dimensions, responsive sizing, format choice, compression, loading strategy, and delivery. Treating it as “just compression” misses the most impactful interventions.
  • The mobile gap makes this urgent: a 2,400px hero image on a 390px mobile screen transmits 37 times more pixels than the browser will render, and Google’s mobile-first indexing means this directly affects search rankings.

Further Reading

See Also