Menu
GitHub Engineering·May 14, 2026

Optimizing Web App Performance with Client-Side Caching and Preheating: GitHub Issues Case Study

This article details GitHub's architectural changes to improve the perceived performance of GitHub Issues navigation. By shifting work to the client, implementing a stale-while-revalidate caching layer with IndexedDB, and introducing a preheating strategy, GitHub significantly reduced latency and enhanced user flow. The approach focuses on client-side optimizations to deliver an 'instant' experience, especially for frequently accessed data, while balancing freshness and resource utilization.

Read original on GitHub Engineering

The Challenge: Latency as a Context Switch

GitHub observed that even small delays in navigating GitHub Issues created significant friction for developers, leading to context switches and reduced productivity. The core problem wasn't that the backend was inherently slow, but rather that common navigation paths involved redundant data fetching, even for previously viewed content. The goal was to achieve 'instant' perceived performance, aligning with modern user expectations for web applications, especially developer tools.

Architectural Strategy: Client-Side First with Stale-While-Revalidate

GitHub's solution involved a fundamental shift in their data flow and navigation behavior, prioritizing client-side rendering from local data followed by background revalidation. This 'local-first' application model with stale-while-revalidate (SWR) was designed to minimize user-visible latency by rendering immediately, then asynchronously checking for data freshness against the server.

ℹ️

Key Principles of the New Architecture

The new architecture is built on three pillars: a client-side caching layer backed by IndexedDB, a preheating strategy for improved cache hit rates without excessive requests, and a service worker to ensure cached data remains available even on hard navigations. This combination ensures perceived speed while maintaining eventual consistency.

Client-Side Caching with IndexedDB

For React soft navigations, where the application runtime is already active, data fetch latency is the primary bottleneck. GitHub implemented a persistent client-side cache using IndexedDB. This choice was driven by IndexedDB's durable storage, object-store model for efficient lookups, and larger quota compared to localStorage. The SWR semantics mean that upon navigation, the client attempts to render from the local cache first, making the page appear instantly, and then initiates a background network request to revalidate and update the cache if necessary. This also provides graceful degradation during network issues.

Preheating Strategy for Enhanced Cache Hits

To increase cache hit ratios beyond initial SWR benefits, GitHub introduced a 'preheating' strategy. Unlike eager prefetching which can generate excessive network traffic, preheating proactively identifies high-intent issue references and populates the client cache *only if* the data is not already present. This is a deliberate trade-off: it prioritizes having *some usable data* locally for instant rendering over ensuring absolute freshness, as freshness can be reconciled asynchronously after initial render. An in-memory cache layer was also added in front of IndexedDB to serve hot payloads synchronously, further reducing critical path latency.

Measuring Success and Trade-offs

GitHub defined

  • Instant: HPC < 200 ms
  • Fast: HPC < 1000 ms
  • Slow: HPC >= 1000 ms

Initial results showed a significant increase in instant React navigations, validating the model. The main trade-off is controlled staleness; GitHub accepted a server/cache divergence of about 4.7% as an explicit operating envelope, balancing perceived speed with data consistency. This iterative approach allows for continuous improvement, acknowledging that a full platform migration to React is a longer-term goal.

client-side cachingweb performanceIndexedDBstale-while-revalidatepreheatingservice workerfrontend architecturelatency optimization

Comments

Loading comments...