
Make Good Use of Caching, Avoid Reloading the Same Resources
Make Good Use of Caching, Avoid Reloading the Same Resources 관련
To prevent users from having to request files every time they visit a website, we can control this behavior by adding Expires or max-age. Expires sets a time, and as long as it's before this time, the browser won't request the file but will directly use the cache. Max-age is a relative time, and it's recommended to use max-age instead of Expires.
But this creates a problem: what happens when the file is updated? How do we notify the browser to request the file again?
This can be done by updating the resource link addresses referenced in the page, making the browser actively abandon the cache and load new resources.
The specific approach is to associate the URL modification of the resource address with the file content, which means that only when the file content changes, the corresponding URL will change. This achieves file-level precise cache control.
So what is related to file content? We naturally think of using digest algorithms to derive digest information for the file. The digest information corresponds one-to-one with the file content, providing a basis for cache control that's precise to the granularity of individual files.
How to implement caching and cache-busting:
1. Server-side cache headers (using Express.js as an example):
// Set cache control headers for static resources
app.use('/static', express.static('public', {
maxAge: '1y', // Cache for 1 year
etag: true, // Use ETag for validation
lastModified: true // Use Last-Modified for validation
}));
// For HTML files that shouldn't be cached as long
app.get('/*.html', (req, res) => {
res.set({
'Cache-Control': 'public, max-age=300', // Cache for 5 minutes
'Expires': new Date(Date.now() + 300000).toUTCString()
});
// Send HTML content
});
2. Using content hashes in filenames (Webpack configuration):
module.exports = {
output: {
filename: '[name].[contenthash].js', // Uses content hash in filename
path: path.resolve(__dirname, 'dist'),
},
plugins: [
// Extract CSS into separate files with content hash
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css'
}),
// Generate HTML with correct hashed filenames
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
};
This will produce output files like:
main.8e0d62a10c151dad4f8e.js
styles.f4e3a77c616562b26ca1.css
When you change the content of a file, its hash will change, forcing the browser to download the new file instead of using the cached version.
3. Example of generated HTML with cache-busting:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Cache Busting Example</title>
<!-- Note the content hash in the filename -->
<link rel="stylesheet" href="/static/styles.f4e3a77c616562b26ca1.css">
</head>
<body>
<div id="app"></div>
<!-- Script with content hash -->
<script src="/static/main.8e0d62a10c151dad4f8e.js"></script>
</body>
</html>
4. Version query parameters (simpler but less effective approach):
<link rel="stylesheet" href="styles.css?v=1.2.3">
<script src="app.js?v=1.2.3"></script>
When updating files, manually change the version number to force a new download.