在webpack中使用CommonsChunkPlugin时,我们是否需要Etag和Last-Modified标题?

我正在使用webpack捆绑所有我的资产文件,所以我得到了这样的东西。

bundle.7fb44c37b0db67437e35.js vendor.495e9142a1f8334dcc8c.js styles.bc5b7548c97362b683f5582818914909.css 

我在名称中使用chunkhash,所以当浏览器caching一些东西时,它不会再次caching直到哈希已经改变。 例如,如果我改变样式的东西,捆绑文件和部署,只有样式的散列会改变,其他人不会这样浏览器将再次从服务器请求样式文件,其余的将从内存caching中使用。

在响应标题我也有Etag最后修改 ,他们改变每次我为每个文件部署应用程序。 我应该从响应中删除它们吗? 这可以混淆浏览器联系服务器,看看文件是否已经改变,即使哈希仍然是相同的?

伟大的问题。 这在很大程度上取决于如何实现后端以及如何计算标题值。 是从我们的服务器提供的文件,还是其他类似s3? 我们正在使用CDN吗? 我们是否使用我们的应用程序服务器的框架? 谁计算这些头文件,Web服务器或应用程序服务器?

为了这个答案的目的,并保持简单让我们假设我们正在使用流行的服务器框架Express没有CDN或第三方托管。 与大多数应用程序服务器一样,Express 根据所提供文件的内容(而不是文件的名称)计算ETagLast-Modified

浏览器第一次请求我们的某个文件时,它将收到资源的ETagLast-Modified 。 下一次请求相同的资源时,浏览器会将缓存的ETagLast-Modified标题发送到服务器。 然后,服务器根据这些标题决定浏览器是否需要下载新版本的资源,或者缓存的版本是否是最新版本。 如果缓存的资源是最新的,则服务器以304 - Not Modified状态码进行响应。 状态码是整个缓存系统的关键 – 浏览器如何决定是否使用缓存资源。

为了生成ETag头,Express将响应主体的二进制Buffer表示传递给etag模块, etag模块根据Buffer的内容( 源:生成ETag头和源:生成哈希 )计算SHA-1哈希。 要生成Last-Modified标题,Express使用文件系统的上次修改时间( 请参阅文档中的lastModified )。

当webpack构建一个新的bundle时,即使chunkhash是相同的,文件的二进制文件也会改变。 这会导致Express输出不同的EtagLast-Modified这意味着下次请求资源时它不会响应 。 如果没有304状态码,浏览器将不必要地重新下载软件包。

回答

我认为这里最好的做法是为这些资产禁用ETagLast-Modified标题,而是使用ExpiresCache-Control: max-age标题设置为将来(通常为1年)的日期。 这样浏览器只会重新下载一个包,如果它已经过期,或者它只是不存在于缓存中。