Unoptimized images
Images are usually the heaviest thing on a page, and when they ship without width/height they shift the layout as they load, when they ship at 2400px in a 400px slot they waste most of what they download, and when they load eagerly below the fold they steal bandwidth from what’s actually visible. AI scaffolds paste raw <img src> tags with none of the attributes that make images fast.
Symptoms
How VibeCheck catches it
In your widget · Problems
To your coding agent · MCP
The same string in your widget and in your agent’s context — no screenshot, no copy-paste.
Root causes
The fix
Give every image explicit intrinsic width and height so the box is reserved before load, add loading="lazy" to below-the-fold images, serve the image at roughly the size it’s displayed (2× max for retina) in a modern format (WebP/AVIF), and use srcset/sizes for responsive delivery.
- Add
widthandheightattributes matching the file’s real aspect ratio - Add
loading="lazy"to images below the fold (never to the LCP image) - Resize and re-encode to WebP/AVIF at the displayed size, with
srcsetfor density
<img
src="/hero-800.webp"
srcset="/hero-800.webp 800w, /hero-1600.webp 1600w"
sizes="(max-width: 600px) 100vw, 800px"
width="800" height="450"
loading="lazy" decoding="async"
alt="Product dashboard" />FAQ
- Should I lazy-load every image?
- No — never lazy-load your LCP (largest, above-the-fold) image; that delays the most important paint. Lazy-load only images below the fold. In Next.js, mark the hero with
priority. - What does "oversized" mean exactly?
- VibeCheck flags an image whose natural (file) dimensions are more than twice its rendered (displayed) size — you’re downloading at least 4× the pixels you show. Resize to the displayed size, 2× for retina.
- Why does missing
width/heightcause layout shift? - Without dimensions the browser doesn’t know the image’s size until it downloads, so it reserves no space and everything below jumps when the image arrives. The attributes let it reserve the box up front.