I rebuilt imagemochi's homepage three times trying to get the Lighthouse performance score above 95. The biggest bottleneck every time? Images. They accounted for 80% of the page weight.

Here's everything I learned, applicable to any website.

Step 1: Serve the Right Size

This sounds obvious but it's the #1 mistake I see. People upload a 4000x3000 photo as a hero image and let CSS scale it down to 1200x800. The browser still downloads all 4000x3000 pixels. You're making your users download 3-4x more data than they need.

Resize your images to the largest size they'll actually display at. If your hero image spans a 1200px container, make the image 1200px wide (or 2400px for retina displays). That's it.

On imagemochi, I serve different sizes based on viewport width using the srcset attribute. Mobile users get 600px images. Desktop users get 1200px. It cut my image payload by 60% on mobile.

Step 2: Use WebP (With JPEG Fallback)

I tested this across my entire site. Converting every image from JPEG to WebP at the same visual quality reduced total image weight by 31%. That translated to about 0.8 seconds faster load time on a 3G connection.

The HTML is simple:

Use the <picture> element to serve WebP to browsers that support it and JPEG to the rest. In 2026, the "rest" is basically just some embedded webviews in old apps, but it's good practice.

Step 3: Lazy Load Everything Below the Fold

Any image that isn't visible when the page first loads should be lazy-loaded. Add loading="lazy" to the <img> tag. The browser won't download the image until the user scrolls near it.

But here's the important part: do NOT lazy load images above the fold (your hero image, logo, first visible content). Those should load immediately. Lazy loading them creates a visible pop-in that feels janky and hurts your Largest Contentful Paint score.

Step 4: Set Width and Height Attributes

Always include width and height attributes on your <img> tags. This lets the browser reserve the correct space before the image loads, preventing layout shift (the annoying page jumping you see on slow connections).

I didn't do this initially on imagemochi. My Cumulative Layout Shift score was 0.35 (bad). Adding explicit dimensions brought it to 0.01 (excellent). Zero code changes otherwise.

Step 5: Compress Aggressively for Web

For web images, quality 78-82 is the sweet spot. I tested this extensively:

That jump from 95 to 82 saves 310KB per image with no perceptible difference. If your page has 10 images, that's 3MB saved. On a 3G connection, that's 8+ seconds.

Batch compress for your website

Drop multiple images, set quality, download all at once. Everything stays in your browser.

Try Compress Tool

Step 6: Consider AVIF (If You're Adventurous)

AVIF is even smaller than WebP โ€” about 20% smaller at the same quality. But encoding is slow and browser support, while growing, isn't universal yet. Chrome and Firefox support it. Safari added support in version 16.

I don't use AVIF on imagemochi yet because the encoding time makes it impractical for a browser-based tool. But for a static website where you can pre-encode everything, it's worth considering.

Real Impact Numbers

After applying all of these techniques to imagemochi:

Images are almost always the biggest performance win on any website. Before you reach for complex optimization tools, just make sure you're serving the right size, the right format, at the right quality.