Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack 4: hash and contenthash and chunkhash, when to use which?

Tags:

webpack

someone have suggested a similar question to this one, but it only explains the differences between those hashes.

BUT, I still can't figure out when should I choose [hash] instead of [contenthash]? Can someone show me an example situation?

=== previous body ===

The webpack docs explain different hashes type as following:

https://webpack.js.org/configuration/output/#outputfilename

hash:

Unique hash generated for every build

contenthash:

Hashes generated for extracted content

chunkhash:

Hashes based on each chunks' content:

I am still confused about when to use which type of the hashes.

[hash] is generated for every build, but after running webpack build multiple times with following config, I didn't find my hash changed.

module.exports = {
  output: {
    filename: '[name].[hash].js'
  }
}

Webpack version 4.41.2

I also find that the webpack config inside react-scripts is using contenthash for js and css file, but hash for assets files like images, this is also confusing, why are they doing it that way, is [hash] the better option for binary files?

like image 535
Littlee Avatar asked Dec 05 '19 11:12

Littlee


1 Answers

Consider you have three generated bundles:

main.js
main.css
vendor.js

main.css referred in main.js file.

Hash:

Hash number will be generated for each build. Generated Hash Number will be same for all the bundled files.

For Example:

Hash: 66e665r76798c278ytr6

Generated Files:
main.66e665r76798c278ytr6.js
main.66e665r76798c278ytr6.css
vendor.66e665r76798c278ytr6.js

All the three files will contain the same hash number. This hash will be same as long as you havent changed any content of the files. Even if you run many builds without changing any content, hash number will be same.

ChunkHash:

In this case, Hash number will be generated based on the entrypoints and it will be different for all the files.

Hash: 66e665r76798c278ytr6

Generated Files:
main.77e665r76798c278ytr6.js
main.78e665r76798c278ytr6.css
vendor.79e665r76798c278ytr6.js

If you havent changed the vendor files, hash will be the same for the generated vendor file. But if you add any new vendor, hash number will be changed.

If you made any changes in main.js, both main.js and main.css will be having new hash number since hash number is changed based on the entrypoint.

ContentHash:

Hash will be generated only if you made any changes in the particular file and each file will be having the unique has number.

For Example, If you changed only main.js file, new hash will be generated only for the changed file, other two hash will be same as previous build

Both Chunkhash and ContentHash generate hash number for each and every generated file. Only difference is ChunkHash generate hash based on the entrypoint.

In most cases, you will be using ContentHash for production.

With the help of contenthash, you can implement long term caching in the browsers. Browser will serve the cached file as long as the hash remains same.

https://github.com/webpack/webpack.js.org/issues/2096

Long Term Caching: To improve the app loading time, we often use caching. During initial load of the app, we can set the header for the assets as Cache-Control: max-age=31536000. After that, browser will cache the assets and subsequent requests will be served from the cache.

Without Hashing:

Consider you have made changes in some assets(say main.js), since you have specified max-age as 31536000, new changes will not get reflected, browser will continue to serve from cache.

With Hashing:

To overrride this, we use hash across all the files. If you made any changes in the files, new hash will be generated and browser consider it as a new request.

Example:

You have made changes only in main.js. In case of [hash], all the files will get the new hash number. browser will consider all the three as new and make three new requests to get the files

This is not the case with [contenthash]. If you mentioned contenthash, then only main.js hash will be changed. Other two files will have the same hash number and will continue to serve from browser cache.

This will improve your app loading time.

If you need to implement long term caching, then it is advisable to use contenthash instead of normal hash.

Generating hashes will increase the app compilation time. So you will be using contenthash/hash during production.

For more info about long term caching: https://developers.google.com/web/fundamentals/performance/webpack/use-long-term-caching

like image 103
Indragith Avatar answered May 10 '23 08:05

Indragith