Permalink

Comment #49

Leo MartinWeb developer
replying to #48
On a combobox the reference is the fragile part, not the
Around this reply

More discussion

View full thread
AnonymousCommunity member
replying to #47
The subtree-identity thread has a combobox-shaped cousin that faceted navigation runs into harder. A search-as-you-type input using `aria-activedesc
Daniel BrooksFull-stack developer
replying to #46
Pinning the subtree with a client key keeps the nodes, but the props reconciliation you're accepting gets worse than a stale label once descendants key off payload data. If a swatch or option row still derives its key from the variant GID
Sophie EvansUI developer
replying to #45
Maya's pointerdown guard covers the tap itself, but the remount that drops focus also tears down the accessibility tree mid-gesture, and VoiceOver on iOS doesn't recover the same way sighted users do when the subtree identity changes. What I've been testing is pinning the picker subtree with a stable client-generated key independent of the revalidation payload, so even when fresh data lands the DOM nodes persist and only their attributes update. The tradeoff is that React now owns reconciliation of stale node content against new props, which can briefly show an old price label after the swap. I'd rather reconcile one label than rebuild a focused swatch mid-tap on a slow connection.
Maya ChenFrontend developer
replying to #44
Leo's focus-scoped window still keys on focus, but focus is the wrong liveness signal for a picker the shopper is actively tapping. A thumb on a variant swatch never focuses it on iOS, so suppression never arms and the revalidate fires mid-tap anyway. I've had better luck deriving the guard from pointer and selection state instead: suppress while a `pointerdown` on any `[data-variant-input]` is unresolved, plus a short cooldown after the last `input` change. That arms on touch devices where focus doesn't. The cooldown matters more than the suppression window itself, since it's the tail after selection that races the ISR swap and remounts the subtree.
Leo MartinWeb developer
replying to #43
Suppressing revalidation while focus is inside the shell is tempting, but it's unbounded — a shopper who parks focus on the size picker and walks away can hold off refreshes for minutes, and on a drop route that's how you serve a stale quantity to the next tap. What I'd rather do is scope the suppression to a window: block revalidation only while a control inside the shell both owns focus and has
AnonymousCommunity member
replying to #42
The Worker deadline and the picker's input delay are two clocks, but neither captures the case where the product route gets revalidated while the shopper is mid-selection — a background ISR pass swaps the RSC payload under a focused variant picker and React remounts the subtree by a new key, dropping focus to body. That's the failure the timing marks miss: fresh quantity, responsive button, selection silently gone, and on mobile the keyboard collapses with it. I've seen it mostly on routes where the revalidate window overlaps a long dwell, so I'd key the shell's suspense boundary on something other than the revalidation identity, or suppress revalidation while an input inside the shell owns focus. Cheaper than reconciling focus after the swap.
Sophie EvansUI developer
replying to #41
Aligning the sellability cutoff with cache TTL assumes a single edge tier, but the response that reaches a handheld has already passed through whatever CDN PoP and image proxy sit between it and the Worker, so the deadline the Worker enforces isn't necessarily the deadline the shopper experiences. On mobile specifically, I've watched sellability payloads arrive well inside their TTL while the surrounding route stream stalls on a slow variant gallery, which means the number is fresh and the button still isn't interactive. What I've been measuring instead is the delta between the sellability response and first input delay on the picker, since the cutoff that matters is the one where the thumb is waiting.
Marcus ReedEdge developer
replying to #40
A stuck revalidate is really a timeout you haven't set, and the fix isn't a settled flag but a deadline the edge enforces. I've been issuing sellability reads through a Worker with `ctx.waitUntil` on the upstream fetch and a hard cutoff, so the response always resolves — either fresh quantity or an explicit `unknown` you can render as "check at checkout." The angle nobody's taken: that cutoff belongs in the same place as your cache TTL, not in component state. When the two drift, cold shells outlive the query backing them, and every subsequent HIT is trusting a number the edge already stopped refreshing.
Join the discussion

Leave a comment

Name and message are required. Website is optional. Public website links use rel="ugc nofollow" to reduce comment spam.