Dashboard

How to Optimize Images in an AI-Built App

AI-generated apps often ship full-size photos. Here is the HTML for hero and below-fold images, a server snippet that resizes uploads, and a pre-ship checklist.

Steve Jefferson
Steve Jefferson
Developer Advocate
1 October 20261 min read

How to optimize images in an AI-built app comes down to four habits: serve a modern format like WebP at several widths, give every image explicit width and height, lazy-load images below the fold but never the hero, and resize anything users upload before you store it. Generated apps often skip all four, so a page that looks fine on your laptop downloads several megabytes on a phone.

None of this needs a new framework. It needs a few attributes, one small server function, and a checklist you run before launch. This guide gives all three, with code you can paste into a prompt for your AI builder or apply by hand.

Why generated apps ship heavy images

An AI builder optimizes for a page that renders, not for a page that loads quickly. It will happily reference a 4000-pixel photo in a 400-pixel slot. The browser downloads every byte and then scales the picture down. The user pays for pixels they never see.

The hero image: load it first, size it exactly

The hero is usually the largest visible element, so it should start loading immediately. Do not lazy-load it. Give it dimensions so the page does not jump when it appears. MDN explains why: if you set the actual size with width and height attributes, the browser knows how much space to allow for the image before it has downloaded.

html
<img
  src="/images/hero-1200.webp"
  srcset="/images/hero-640.webp 640w,
          /images/hero-1200.webp 1200w,
          /images/hero-1600.webp 1600w"
  sizes="(max-width: 700px) 100vw, 1200px"
  width="1600" height="900"
  fetchpriority="high"
  alt="Describe what is in the photo, not the keyword" />

The srcset list tells the browser which files exist, and sizes tells it how wide the slot will be, so it can pick the smallest file that still looks sharp. The MDN guide to responsive images walks through the selection steps.

Images below the fold: let them wait

Everything the user has to scroll to see can load later. One attribute does it:

html
<img
  src="/images/team-800.webp"
  width="800" height="533"
  loading="lazy" decoding="async"
  alt="Three staff members at the front desk" />

Keep the width and height here too. Lazy loading without dimensions is how layouts start to jump as the user scrolls.

User uploads: resize before you store

If your app lets people upload photos, never serve the original. Phone cameras produce very large files, and they often carry location data in the metadata. Resize on the server, convert to WebP, and let the library strip metadata, which it does by default unless you ask it to keep it. A common choice in Node is the sharp library:

javascript
import sharp from 'sharp';

export async function processUpload(buffer) {
  const sizes = [400, 800, 1600];
  const out = {};
  for (const w of sizes) {
    out[w] = await sharp(buffer)
      .rotate()                       // respect camera orientation
      .resize({ width: w, withoutEnlargement: true })
      .webp({ quality: 80 })
      .toBuffer();
  }
  return out;                          // store each size, serve via srcset
}

Also set an upload size limit, reject files that are not images by checking the content, not the file extension, and do the resizing in a background job if uploads are frequent. See how to add background jobs to an AI-built app.

A pre-ship checklist

Check

Pass looks like

Format

Photos are WebP or AVIF, not large PNG or uncompressed JPEG

Dimensions

Every img has width and height set

Responsive

Large images have srcset and sizes

Hero

Not lazy-loaded, marked high priority

Below the fold

loading set to lazy

Uploads

Resized, converted, metadata stripped, size limit enforced

Alt text

Describes the image for a person who cannot see it

Caching

Image files served with long cache lifetimes and versioned filenames

Run it on your slowest realistic connection. Your browser's developer tools can throttle the network, and the waterfall view shows which files are largest.

How to get your AI builder to do this

Paste the checklist into your prompt and ask it to audit every img tag in the project and report what fails, before changing anything. Then approve fixes in small batches. The checks also belong in your launch routine, which how to test an AI-built app before launch covers in full. If your app generates pictures rather than serving uploaded ones, see how to add image generation to an AI-built app. For the bigger picture of building with AI, start at how to build an app with AI.

FAQ

What is the best image format for a web app?

WebP is a safe default for photos, and AVIF can be smaller where your audience's browsers support it. Keep a JPEG fallback only if you need to support very old browsers.

Do I need a CDN to optimize images?

No. Correct formats, sizes and attributes come first. A CDN then helps by serving files from locations near the user and caching them.

Should every image be lazy-loaded?

No. Lazy-load images below the fold. The first large visible image should load immediately.

Why do my images make the page jump while loading?

The browser does not know their size. Add width and height attributes, or reserve the space with CSS aspect-ratio.

How did this land?

About the author

Steve Jefferson
Steve Jefferson

Developer Advocate

Steve builds something with Swarmz every week and writes up what worked, what broke, and what he'd do differently. Tutorials and hands-on guides are his lane.

Share

Get the next post in your inbox

One email a month. Product updates, engineering posts, and the best of Built with Swarmz.

I agree to receive emails about AI building tips and Swarmz product news. Unsubscribe any time.