Modern SPAs often suffer from the time gap between HTML render and React hydration, especially when data fetching kicks in after the app loads. What if you could speculatively preload app state before hydration — like how browsers preload fonts or images?

Using a combination of ``, Service Workers, and a custom React hook, you can preload data before React even boots, dramatically improving Time to Interactive (TTI) for initial render.

Let’s build it.


Step 1: Preload API Data in the HTML Head

Before your React app initializes, you can hint to the browser to preload key JSON data by injecting this tag into your server-rendered HTML:

This doesn’t execute a fetch directly — it just hints the browser to fetch the resource early and cache it in the preload cache.


Step 2: Intercept Preload with a Service Worker

To capture this speculative fetch and make it available to React before the app asks for it, install a Service Worker that caches preload fetches.

Inside sw.js:

self.addEventListener("fetch", (event) => {
  if (event.request.url.includes("/api/dashboard")) {
    event.respondWith(
      caches.open("preloaded-api").then(async (cache) => {
        const match = await cache.match(event.request);
        if (match) return match;

        const response = await fetch(event.request);
        cache.put(event.request, response.clone());
        return response;
      })
    );
  }
});

This will store the preload response in a named cache, so your React app can pull from it instantly.


Step 3: Install the Service Worker on First Load

Somewhere near the top of your React app (or in index.tsx):

if ("serviceWorker" in navigator) {
  navigator.serviceWorker.register("/sw.js").then(() => {
    console.log("SW registered");
  });
}

This ensures your Service Worker is available for future navigations — and will intercept preload requests.


Step 4: Create a React Hook to Load from Cache First

This hook will load preloaded data from the Service Worker cache, falling back to a network fetch if needed.

export function usePreloadedData(url) {
  const [data, setData] = React.useState(null);

  React.useEffect(() => {
    let active = true;

    async function fetchData() {
      const cache = await caches.open("preloaded-api");
      const cached = await cache.match(url);

      if (cached) {
        const json = await cached.json();
        if (active) setData(json);
      } else {
        const res = await fetch(url);
        const json = await res.json();
        if (active) setData(json);
      }
    }

    fetchData();
    return () => { active = false };
  }, [url]);

  return data;
}

Now, in your component:

const dashboardData = usePreloadedData("/api/dashboard");

Boom — React renders with preloaded data immediately, avoiding the wait for hydration + fetch.


Step 5: Optional – Preload Multiple Endpoints

Just add more `` tags in your HTML head for other critical endpoints, and update your Service Worker accordingly.



Then in the Service Worker:

if (event.request.url.includes("/api/")) {
  // same logic, cache any API preload
}

Pros:

  • 🚀 Faster perceived load time and TTI
  • 🧠 Makes data available before React initializes
  • 🧰 No backend change needed — all frontend-driven
  • 🕵️‍♀️ Useful for apps with heavy initial data requirements
  • 🧱 Works with or without SSR

⚠️ Cons:

  • 🔧 Requires Service Worker setup and cache management
  • 🔒 Preloaded data must be public (no auth headers)
  • 🧹 Risk of stale cache unless you manage expiry
  • 🧬 Complexity added for minor performance gain unless justified

Summary

By combining ``, Service Workers, and a simple custom hook, you can preload and cache critical API data before your React app loads — a clever performance optimization that mimics how browsers treat fonts and images. It's a niche but potent tool for apps where milliseconds matter.

This technique is ideal for dashboards, SPAs with static APIs, or PWAs needing instant load.


For a much more extensive guide on getting the most out of React portals, check out my full 24-page PDF file on Gumroad. It's available for just $10:

Using React Portals Like a Pro.

If this was helpful, you can support me here: Buy Me a Coffee