Missing caching headers can force browsers to unnecessarily download resources on every visit. Implementing proper caching strategies can significantly improve load times and reduce server load.
Missing caching headers occur when your server doesn't provide proper cache control directives:
1 2 3 4 5 6 7 8 9 10
# Response Without Caching Headers HTTP/1.1 200 OK Content-Type: text/html # Response With Caching Headers HTTP/1.1 200 OK Content-Type: text/html Cache-Control: public, max-age=31536000 ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4" Last-Modified: Wed, 20 Jan 2024 10:00:00 GMT
Missing caching headers affect your website in several ways:
Performance Impact
User Experience Issues
Technical Consequences
First, check your caching implementation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// Function to check caching headers async function checkCaching(url) { try { const response = await fetch(url, { method: 'HEAD' }); return { cacheControl: response.headers.get('cache-control'), etag: response.headers.get('etag'), lastModified: response.headers.get('last-modified'), expires: response.headers.get('expires'), hasCaching: response.headers.has('cache-control') }; } catch (error) { console.error('Cache check failed:', error); return null; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
# Set Caching Headers in .htaccess <IfModule mod_expires.c> ExpiresActive On # Images ExpiresByType image/jpeg "access plus 1 year" ExpiresByType image/png "access plus 1 year" ExpiresByType image/webp "access plus 1 year" # CSS, JavaScript ExpiresByType text/css "access plus 1 month" ExpiresByType application/javascript "access plus 1 month" # HTML documents ExpiresByType text/html "access plus 0 seconds" </IfModule> <IfModule mod_headers.c> <FilesMatch "\.(jpg|jpeg|png|gif|webp)$"> Header set Cache-Control "public, max-age=31536000" </FilesMatch> <FilesMatch "\.(css|js)$"> Header set Cache-Control "public, max-age=2592000" </FilesMatch> </IfModule>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# Set Caching Headers location ~* \.(jpg|jpeg|png|gif|webp)$ { expires 1y; add_header Cache-Control "public, no-transform"; } location ~* \.(css|js)$ { expires 1M; add_header Cache-Control "public, no-transform"; } location ~* \.(html|xml)$ { expires -1; add_header Cache-Control "no-store, no-cache, must-revalidate"; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
const express = require('express'); const app = express(); // Static files caching app.use(express.static('public', { maxAge: '1y', setHeaders: (res, path) => { if (path.endsWith('.html')) { // Don't cache HTML files res.setHeader('Cache-Control', 'no-cache'); } else if (path.match(/\.(jpg|jpeg|png|gif|webp)$/)) { // Cache images for 1 year res.setHeader('Cache-Control', 'public, max-age=31536000'); } else if (path.match(/\.(css|js)$/)) { // Cache CSS and JS for 1 month res.setHeader('Cache-Control', 'public, max-age=2592000'); } } }));
Cache Duration
Implementation Rules
Quality Control
Indexguru's SEO Analyzer
Development Tools
Testing Resources
1 2 3 4 5 6
# Nginx static asset caching location /static/ { expires 1y; add_header Cache-Control "public, no-transform"; add_header ETag ""; }
1 2 3 4 5 6 7 8
// Express API caching app.get('/api/data', (req, res) => { res.set({ 'Cache-Control': 'public, max-age=300', // 5 minutes 'ETag': generateETag(data) }); res.json(data); });
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// Dynamic content caching app.get('/content/:id', (req, res) => { const lastModified = getLastModified(req.params.id); // Check if-modified-since if (req.get('if-modified-since') === lastModified) { res.status(304).end(); return; } res.set({ 'Last-Modified': lastModified, 'Cache-Control': 'private, must-revalidate' }); res.send(content); });
Implementing caching leads to:
1 2 3 4 5 6 7 8 9 10 11 12
# Bad: Caching everything location / { expires 1y; # Don't cache everything } # Good: Selective caching location /static/ { expires 1y; } location / { expires -1; }
1 2 3 4 5 6 7 8 9
// Bad: No validation res.set('Cache-Control', 'public, max-age=31536000'); // Good: With validation res.set({ 'Cache-Control': 'public, max-age=31536000', 'ETag': generateETag(content), 'Last-Modified': getLastModified(content) });
1 2 3 4 5
# Bad: Conflicting directives Header set Cache-Control "no-cache, max-age=3600" # Good: Clear directive Header set Cache-Control "public, max-age=3600"
While caching setup requires careful consideration, it's a crucial optimization technique that can dramatically improve your website's performance. By implementing proper caching strategies and regularly monitoring their effectiveness, you can create a faster, more efficient website.
Need help implementing and monitoring caching? Try Indexguru's SEO tools to automatically check caching headers and get actionable recommendations for improvement.
Takes 5 minutes to setup