v146 · Web APIs · Pervasive Resources
Pervasive Resources
What makes a resource "extremely pervasive", which resources can qualify for shared caching, and how Chrome balances privacy risk against performance benefit.
allowlist matcher
Paste a resource URL or a snippet from a fetch log. The matcher models the Chrome-managed allowlist rules: extremely common third-party providers can qualify, while self-hosted, version-pinned framework URLs and personalised responses remain partitioned.
Run the matcher to classify the resource.
Chrome 86 partitioned the HTTP cache to prevent cross-site tracking via timing attacks. Chrome 146 carves out a narrow exception for resources so ubiquitous that sharing their cache entries provides measurable performance gains while contributing negligible additional tracking surface.
qualification criteria
| Criterion | Required | Rationale |
|---|---|---|
| Billions of daily fetches | Yes | Performance benefit must be population-scale |
| Loaded by millions of distinct origins | Yes | Pervasiveness must be across the web, not a single network |
| Stable, versioned URL | Yes | Same URL must always return identical bytes |
| Cache-Control: public, long max-age | Yes | Resource must be intended for caching without revalidation |
| No authentication or cookies | Yes | Personalised responses must never be shared |
| No query-string personalisation | Yes | URL must be fully deterministic |
| Served from a public CDN | Yes | Self-hosted copies at private URLs do not qualify |
| Developer opt-in required | No | Allowlist managed by Chrome; no header or attribute needed |
worked examples
| Resource category | Likely shared? | Why |
|---|---|---|
| Common analytics scripts | Yes | Provider-hosted tags with very broad HTTP Archive coverage are the core candidate shape. |
| Social media embeds | Yes | Widely reused third-party embed loaders are plausible allowlist candidates when responses are public and stable. |
| Video player embeds | Yes | The shared resource is the common player script or frame bootstrap, not each site's video file. |
| Captcha and ads libraries | Yes | High-volume provider scripts can be curated when they do not vary by user. |
| React, Vue, jQuery, Lodash, or Tailwind via pinned npm URLs | No | Manual version-pinned framework/library embeds are explicitly outside this carve-out. |
| Self-hosted copies or wrapper bundles | No | The top-level site still keys those entries; private URLs are not pervasive web resources. |
privacy vs performance tradeoff
privacy risk (extremely pervasive resources)
- An attacker already knows these URLs are loaded by most sites
- Cache timing reveals presence/absence — but these resources are always present
- No per-user variation in the response removes the signal entirely
- Tracking benefit approaches zero
performance gain
- Common analytics, social, video-player, captcha, and ads scripts can skip duplicate network transfers
- Cold start time reduced for many pages
- LCP improvement when a render-blocking script is already cached
- Bandwidth savings at scale: billions of avoided fetches daily
what does NOT qualify
| Resource type | Shared cache | Reason |
|---|---|---|
| API responses (JSON, XML) | No | Typically dynamic or personalised |
| Self-hosted scripts | No | Not pervasive across origins |
| Authenticated resources | No | Sharing would expose private data |
| Versioned CDN resources with low usage | No | Performance benefit below threshold |
| Images and media files | No | Usually site-specific; only common player bootstrap resources are candidates |
developer impact
// No code changes needed. Chrome handles allowlisted resources transparently.
// To check if a resource was served from cache, use Resource Timing:
const observer = new PerformanceObserver(list => {
for (const entry of list.getEntries()) {
if (entry.initiatorType === 'script') {
const fromCache = entry.transferSize === 0 && entry.encodedBodySize > 0;
console.log(entry.name, fromCache ? '(cached)' : '(network)');
}
}
});
observer.observe({ type: 'resource', buffered: true });
// Developers cannot opt a resource into the shared bucket.
// Use Resource Timing to observe transfer size, and keep expecting
// self-hosted or manually version-pinned resources to remain partitioned.