P2Issue #0
Serve static assets with an efficient cache policy
❓ What does it mean?
❓ What does it mean?
Static assets are files that don't change frequently, such as:
• Images (JPG, PNG, WebP)
• CSS and JavaScript files
• Fonts (WOFF, WOFF2, TTF)
• Videos and PDFs
An efficient cache policy tells the browser how long to store these files locally, so they don't need to be re-downloaded on every visit.
Without proper caching, users download the same files repeatedly, wasting bandwidth and slowing down page loads.
🚨 Why is it important for SEO?
🚨 Why is this a problem for SEO?
Slower Repeat Visits – Users must re-download assets on every page load, increasing load time.
Higher Server Load – More requests to the server instead of serving from browser cache.
Poor Core Web Vitals – Affects LCP (Largest Contentful Paint) and FCP (First Contentful Paint).
Wasted Bandwidth – Especially problematic for mobile users on limited data plans.
SEO Rankings – Google rewards faster sites; poor caching hurts performance scores.
✅ Recommended Cache Duration:
• Images, Fonts, Videos: 1 year (immutable)
• CSS/JS: 1 year with versioning/hashing
• HTML: No cache or short cache (5 minutes)
✅ How to Fix It
✅ Best Practices to Fix
Set Cache-Control headers for static assets:
• Cache-Control: public, max-age=31536000, immutable (1 year for versioned files)
• Cache-Control: public, max-age=86400 (1 day for frequently updated assets)
Use Content Hashing/Versioning – Add unique hashes to filenames (app.abc123.js) so browsers cache aggressively without serving stale content.
Use a CDN – CDNs automatically cache and serve assets from edge locations (Cloudflare, AWS CloudFront, Vercel).
Enable Browser Caching in Server Config:
• Nginx, Apache, or Next.js configuration
Avoid No-Cache for Static Assets – Only HTML should be dynamic; images/CSS/JS should be cached.
Use ETags and Last-Modified Headers – Helps browsers validate cached resources efficiently.
❌ Bad Example
📌 Example
❌ Bad (No Cache Policy):
HTTP Response Headers:
Cache-Control: no-cache
Expires: 0
<link rel="stylesheet" href="/styles.css">
<script src="/app.js"></script>
<img src="/logo.png" alt="Logo">
👉 Every time a user visits the site, the browser re-downloads styles.css, app.js, and logo.png.
👉 Wastes bandwidth and increases page load time on repeat visits.
👉 Poor user experience, especially on slow connections.
✅ Good Example
✅ Good (Efficient Cache Policy):
HTTP Response Headers:
Cache-Control: public, max-age=31536000, immutable
<link rel="stylesheet" href="/styles.a3f2c1.css">
<script src="/app.b8e4d9.js"></script>
<img src="/logo.png" alt="Logo">
👉 Browser caches CSS, JS, and images for 1 year.
👉 On repeat visits, assets load instantly from cache.
👉 When files change, new hashed filenames (styles.xyz123.css) force fresh downloads.
✅ Next.js Automatic Caching:
Next.js automatically sets optimal cache headers for static assets in the /public folder and optimized images via next/image.
// next.config.js
module.exports = {
async headers() {
return [
{
source: '/fonts/:path*',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=31536000, immutable',
},
],
},
{
source: '/images/:path*',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=31536000, immutable',
},
],
},
];
},
};
✅ Nginx Configuration:
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
}
⚡ Result
⚡ SEO & UX Impact of Fixing
Faster Repeat Visits → Assets load instantly from browser cache.
Improved Core Web Vitals → Better LCP, FCP, and overall page speed.
Reduced Server Load → Fewer requests = lower bandwidth costs.
Higher SEO Rankings → Google rewards faster, well-optimized sites.
Better Mobile Performance → Critical for users on slow/limited connections.
👉 Cache Duration Guidelines:
• Images, Fonts, Videos: 1 year (max-age=31536000)
• Versioned CSS/JS: 1 year (with content hashing)
• HTML pages: No cache or 5 minutes (dynamic content)
• API responses: Depends on update frequency (seconds to hours)