使用webpack chunkhash和缓存控制进行长期缓存

时间:2017-06-17 14:15:45

标签: caching hash webpack cache-control

我正在使用webpack捆绑我的所有文件。在webpack中,我使用chunkhash,Md5Hash和manifest为我的每个文件生成独特的chunkhash,这些文件可以通过浏览器下载。它看起来像这样。

styles.3840duiel348fdjh385idfki.css
bundle.488503289dfksdlkor93lfui.js
vendor.sdkkfuuewkf892377rfkjdle.js
image.dkkdiiue9984ujjkfld003kfpp.png

这意味着浏览器可以缓存它们,如果没有更改哈希,它将使用缓存版本。同时我可以只更改样式,只有那个哈希值会被更改,所以当我部署应用程序浏览器时仅下载新样式。

问题是我的服务器上使用了这个:

Cache-Control: public max-age=31536000

这表示积极的缓存,浏览器将使用缓存版本一年,除非更改URL,文件名。例如,当我更改样式时,我的哈希值会发生变化,浏览器应该从服务器请求新样式。这是根据这篇文章(模式1)和我发现的更多 https://jakearchibald.com/2016/caching-best-practices/

我的问题是,当我更新某些内容时,示例样式,样式的哈希值会更改,我会部署它。浏览器不会在我的页面上请求重新加载的新样式。它将服务于缓存的文件。我该如何解决这个问题?

我可以使用Cache-Control: no-cache但这不是解决方案,因为浏览器每次都必须检查服务器是否可以使用缓存版本。这是每次有人访问该页面时不需要的4个http请求。

3 个答案:

答案 0 :(得分:1)

我解决这个问题的方法是在我的文件名中添加一个数字(即Date.now()),如下所示。

文件名:[name].${Date.now().valueOf()}.[chunkhash].js 这在可预见的时间内非常可靠地工作。我用这种方法看到的唯一缺点是:每次发布时,都会强制刷新所有包。

但是,有些情况下,当模块不更改但其顺序发生变化(因此模块ID)时,渲染chunkhash会产生问题。模块ID和顺序不是chunkhash的一部分!请参阅:https://github.com/webpack/webpack/issues/1856

其他替代方法是使用命名模块(我相信会产生一些性能影响),除此之外可能涉及命名我不确定的模块。

答案 1 :(得分:0)

我是这样做的。我为我的客户端和服务器包使用不同的webpack配置。对于我的客户端包有bundle.js,vendor.js,styles.css ...我使用chunkhash和Cache-Control: public max-age=31536000,如我的问题所述。对于服务于html(ejs)的服务器包,我使用Cache-Control: no-cache。这很好用,因为浏览器会在每次重新加载时联系服务器,但这只是一个http请求。如果没有更改,浏览器将使用所有资产的缓存版本,因为html中的chunkhash没有更改。

例如,如果我更新了样式并且chunkhash被更改,浏览器将会看到在重新加载时联系服务器时只会下载新样式。

答案 2 :(得分:0)

仅指示浏览器在页面加载时加载资产...这就是它的工作方式。您可以轮询或使用任何形式的浏览器推送来检测后端更改,然后强制用户刷新其浏览器。

这不是缓存问题,不是浏览器问题……只是您掌握的信息可能已经过时了。您将不得不使用它或创建解决方法。

将其视为您公司咖啡机旁的日历,该日历在本周六有一个“聚会”活动。您看到了,奔向您的同事告诉他们这个好消息。同时,在日历上写事件的人意识到他犯了一个错误,并将事件更改为下一个星期六。您没有这些新信息,因此只要您不去喝咖啡,就会为您的同事提供错误的信息。知道更改的唯一方法是,有人会比您再去喝杯咖啡早通知您吗……例如,在日历上写活动的人会向所有人发送电子邮件,对自己的错误和聚会表示歉意定于下周六。