Do we need Etag and Last-Modified header when using CommonsChunkPlugin in webpack Do we need Etag and Last-Modified header when using CommonsChunkPlugin in webpack nginx nginx

Do we need Etag and Last-Modified header when using CommonsChunkPlugin in webpack


Great question. This depends largely on how the back-end is implemented and how it calculates the header values. Are the files served from our server, or something else like s3? Are we using a CDN? Are we using a framework for our application server? Who calculates these headers, the web server or the application server?

For the purposes of this answer and to keep things simple let's assume we are using the popular server framework Express with no CDN or 3rd party hosting. Like most application servers, Express calculates ETag and Last-Modified based on the content of the file being served - not the name of the file.

The first time a browser requests one of our files, it will receive the the ETag and Last-Modified for the resource. The next time the same resource is requested the browser will send the cached ETag and Last-Modified headers to the server. The server then decides based on these headers whether the browser needs to download a new version of the resource or if the cached version is current. If the cached resource is current, the server responds with a 304 - Not Modified status code. The status code is the key to this whole caching system - it is how the browser decides if it should use the cached resource.

To generate the ETag header, Express passes a binary Buffer representation of the response body to the etag module which calculates a SHA-1 hash based on the contents of the Buffer (source: generating ETag header and source: generating hash). To generate the Last-Modified header, Express uses the file system's last modified time (see lastModified in docs).

When webpack builds a new bundle the file's binary will change even if the chunkhash is the same. This causes Express to output a different Etag and Last-Modified, which means it will not respond with a 304 the next time the resource is requested. Without the 304 status code, the browser will unnecessarily re-download the bundle.

Answer

I think the best thing to do here is disable ETag and Last-Modified headers for these assets and instead use the Expires or Cache-Control: max-age header set to a date far in the future (usually 1 year). This way the browser will only re-download a bundle if it is expired or if it simply does not exist in the cache.