Browser Font Caching Mechanics: HTTP Headers, Partitioning & Invalidation

Browser font caching dictates repeat-visit performance and layout stability. This blueprint maps the HTTP caching pipeline, origin partitioning rules, and invalidation workflows required for deterministic font delivery. For broader delivery architecture, reference Font Loading & Delivery Strategies. Implementing these controls reduces repeat-visit font TTFB to under 10ms and eliminates Cumulative Layout Shift (CLS) caused by late-loading glyphs.

Cache-Control Directives & TTL Configuration

Set Cache-Control: public, max-age=31536000, immutable for versioned font assets. This instructs the browser to bypass revalidation checks entirely for the asset's lifetime.

Apply stale-while-revalidate=86400 to allow background cache updates without blocking render. The browser serves the cached font immediately while fetching a fresh copy in the background.

Coordinate initial fetch priority with Preloading & Resource Hints to bypass cache lookup latency on first visit. This guarantees the font request enters the critical rendering path without waiting for CSS parsing.

Avoid no-cache on static font files. Reserve this directive exclusively for dynamic font generation endpoints or user-customized typography APIs.

Cross-Origin Cache Partitioning & CORS

Modern browsers isolate font caches by requesting origin to prevent cross-site fingerprinting. Each unique origin maintains a separate cache partition.

Missing Access-Control-Allow-Origin triggers duplicate cache entries per subdomain. The browser treats fonts fetched from different subdomains as distinct resources.

CDN edge configurations must forward the Origin header and append Vary: Origin to the response. This ensures the CDN caches separate variants per requesting domain.

Validate cache hit ratios via X-Cache or CF-Cache-Status headers in the network waterfall. A consistent HIT status across subdomains confirms correct partitioning.

Service Worker & Cache API Pipeline

Implement a CacheFirst strategy for font files with explicit network fallback. This prioritizes local storage while preserving update capabilities.

Use cache.addAll() during the install event for critical subset bundles. Pre-caching guarantees immediate availability before the first paint.

Integrate runtime caching rules with Configuring font loading for offline PWAs for deterministic offline typography. This prevents broken glyph rendering during network degradation.

Monitor CacheStorage quota limits via navigator.storage.estimate(). Evict unused subsets via LRU algorithms to prevent quota exhaustion.

Cache Invalidation & Versioning Workflows

Deploy content-hashed filenames (inter-v3.19.woff2) instead of query parameters. Hash-based URLs guarantee unique cache keys for every asset revision.

Query strings (?v=2) are frequently ignored by proxy caches and CDNs. Relying on them causes stale asset delivery and unpredictable invalidation.

Align cache miss fallback rendering with Font-Display Values Explained to prevent FOIT during version transitions. Swap strategies maintain readability while new hashes propagate.

Automate cache-busting via build pipeline hooks that update CSS references atomically. Synchronized CSS and asset deployment prevents mixed-version rendering.

Configuration Reference

Nginx Cache Headers for Font Assets

location ~* \.(woff2|woff|ttf|otf)$ {
 add_header Cache-Control "public, max-age=31536000, immutable";
 add_header Access-Control-Allow-Origin "*";
 expires 1y;
}

Service Worker Cache-First Strategy

self.addEventListener('fetch', (event) => {
 if (event.request.destination === 'font') {
 event.respondWith(
 caches.match(event.request).then(cached => cached || fetch(event.request).then(response => {
 return caches.open('v1-fonts').then(cache => {
 cache.put(event.request, response.clone());
 return response;
 });
 }))
 );
 }
});

Atomic CSS Reference Update

/* Build output: inter-v3.19.woff2 */
@font-face {
 font-family: 'Inter';
 src: url('/fonts/inter-v3.19.woff2') format('woff2');
 font-display: swap;
}

Common Pitfalls

  • Query String Cache Busting: Using ?v= parameters results in CDN cache misses and origin overload. Switch to path-based content hashing.
  • Missing Vary: Origin: Omitting this directive causes CORS-preflight cache poisoning and duplicate font downloads across subdomains.
  • Low max-age on Variable Fonts: Setting short TTLs on variable fonts increases bandwidth consumption and layout shift risk. Enforce 1-year immutable headers.
  • Unprotected Service Worker Cache: Implementing CacheFirst without a network fallback breaks rendering during cache corruption. Always chain fetch() as a fallback.
  • Misaligned font-display: Failing to align font-display with cache miss windows triggers FOIT or excessive FOUT. Use swap or optional for cached transitions.

FAQ

What is the optimal Cache-Control TTL for web fonts? 1 year (max-age=31536000) with immutable for hashed assets. Use stale-while-revalidate for background updates without render blocking.

How does cross-origin cache partitioning impact font delivery? Browsers cache fonts per requesting origin. Missing CORS headers or incorrect Vary directives force duplicate downloads across subdomains.

Should query strings be used for font cache busting? No. Most CDNs and proxy caches ignore query strings. Use content-hashed filenames in the URL path for reliable invalidation.

How do Service Workers interact with browser font caches? Service Workers intercept fetch requests and can serve from CacheStorage independently of the HTTP cache. Implement CacheFirst with network fallback for resilience.