◉GEMINI LABJP
●ARGON — gemini-4-argon is generally available as of 10/13, aimed at complex coding, agents, math and science●DEEP RES — deep-research-pro-preview-12-2025 shuts down 10/23, 7 days left. Move to deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 is GA (10/06). gemini-3.1-flash-image is deprecated with no shutdown date yet●MCP — One write-up cut an 85,000-token tool result to 310 tokens by wrapping it in an ADK FunctionTool●FLASH — gemini-3.7-flash and 3.5-flash now route automatically to newer Flash models (10/08)●NEW — Stop Re-Reading Every Crash Report: Gre…●ARGON — gemini-4-argon is generally available as of 10/13, aimed at complex coding, agents, math and science●DEEP RES — deep-research-pro-preview-12-2025 shuts down 10/23, 7 days left. Move to deep-research-preview-04-2026●NANO — gemini-nano-banana-2.1 is GA (10/06). gemini-3.1-flash-image is deprecated with no shutdown date yet●MCP — One write-up cut an 85,000-token tool result to 310 tokens by wrapping it in an ADK FunctionTool●FLASH — gemini-3.7-flash and 3.5-flash now route automatically to newer Flash models (10/08)●NEW — Stop Re-Reading Every Crash Report: Gre…
Articles/Advanced
⬡ Advanced/2026-10-14Intermediate

Fine on Desktop, Blank on Safari: Four Things to Gather Before You Ask an AI to Diagnose It

After a shuffle, my lazy-loaded images never loaded again, but only in Safari on iPhone. Here is what to collect by hand before asking Gemini or any other model to diagnose a bug that does not reproduce on desktop, plus a request template you can paste.

gemini119safarilazy-loadingdebugging4prompt-design

I had just added a shuffle button to an image gallery and checked it on my desktop browser. Every shuffle worked. Then I opened the same page in Safari on my iPhone, and after a shuffle the images stayed blank. A reload fixed it. Only the moment right after the shuffle was broken.

As an indie developer running my own sites at Dolice, I run into "it doesn't reproduce on my machine" bugs a few times a year. What I'd like to say first is this: with this kind of bug, the quality of an AI's answer is mostly decided by how well you gathered evidence before asking. Below I use this one case to walk through how I gather it.

What I know, stated plainly

These points are confirmed:

  • It happens when a list of lazy-loaded images is rearranged by script (the elements are moved to new positions).
  • It happens in Safari on iPhone. It does not reproduce in desktop browsers.
  • After the move, the images never load.
  • I have not tested in-app browsers (WebViews), so I list that as unconfirmed.

What I have not done is trace why Safari behaves this way. I haven't read the spec or the engine source to back an explanation, so I won't offer one. I have a guess — that the loading check is not re-run for moved elements — but it remains a guess.

The fix: start loading yourself after the move

The fix is one idea. After moving the elements, don't rely on the browser's lazy loading; trigger loading with your own visibility check. I verified it on a real iPhone by shuffling repeatedly.

The code below shows the idea. It is not my production code, and I make no claim about how it behaves in Safari — please test it on your own device.

// Call this after a shuffle. It loads only images near the viewport.
// Assumes the real URL is kept in data-src.
function wakeVisibleImages(container, margin = 200) {
  const vh = window.innerHeight;
  container.querySelectorAll('img[data-src]').forEach((img) => {
    const r = img.getBoundingClientRect();
    if (r.bottom < -margin || r.top > vh + margin) return; // leave far-away images alone
    img.src = img.dataset.src;
    img.removeAttribute('data-src');
  });
}
 
// Minimal reproduction of the shuffle itself
function shuffle(grid) {
  const items = [...grid.children];
  items.sort(() => Math.random() - 0.5).forEach((el) => grid.appendChild(el));
  wakeVisibleImages(grid); // right after the move
}

Loading every image at once would defeat the point of lazy loading, which is why margin limits how close an image must be.

Four things to gather before you ask a model

If you ask Gemini or a similar model about this bug, collect these four things first. To be clear, I did not ask an AI about this particular bug; what follows is how I would go about it, for anyone in the same spot.

  1. The environment: device, OS version, browser. Separate "Safari itself" from "in-app browser."
  2. Where it reproduces and where it doesn't: "not on desktop" is itself a strong clue.
  3. The action just before the symptom: here it was moving elements. The action before the symptom is sometimes closer to the cause than the blank image.
  4. A minimal reproduction: not the whole site, about ten lines.

With those in hand, the request can stay short:

[Environment] Safari on iPhone (in-app browsers untested). Does not reproduce on desktop browsers.
[Symptom] After rearranging a list of lazy-loaded images by script, the images never load. A reload shows them.
[Action just before] I move child elements to new positions with appendChild.
[Reproduction] (paste a ~10-line minimal example)
[What I want] Possible causes, most likely first, and how to verify each.

I add "most likely first" and "how to verify each" so I don't adopt a guess as an answer. Whatever the model returns stays a hypothesis until I've checked it on the real device.

The line I drew after this

If I had only checked on desktop, I would never have seen this bug; everything looks correct on that screen. It was when I tried to describe the symptom that I noticed "which environments I'd tested" existed only in my head.

Until I can say which environments I've checked, I don't call it fixed — to an AI or to myself. I intend to keep that line.

One next step

Pick one place in your site where lazy-loaded images get moved — shuffling, filtering, infinite scroll — and try it on a real iPhone in Safari. If it reproduces, write down the four items above before you ask a model. I wrote about a similar "prepare before you investigate" habit in Stop Re-Reading Every Crash Report.

Share

Thank You for Reading

Gemini 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 →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⬡ Advanced2026-10-10
Keeping Money and Health Questions Out of Your History: Gemini Temporary Chat and the Settings to Check
Before you ask Gemini about household spending or a health worry, here is the order I use to check Temporary Chat and the Activity setting, so you can decide what gets kept and what doesn't.
⬡ Advanced2026-08-25
Rebuilding the CTR Denominator After AI Search Fans Out Your Queries
My top five queries by impressions all had zero clicks, and four of them were not phrases a person would type. Here is how I rebuilt the denominator and where I let Gemini make the call.
⬡ Advanced2026-08-24
A Provenance Gate That Never Asks Gemini to Name the Country
How I rebuilt the pre-publish provenance check for a ukiyo-e wallpaper app, moving from asking the model to name a country to asking it only to list the marks physically present on the paper. Includes the working code, the decision table that lives on my side, and why an abstain path had to come before accuracy.