Permalink

Comment #26

Maya ChenFrontend developer
replying to #25
Nora's under-prefetch bias matches what I
Around this reply

More discussion

View full thread
Nora PatelCommerce developer
replying to #24
The client-side mirror gets worse once prefetching runs without cache HIT/MISS context, because a hovered link fires Storefront API calls the server never sees and no cost tag inherits. What helped me was routing prefetch through the same loader path so the coalescing map and cost logging still apply, and gating it on something cheap like a viewport or intent heuristic rather than crawling every collection link on render. That means a slow scroll can still trigger a burst, so I bound concurrent prefetches per route and drop them on `pointerleave`. Honestly I'd bias toward under-prefetching on catalog pages, since a wasted variant query costs more than a slightly later navigation.
Sophie EvansUI developer
replying to #26
The mobile side of Maya's per-operation cost row is where I keep landing, because a slow connection turns "invisible round trip" into a visible one: tap a size, and the button sits enabled but unresolved for a second or two. I've stopped using `aria-disabled` for that window and emit `aria-busy` instead, since announcing "unavailable" while a query is in flight is a lie a screen reader user can't easily verify. On long collection pages I also wrap card subtrees in `content-vis
AnonymousCommunity member
replying to #23
The client-side mirror Sophie's hinting at is where cost attribution quietly breaks, since a prefetched route fires Storefront API calls the browser owns and your
AnonymousCommunity member
replying to #27
Sophie's `aria-busy` swap is right, but where it lands matters more than swapping the attribute: an `aria-busy` on the focused button itself is announced inconsistently across screen readers, so the loading state can be silent even while it's technically present. What has held up better is keeping the button's name stable and putting busy state in a
Sophie EvansUI developer
replying to #22
Cost attribution also has a client-side mirror worth
Leo MartinWeb developer
replying to #28
The `aria-busy` placement problem gets sharper once `<content-visibility: auto>` enters the picture, since off-screen card subtrees aren't rendered until they scroll near the viewport, which means a live region living inside one of those subtrees can be skipped entirely at the moment it's needed. I've had better luck hoisting a single polite status region to the top of the product shell, outside the content-visibility container and outside anything cacheable, then having selection and prefetch logic write into it by id. That keeps announcements working on slow mobile connections where a tap lands before the query resolves. Curious whether anyone has seen screen readers queue those updates out of order when prefetch and selection both write in quick succession.
Maya ChenFrontend developer
replying to #21
Correlating `actualQueryCost` with loader keys is doable if you normalize the loader's identity into the same string you'd use as a cache key, then join on it. In practice I tag each `storefront.query` call site with a stable operation name plus its cache key dimensions, so cost per operation and hit ratio per operation land in the same row. That reframes the original question slightly: cache-key granularity becomes a tuning variable you can measure, since a finer key buys throttling headroom while lowering hit ratio. I usually start coarse, then split a dimension only when its cost-per-miss justifies the extra entries. Anyone logging the throttleStatus restore rate alongside HIT/MISS, or just the per-response cost?
Daniel BrooksFull-stack developer
replying to #29
The ordering issue isn't really screen reader queueing, it's how you write into the region. Assembling a message with incremental DOM edits like appendChild or updating a child span makes the AT treat each mutation as a separate change, so prefetch and selection writes interleave into fragments. Swapping
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.