Duplicate network requests
When several components each fetch the same endpoint, you pay for the same data multiple times — wasted bandwidth, extra server load, slower time-to-content, and the risk that responses arrive out of order and overwrite each other. It is endemic in AI-built frontends because each component is generated in isolation, so each one fetches what it needs independently instead of sharing.
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
Put a caching data layer in front of your fetches so identical in-flight requests are deduplicated and results are shared. Lift shared data to a common parent, cache responses, debounce rapid-fire inputs, and set sensible Cache-Control headers on the API.
- Adopt a query cache (or a shared in-flight promise map) that dedupes by key
- Give the same resource the same query key everywhere it’s used
- Debounce search/autocomplete and cache responses on the server
const inFlight = new Map()
function dedupedFetch(url) {
if (!inFlight.has(url)) {
inFlight.set(url, fetch(url).then((r) => r.json()).finally(() => inFlight.delete(url)))
}
return inFlight.get(url)
}FAQ
- Is fetching the same URL twice always a bug?
- Not always — polling or intentional revalidation is fine. VibeCheck flags the same method+URL hitting 2+ times within 2 seconds, which almost always means two components fetched independently rather than sharing.
- Does HTTP caching solve this?
Cache-Controlhelps the browser reuse responses, but the requests are still made and can still race. Client-side dedup (a query cache or shared promise) prevents the duplicate calls in the first place.- Why do my duplicates come in bursts on mount?
- Because several components mount together and each kicks off its own fetch. Sharing one query key (or lifting the fetch to a parent/loader) collapses them into a single request.