In web development, optimizing performance and ensuring efficient caching of static assets is crucial. When a browser downloads an asset, it adheres to the server's policy to determine whether it needs to download the asset again in subsequent visits. In the absence of a defined policy from the server, the browser relies on default behavior, typically caching the files for the duration of the session. Let's delve deeper into the caching process and its implications.
There is a huge problem with our current setup. Every-time we bundle our application, webpack always outputs our files with the same name. When it comes to caching, using the same file name for each build can have unintended consequences and lead to various issues. In this article, we'll explore the potential harm of employing caching with identical file names and discuss the importance of employing cache-busting techniques.
The Problem with Same File Names:
To overcome the issues associated with using the same file name, cache-busting techniques are employed to ensure that updated code is properly delivered to users. Content Hashing is a technique used in Webpack to generate unique hashes for files based on their content. These hashes enable effective cache management by ensuring that clients can cache files for an extended period while easily detecting and fetching updated versions when needed.
In this article, we will explore the concept of content hashing in Webpack and its significance in optimizing caching. We'll delve into how content hashes are generated, how they are used in file naming, and how they facilitate cache invalidation. By understanding content hashing, you'll be equipped with a powerful technique to improve the performance and caching strategies of your web applications. So let's dive in and uncover the world of content hashing in Webpack!
Webpack provides different hashing algorithms to generate content-based hashes. The most commonly used algorithm is the contenthash, which generates a unique hash based on the file's content. This hash is typically appended to the filename, allowing the browser to cache the file based on the hash value.
To use content hashing in webpack, we can configure the output filename in our webpack configuration to include the content hash.
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const { PurgeCSSPlugin } = require('purgecss-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')
const path = require('path')
module.exports = {
entry: './src/index.ts',
module: {
rules: [
{
test: /\\.scss$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
{
test: /\\.ts$/,
use: 'ts-loader',
},
],
},
optimization: {
minimizer: [new CssMinimizerPlugin(), new TerserPlugin()],
},
output: {
clean: true,
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, '../dist'),
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html',
}),
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
}),
new PurgeCSSPlugin({
paths: ['./src/index.html'],
}),
],
}
<aside>
💡 The clean
property in the output configuration of webpack allows us to automatically clean the dist
directory before each build. This ensures that only the files generated in the latest build are present in the output directory, removing any remnants from previous builds.
</aside>
With this configuration, webpack will generate a unique content hash for the bundle file each time the content changes. When webpack builds our project and generates bundled JavaScript files, it replaces [name]
with the corresponding entry point or chunk name and [contenthash]
with a unique hash value based on the file content. This results in a unique filename for each JavaScript bundle. When deploying the application, the browser will cache the bundle file based on the hash value. If any changes are made to the bundle file, the hash will change, forcing the browser to fetch the updated file.
Running our build script with this configuration will result in the generation of a new JavaScript file in the dist
folder. The name of the file will follow a specific pattern: main.
followed by a unique set of random characters, which are generated based on the content of the file. As we can see the bundle's name now reflects its content (via the hash). If we run another build without making any changes, the filename stays the same.
<aside>
💡 Change the content of src/index.ts
and run the build again. The content hash will now change because the content of our file has changed.
</aside>
Content hashing is an effective approach to optimize caching and improve performance in production environments. It ensures that clients receive the latest version of the files when they change while still leveraging the benefits of caching for unchanged files.