Image and asset optimization
Ship the right format and dimensions at the right compression, deliver and cache efficiently, and prioritize the LCP image.

WHAT YOU WILL BE ABLE TO DO
Learning outcomes
- Explain image and asset optimization in plain language.
- Connect the behavior to the underlying browser or framework model.
- Implement the core pattern and reason through edge cases.
- Answer common follow-ups without relying on memorized phrases.
01Explain it simply
Images and media are usually the largest bytes on a page. Optimizing them means shipping the right format, at the right compression, at the right dimensions, delivered and cached efficiently — and prioritizing the one image that determines when the page looks loaded.
One-line definition: Ship the right format and dimensions at the right compression, deliver and cache efficiently, and prioritize the LCP image.
02Mental model
Modern formats (AVIF, then WebP, with a JPEG or PNG fallback) cut bytes substantially at equal quality. Compression is a quality-vs-size dial tuned per image type, not a fixed setting. Images should be encoded near their maximum displayed dimensions. An image CDN can do format negotiation, resizing, and compression on the fly from one source file. The image most likely to be the Largest Contentful Paint element should be discoverable early and preloaded; everything below the fold should be lazy.
03Step by step
- Serve AVIF or WebP with a fallback, negotiated by the CDN or a picture element.
- Encode each image near its largest real display size, with quality tuned to the content.
- Provide width-descriptor srcset candidates so smaller viewports download smaller files.
- Identify the LCP image and preload it or mark fetchpriority high; lazy-load the rest.
- Serve from a CDN with long cache lifetimes and content-hashed URLs for cache busting.
- For decorative or vector art prefer SVG; inline tiny SVGs, cache larger ones.
04Working example
<link rel="preload" as="image" href="/hero-800.avif" fetchpriority="high" />
<img src="/hero-800.jpg" srcset="/hero-400.avif 400w, /hero-800.avif 800w, /hero-1600.avif 1600w" sizes="(min-width: 768px) 50vw, 100vw" width="800" height="450" alt="Product hero"/>The preload makes the browser start downloading the hero image immediately at high priority instead of waiting for layout, which is what improves LCP. The srcset offers AVIF candidates at three widths so a phone fetches roughly 40KB instead of the 200KB desktop file, and width/height reserve space so nothing shifts.
05Where it is used
- Reducing total page weight, usually the single biggest lever
- Improving LCP by prioritizing the hero image's request
- Cutting mobile data usage with correctly sized responsive candidates
- Serving one source asset in many optimized forms via an image CDN
06Common mistakes
- Shipping a 3000px image into a 400px container and letting CSS scale it down — the bytes were already downloaded
- Lazy-loading the LCP image, delaying the exact thing the metric measures
- One global compression setting instead of tuning per image type
- Not cache-busting with a content hash, so a changed image is served stale from the CDN
07Interview answer
Order the levers by impact: right dimensions and format first, then compression, then delivery and caching, then prioritization. Call out that the LCP image needs the opposite treatment — eager, preloaded — from everything else.
A hero image is set to loading="lazy" for consistency with the rest of the page's images, and LCP is poor. Why?
loading="lazy" defers the request until the browser calculates the image is near the viewport, which delays the download of the largest above-the-fold element; the LCP image should load eagerly and ideally be preloaded, the opposite of below-the-fold images.
DDConcept deep dives
Deep dive 1
Dimensions and format dominate; everything else is smaller
Image bytes scale roughly with pixel count, so encoding at the real display size instead of shipping a huge file that CSS scales down is often a multiple-x reduction — far more than tuning a quality slider. Modern formats (AVIF, then WebP, with a fallback) add another large cut at equal quality. Compression tuning, CDN delivery, and caching matter, but they're refinements on top of getting size and format right.
- A 4000px image in a 600px slot has already wasted its bytes before CSS touches it.
- Serve AVIF or WebP with a universally supported fallback and let the browser choose.
- An image CDN turns one source file into on-demand sized, formatted, compressed variants.
Deep dive 2
The LCP image is the exception to every lazy-loading rule
Below-the-fold images should be lazy-loaded to save bandwidth and main-thread decode time. The Largest Contentful Paint image needs the opposite: preload it or set fetchpriority high so its request starts before layout, because the metric essentially measures when that image finishes rendering. Applying blanket lazy-loading to the hero image directly regresses LCP.
- Identify the likely LCP element and prioritize its request explicitly.
- Every other image gets loading=lazy plus reserved space to avoid shift.
- width and height (or aspect-ratio) on every image prevents the content jump scored as CLS.
Deep dive 3
Delivery and caching are about not paying twice
Serving from a CDN puts bytes near the user; content-hashed filenames let those bytes cache effectively forever, since a changed image gets a new URL and a new cache entry. Without hashing you're forced to choose between short cache lifetimes and users seeing stale images after an update. This layer doesn't shrink any single image, but it removes repeat downloads across visits and users.
- Long max-age plus immutable is safe when the filename contains a content hash.
- The CDN can also handle format negotiation and resizing centrally.
- Vector art (icons, logos, diagrams) should be SVG — resolution-independent and usually smaller.
QAInterview questions and model answers
Attempt each answer aloud before opening it. The model answer shows the depth and precision expected in an interview; it is not a script to memorize.
Intermediate · Conceptual · 1 min · Question 1Order the image optimization levers by typical impact.Open model answer
Model answer
Correct dimensions first — never ship a 3000px file for a 400px slot. Then modern format (AVIF or WebP with fallback). Then compression tuned per image type. Then delivery: CDN, long cache lifetimes, content-hashed URLs. Then prioritization of the LCP image. Dimensions and format usually dwarf the rest.
Open question page →Intermediate · Conceptual · 1 min · Question 2Why does encoding an image at display size matter more than compression settings?Open model answer
Model answer
Resolution scales bytes roughly with pixel count, so halving each dimension is about a 4x reduction — far larger than the difference between two reasonable quality settings. CSS scaling a large image down wastes bytes that were already downloaded and decoded.
Open question page →Intermediate · Conceptual · 1 min · Question 3How should the Largest Contentful Paint image be handled differently from other images?Open model answer
Model answer
It should load as early as possible — preloaded or with fetchpriority high — because the metric essentially measures when it finishes rendering. Every other image, especially below the fold, should be lazy-loaded so it doesn't compete for that early bandwidth.
Open question page →Intermediate · Conceptual · 1 min · Question 4What does an image CDN do for you?Open model answer
Model answer
From one high-quality source file it negotiates format based on Accept headers, resizes to requested dimensions, applies compression, and caches each variant at the edge. It replaces a build-time matrix of pre-generated sizes and formats with on-demand transformation.
Open question page →Beginner · Conceptual · 1 min · Question 5When should you use SVG instead of a raster format?Open model answer
Model answer
For icons, logos, diagrams, and other vector art: SVG scales to any size without extra bytes, stays crisp at any density, and is often smaller for simple graphics. It's the wrong choice for photographs, which have no vector representation.
Open question page →Intermediate · Conceptual · 1 min · Question 6Why does an image need explicit width and height even with responsive CSS?Open model answer
Model answer
So the browser can compute the aspect ratio and reserve the correct layout box before the file downloads, preventing the content jump measured as Cumulative Layout Shift. The attributes set the ratio; CSS still controls the final rendered size.
Open question page →Advanced · Conceptual · 1 min · Question 7What's the trade-off of aggressive image lazy-loading?Open model answer
Model answer
It saves bandwidth and defers work for offscreen images, but applied to above-the-fold or LCP images it delays exactly what the user is waiting to see. It also needs a reserved space or it causes layout shift when images pop in during scroll.
Open question page →Intermediate · Conceptual · 1 min · Question 8How do content-hashed filenames help image performance?Open model answer
Model answer
They let the CDN and browser cache an image effectively forever, since a changed image gets a new filename and thus a new cache entry. Without them you're stuck choosing between short cache lifetimes and users seeing stale images after an update.
Open question page →Advanced · Conceptual · 1 min · Question 9What causes a large decode cost even when an image downloads quickly?Open model answer
Model answer
Very high-resolution images take significant main-thread time to decode into a bitmap, which can jank scrolling or delay paint. Serving appropriately sized images avoids it; decoding="async" can also let the browser schedule the decode off the critical path.
Open question page →Intermediate · Conceptual · 1 min · Question 10Should every image be converted to AVIF?Open model answer
Model answer
AVIF gives the best compression for most photos, but encode time is high and some very simple graphics compress better or equivalently as optimized PNG or SVG. Serve AVIF with a WebP and then a universally supported fallback, and let the browser pick.
Open question page →SCScenario questions
Scenario 1
A product page scores poorly on LCP and total page weight. Audit shows the hero is a 2.4MB 4000px PNG scaled to 600px by CSS, and 30 thumbnail JPEGs load eagerly on page load.
- Re-encode the hero near its real display size in AVIF with a fallback.
- Preload the hero and set fetchpriority high.
- Add width and height to reserve its layout box.
- Lazy-load the 30 thumbnails and reserve their space.
- Serve everything from a CDN with content-hashed, long-lived URLs.
Reveal worked answer
The hero alone is most of the problem: a 4000px PNG for a 600px slot. I'd re-encode it near display size as AVIF with a JPEG fallback — that's a huge reduction before touching quality settings — then preload it with fetchpriority high so its request starts before layout, since that's what LCP measures, and set width and height to stop the shift. The 30 thumbnails shouldn't load until they're near the viewport, so I'd lazy-load them with reserved space. CDN delivery with hashed filenames then lets all of it cache aggressively.