Do we need Etag and Last-Modified header when using CommonsChunkPlugin in webpack?
I am using webpack to bundle all my resource files, so I end up with something like this.
bundle.7fb44c37b0db67437e35.js
vendor.495e9142a1f8334dcc8c.js
styles.bc5b7548c97362b683f5582818914909.css
I use chunkhash in the name, so when the browser caches something, it is not cached again until the hash changes. For example, if I change something in the styles, link the files and expand, only the hash from the styles will change, others will not ask the server again for only the stylesheet, and the rest will be used from the memory cache.
I also have Etag and Last-Modified in the response header , and they change every time I deploy the application for each file. Should I remove them from the answer? Could this confuse the browser to contact the server and see if the files have changed even though the hash stays the same?
source to share
Great question. It depends a lot on how the frontend is implemented and how it calculates the header values. Are files from our server supported or something else like s3? Are we using a CDN? Are we using frameworks for our application server? Who is calculating these headers, web server or app server?
For the purposes of this answer and to keep things simple, let's say we are using the popular Express server infrastructure without CDN or Third Party Hosting. As with most application servers, Express calculates ETag
and Last-Modified
based on the contents of the served file - not the file name .
For the first time the browser requests one of our files, he will receive ETag
and Last-Modified
for the resource. The next time, when requested by the same resource, the browser sends the cached headers ETag
and Last-Modified
the server. The server then decides, based on these headers, whether the browser needs to load the new version of the resource or if the cached version is the current one. If the cached resource is current, the server responds with a status code 304 - Not Modified
. The status code is the key to the entire caching system - it determines whether the browser should use a cached resource.
To generate the header ETag
, Express passes the binary Buffer
representation of the response body to the module ETag
, which computes the SHA-1 hash based on the contents of the buffer ( source: generating the ETag header and source: generating the hash ). Last-Modified
Express uses the last modified filesystem time ( see lastModified
docs ) to generate the header .
When webpack creates a new package, the binary will change even if the chunkhash is the same. This causes Express to issue different ETag
and Last-Modified
, which means that it will not respond 304
on the next resource request . Without a status code, the 304
browser would unnecessarily re-download the package.
Answer
I think that the best thing is to turn off headers ETag
and Last-Modified
for these assets, and instead use a title Expires
or Cache-Control: max-age
set to date far in the future (usually 1 year). This way the browser will only re-download the package if it has expired or it just doesn't exist in the cache.
source to share