◉ANTIGRAVITY LABJP
Articles/Tips & Best Practices
✦ Tips & Best Practices/2026-10-15Intermediate

The Images Weren't Broken, My Way of Checking Them Was: Doubting the iframe First, Then Reading currentSrc

A record of misdiagnosing healthy images as unloaded because I audited them through an iframe in a separate tab. In a hidden frame, naturalWidth reads 0 at a rendered width of 0, and lazy images never start. Here are the numbers I reproduced locally, an audit script that reads currentSrc and rendered width on the real page, and the trap of bulk-replacing CSS values with a regex.

image auditlazy loadingsrcsetPlaywright3indie dev20Antigravity383

✦ Premium Article

I was auditing the images on my own site one evening. What I wanted to know was simple: do the images on every page actually show up, on both a phone-width and a desktop-width screen?

Opening pages one by one was tedious, so I built a throwaway audit tab that embedded the live pages in an iframe, switched the width between 375px and 1280px, and read each image's state. The result listed several images as "not loaded."

I panicked and started thinking about what to fix. Then I opened the real pages in a normal tab, and every image was there. The images were fine. My way of checking was what had broken.

Below I walk through what was happening, using numbers I reproduced and measured on my own machine, and the order in which I now doubt things when an image looks wrong.

The first thing to say is the order of suspicion

When an image looked missing, I used to suspect the URL or the server first. These days I reverse the order.

  1. Is the place I am checking in a state where the image is even allowed to start loading?
  2. Am I reading the state after loading has started?
  3. Only if it is still empty after both, suspect the image itself.

Most misdiagnoses happen at steps one and two. The image was never broken. I was measuring in a place where loading cannot start, or at a moment before it starts.

The setup, and the results up front

I used Playwright with headless Chromium on my own machine. The test page was tiny: two images displayed at 400px wide and one pointing to a file that does not exist. The first image had loading="lazy" and sat about 6,000px down the page. The second was an ordinary image with srcset and sizes.

Where I checkedLazy imageNormal image (srcset)
Real page opened directly (1280px wide)Before scrolling: complete=false, empty currentSrc. After scrolling: loadedcurrentSrc picked the 800w candidate; naturalWidth was 800
Visible iframe (375px wide)complete=false, currentSrc stayed emptycurrentSrc picked the 400w candidate; naturalWidth was 374
iframe with display:nonecomplete=false, rendered width 0complete=true yet naturalWidth was 0, and rendered width was 0

This table explains most of my misdiagnosis. In a hidden frame, even a fully loaded ordinary image reports naturalWidth as 0, while complete is true. A check written as "naturalWidth of 0 means broken" falls apart right there.

I noticed one more thing about naturalWidth. In a 375px frame, srcset picked the 400px-wide file, whose real size is 400px, yet naturalWidth was 374. With width descriptors, naturalWidth is not the raw pixel count but a value divided by the density the browser selected. A mismatch with the file's real size does not mean the image is being shrunk.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦Before calling an image broken, you can read rendered width, load state and currentSrc to tell apart a truly broken image, one that has not started loading, and one your test frame is simply unable to measure
✦Before asking an agent to confirm that images display, you can write where to check and what counts as a pass into the instruction itself, saving the time you would spend fixing things a false report said were broken
✦Before bulk-replacing CSS numbers, you can run a check that catches media-query breakpoints being shrunk along with everything else, preventing a quiet layout drift that is painful to trace afterwards
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

✦ Tips2026-09-22
Don't Leave Your Chat Records to the Export Button — Three Routes for the Night It Does Nothing
Three ways to keep a record of your Antigravity conversations when the Export button does nothing at all: how to tell a broken button from a silent success, how to locate the conversation file in your own environment by modification time, and how to decide what to keep before the session ends.
✦ Tips2026-09-16
The Day the Upload to Agent Overlay Took Every Drop, and How I Got File Handling Back
A full-window Upload to Agent overlay intercepts every drop, so files never reach the integrated terminal or the explorer sidebar. Here are the two workarounds the community found, plus three ways to hand over a path without dragging.
✦ Tips2026-09-07
When the few lines you quoted stop making sense in the next prompt
Antigravity 2.12.0 lets you quote part of a response into your next prompt, but the definitions those lines depend on stay behind. Here is a small script that counts what got left out, plus the widths I actually measured.