At a glance
List of static resources with weak or missing cache-control headers, ranked by repeat-visit cost. Lighthouse’s “Serve static assets with an efficient cache policy” audit identifies images, CSS, JS, and fonts where the Cache-Control header sets a short TTL (under 1 month) or is missing entirely. Repeat-visitors pay these bytes again instead of serving from browser cache. The fix is purely server-side header configuration; no code changes required.
| What it counts | Per resource: URL, file size, current cache TTL, recommended TTL, byte-savings on repeat visit. Sorted by potential repeat-visit savings. |
| Why caching matters for ecommerce | Ecommerce traffic has high repeat-visit rates (returning customers, cart-abandonment recovery, branded search). Brands with weak caching pay full bytes on every visit instead of serving the static portion from browser cache. Strong caching cuts repeat-visit page weight by 60-80 percent (everything except dynamic HTML serves locally). |
| Cache-Control TTL recommendations | (1) Hashed/versioned assets (e.g. app.a3f8b9.js with content hash in filename): Cache-Control: public, max-age=31536000, immutable (1 year). Safe because filename changes when content changes. (2) Non-versioned but stable (logos, fonts that rarely change): max-age=2592000 (30 days). (3) Frequently-changing static files: max-age=86400 (1 day) or must-revalidate for stale-while-revalidate behaviour. (4) HTML: no-cache or short TTL (5-60 minutes); HTML is dynamic. |
| Common ecommerce caching gaps | (1) Theme assets without versioning: BC Stencil bundles *.css and *.js without content hashing; default cache TTL is conservative. (2) Product images served via image CDN: usually well-cached by the CDN, but custom-uploaded merchant images sometimes serve with 1-day TTL by default. (3) Third-party scripts: vendors like Klaviyo, Tidio set their own headers; the merchant doesn’t control these. (4) Font files: should be very long-cached (1 year) since fonts almost never change, but defaults are sometimes 1 day. |
| Sample type | Lab data from Lighthouse audit. Each resource’s Cache-Control header is read from the actual HTTP response. |
| Why this is the easiest optimisation | No code changes needed. Edit server / CDN / image-CDN configuration to set proper Cache-Control headers. Edits apply within minutes; impact appears immediately for all repeat visitors. |
| Currency | n/a, list with byte-savings annotations. |
| Time window | T (current state). |
| Alert trigger | total cacheable bytes > 500KB shipped on repeat visit. |
| Sentiment key | null |
| Roles | owner, operations |
Calculation
Calculated automatically from your Website Performance (PageSpeed + CrUX) data. See the At a glance summary above for what the metric tracks and the worked example below for a typical reading.Worked example
A UK-based BigCommerce fashion store homepage audit, mobile, Wednesday 15 May 26.| Rank | Resource | Size | Current TTL | Recommended | Repeat-visit savings |
|---|---|---|---|---|---|
| 1 | stencil-bundle.js (theme JS) | 132KB | 1 day | 1 year (with hash) | 132KB |
| 2 | hero-banner-spring.png | 2,840KB | 1 hour | 30 days | 2,840KB |
| 3 | stencil-bundle.css (theme CSS) | 134KB | 1 day | 1 year (with hash) | 134KB |
| 4 | inter-regular.woff2 (font) | 60KB | 1 day | 1 year | 60KB |
| 5 | inter-bold.woff2 (font) | 60KB | 1 day | 1 year | 60KB |
| 6 | product-1234-detail-1.jpeg | 480KB | 1 hour | 30 days | 480KB |
| 7 | klaviyo-popup.css | 28KB | (no Cache-Control) | (vendor controls) | (out of scope) |
| 8 | tidio-chat.js | 148KB | 1 day | (vendor controls) | (out of scope) |
| Merchant-controlled total | 3,706KB | 3,706KB |
- 3.7MB of repeat-visit bytes are currently re-downloaded unnecessarily because cache TTLs are too short. A returning customer hits the site, downloads the same theme JS, hero image, fonts, and product images they downloaded yesterday. The browser would happily serve from cache if the headers said it could.
-
Theme JS + CSS at 1-day TTL is the simplest fix. BC’s default is conservative because Stencil bundles aren’t content-hashed by default, so the browser can’t tell when content has actually changed. Two paths: (a) Add content-hashing to theme bundle filenames so cache TTL can be 1 year safely (
bundle.a3f8b9.js); (b) Use etag validation so browsers re-validate efficiently without re-downloading. Path (a) is more performant; path (b) is simpler to ship. - Hero banner image at 1-hour TTL is wasteful. The image rarely changes; the 1-hour TTL forces every repeat visitor to re-download 2.8MB. Set 30-day TTL via the image CDN configuration; if the merchant changes the hero image they’ll need to update the URL or trigger a CDN purge, which is fine for occasional content updates.
-
Web fonts at 1-day TTL is wrong. Fonts almost never change. Set 1-year TTL with
immutabledirective; fonts are the canonical case for aggressive caching. - Product images at 1-hour TTL is the same pattern as the hero. Image CDNs typically handle this well but per-merchant configuration sometimes drifts to conservative defaults. Bulk-update via CDN console: set 30-day TTL across product image bucket.
- Klaviyo + Tidio scripts (ranks 7-8) are vendor-controlled. The merchant can’t change these. Out of scope for the merchant; raise with the vendor if it becomes a sustained issue.
- Cumulative impact: setting proper TTLs across ranks 1-6 saves 3.7MB of repeat-visit bytes. Returning customers experience load times near zero for static content; only the dynamic HTML hits the network. For ecommerce, this is the closest thing to “free” performance: zero code changes, immediate impact, proportional to repeat-visit traffic share (typically 40-60 percent of total sessions).
- Industry data: brands with strong caching see 30-50 percent faster repeat-visit LCP than first-visit LCP. The conversion rate impact is smaller than first-visit work (most users are first-visit on a given page) but the cumulative effect across all repeat visitors is meaningful.
- Check Cache-Control headers in DevTools Network tab; the “Cache” column shows TTL.
- Identify high-byte resources with short TTL. Concentrate on resources over 100KB with TTL under 7 days.
- Configure CDN / server / image-CDN to set proper TTLs.
- Re-audit to confirm headers updated as expected.
| Time horizon | Action |
|---|---|
| First 1 hour | Identify top 3 cacheable resources with weak TTL. |
| First 24 hours | Configure CDN / server to set 30-day or 1-year TTL on stable assets. |
| Re-audit | Confirm headers updated. |
Sibling cards merchants should reference together
| Card | Why merchants reach for it |
|---|---|
psi_total_weight | First-visit page weight; caching reduces repeat-visit weight. |
psi_image_optimisation | Image format + caching combined cut repeat-visit cost dramatically. |
psi_render_blocking | Cached CSS/JS still parse + execute, but skip the network download. |
psi_third_party_cost | Third-party scripts often have weak vendor-controlled cache headers. |
crux_lcp_p75 | Repeat-visit LCP improves with strong caching. |
psi_perf_score_summary | Composite score; caching contributes via LCP improvement. |
psi_top_opportunities_bytes | Composite byte-savings ranking. |
Reconciling against the vendor’s own dashboard
Where to look:- PageSpeed Insights, “Serve static assets with an efficient cache policy” opportunity in Diagnostics.
- Chrome DevTools → Network tab, the “Cache” column shows TTL per resource; “Disable cache” checkbox lets you compare cold-cache vs warm-cache load times.
- CDN / image-CDN console, usually the right place to configure default cache TTLs for static assets.
| Reason | Direction | What to do |
|---|---|---|
| CDN edge state. Different CDN edges may cache differently; PSI runs from Google’s infrastructure which may hit different edges than your audit’s region. | Either direction | Use a single edge for direct comparison. |
| Recent CDN config change. A recent header update may not have propagated to all edges. | Vortex IQ may show stale state | Wait 5-10 minutes after CDN config changes; re-audit. |
psi_total_weight, psi_image_optimisation).
Quick rule for support tickets: if a merchant says “I set 1-year TTL on my CDN but Vortex IQ still flags the resource”, the most common cause is CDN edge propagation delay or origin-cache vs edge-cache configuration mismatch. Verify the actual Cache-Control header in DevTools Network tab.
Known limitations / merchant FAQs
My theme bundle has 1-day cache. Why is that a problem? It forces every repeat visitor to re-download 130-300KB of theme JS+CSS that almost certainly hasn’t changed since their last visit. Strong caching (1-year with content hashing) makes the browser skip the download entirely and use the local cached copy. For ecommerce sites with 40-60 percent repeat-visit traffic, this is a substantial win. What if I update my theme? Won’t long cache TTLs cause stale content? Only if you don’t use content-hashing. The pattern: when your build process generatesbundle.a3f8b9.js (with content hash in filename), every theme update produces a new filename. Old browsers serve the old bundle from cache; new browsers fetch the new bundle. Cache invalidation is automatic via the URL change.
Can I just set 1-year TTL on everything?
Not on HTML. HTML pages are dynamic (cart state, login state, dynamic pricing) and need short cache TTLs. HTML default: no-cache or 1-5 minute TTL with revalidation. Static assets (images, CSS, JS, fonts) can be aggressively cached.
My image CDN says it’s caching, but Lighthouse flags my images. Why?
The CDN may be caching at the edge but the Cache-Control header sent to the user’s browser is shorter. Two-tier caching: CDN serves to users, but the user’s browser only caches per the response header. Check the actual response header in DevTools Network tab; the CDN edge cache and browser cache are different layers.
What about service workers? Do they handle this?
Service workers can cache more aggressively than HTTP Cache-Control allows, including offline support. For ecommerce, service workers are powerful but complex; most merchants achieve adequate caching via standard HTTP headers without the maintenance overhead of service worker code.
Can Vortex IQ change my CDN config automatically?
Read-only by design. The card identifies what should be cached longer; the merchant or developer configures the CDN.
My third-party scripts (Klaviyo, GTM, Tidio) have short TTLs. Can I fix that?
Generally no; vendors control their own headers. Workarounds: (a) self-host the script if vendor permits (rare); (b) live with the cost. Most third-party scripts cache reasonably (1-day to 1-week) by default; if you see very short TTLs (under 1 hour), raise with the vendor.
Should I worry about caching for first-time visitors?
No. Caching helps repeat visits; first visits download everything regardless. First-visit performance is driven by image optimisation, render-blocking fixes, and JS bundle work. Caching is the repeat-visit lever.