Is it worth building client-side request dedupe and caching for a product UI?

Hey folks, I’m in the middle of shipping a dashboard where multiple widgets hit the same endpoint, and I’m trying to decide if adding client-side request dedupe + a tiny cache is worth the complexity or just future pain.

const inFlight = new Map<string, Promise<any>>();
const cache = new Map<string, { at: number; data: any }>();

export function fetchOnce(key: string, fn: () => Promise<any>, ttlMs = 5000) {
  const hit = cache.get(key);
  if (hit && Date.now() - hit.at < ttlMs) return Promise.resolve(hit.data);

  const existing = inFlight.get(key);
  if (existing) return existing;

  const p = fn()
    .then((data) => {
      cache.set(key, { at: Date.now(), data });
      return data;
    })
    .finally(() => inFlight.delete(key));

  inFlight.set(key, p);
  return p;
}

Given the failure modes (stale data, memory growth, weird cross-widget coupling), how do you decide when this pattern is a net product win vs keeping it simple and eating the extra requests?