使用 webpack chunkhash 和缓存控制进行长期缓存
Long term caching with webpack chunkhash and cache control
我正在使用 webpack 来捆绑我所有的文件。在 webpack 中,我使用 chunkhash、Md5Hash 和 manifest 为浏览器下载的每个文件生成唯一的 chunkhash。它看起来像这样。
styles.3840duiel348fdjh385idfki.css
bundle.488503289dfksdlkor93lfui.js
vendor.sdkkfuuewkf892377rfkjdle.js
image.dkkdiiue9984ujjkfld003kfpp.png
这意味着浏览器可以缓存它们,如果哈希没有改变,它将同时使用缓存的 version.At 例如,我可以只改变样式,只有那个哈希会被改变,所以当我部署时应用程序浏览器将只下载新样式。
问题是在我的服务器上我使用了这个:
Cache-Control: public max-age=31536000
这表示积极的缓存,浏览器将使用缓存版本一年,除非 URL,文件名被更改。例如,当我更改样式时,我的哈希值也会更改,浏览器应从服务器请求新样式。这是根据这篇文章(模式 1)和我发现的其他一些 https://jakearchibald.com/2016/caching-best-practices/
我的问题是,当我更新某些内容时,示例样式、样式的哈希值发生了变化,我部署了它。浏览器不会请求新样式,除非我在我的页面上点击 reload。它将服务器缓存的文件。我该如何解决这个问题?
我可以使用 Cache-Control: no-cache
但这不是解决方案,因为浏览器每次都必须检查服务器是否可以使用缓存版本。也就是说每次有人访问该页面时都不需要 4 个 http 请求。
我是这样做的。我为我的客户端和服务器包使用不同的 webpack 配置。对于具有 bundle.js、vendor.js、styles.css... 的客户端包,我使用 chunkhash 和 Cache-Control: public max-age=31536000
,如我的问题所述。对于服务于 html(ejs) 的服务器包,我使用 Cache-Control: no-cache
。这很好用,因为浏览器会在每次重新加载时联系服务器,但这只是一个 http 请求。如果没有任何改变,浏览器将使用所有资产的缓存版本,因为 html 中的 chunkhash 没有改变。
例如,如果我更新样式并且更改了 chunkhash,浏览器将看到在重新加载时联系服务器并且只会下载新样式。
我解决这个问题的方法是在我的文件名中再添加一个数字(Date.now()),如下所示。
文件名:[name].${Date.now().valueOf()}.[chunkhash].js
这在可预见的时间内非常可靠地工作。我看到这种方法的唯一缺点是:每次发布时,这都会强制刷新所有包。
但是,在某些情况下,chunkhash 被渲染会产生问题,即模块未更改但它们的顺序发生更改(因此模块 ID)。模块 ID 和顺序不是 chunkhash 的一部分!请参考:https://github.com/webpack/webpack/issues/1856
其他替代方法是使用命名模块(我相信这会对性能产生一些影响)此外可能涉及命名我不确定的模块。
仅当您的页面加载时,浏览器才会被指示加载您的资产...这就是它的工作方式。您可以轮询或使用任何类型的浏览器推送来检测后端更改,然后强制您的用户刷新他们的浏览器。
这不是缓存问题,也不是浏览器问题...只是当您获得信息时它可能已经过时了。您将不得不忍受它或创建一个解决方法。
将其视为贵公司咖啡机旁边的日历,本周六有活动 'party'。您看到它和 运行 您的同事告诉他们这个好消息。与此同时,在日历上写下活动的人意识到他犯了一个错误,并将活动更改为下周六。你没有这个新信息,所以只要你不去喝咖啡,你就会向你的同事提供错误的信息。了解更改的唯一方法是,如果有人会在你去喝另一杯咖啡之前通知你......例如,在日历上写下事件的人会向所有人发送一封电子邮件,对他的错误表示抱歉,并且派对安排在下周六。
我正在使用 webpack 来捆绑我所有的文件。在 webpack 中,我使用 chunkhash、Md5Hash 和 manifest 为浏览器下载的每个文件生成唯一的 chunkhash。它看起来像这样。
styles.3840duiel348fdjh385idfki.css
bundle.488503289dfksdlkor93lfui.js
vendor.sdkkfuuewkf892377rfkjdle.js
image.dkkdiiue9984ujjkfld003kfpp.png
这意味着浏览器可以缓存它们,如果哈希没有改变,它将同时使用缓存的 version.At 例如,我可以只改变样式,只有那个哈希会被改变,所以当我部署时应用程序浏览器将只下载新样式。
问题是在我的服务器上我使用了这个:
Cache-Control: public max-age=31536000
这表示积极的缓存,浏览器将使用缓存版本一年,除非 URL,文件名被更改。例如,当我更改样式时,我的哈希值也会更改,浏览器应从服务器请求新样式。这是根据这篇文章(模式 1)和我发现的其他一些 https://jakearchibald.com/2016/caching-best-practices/
我的问题是,当我更新某些内容时,示例样式、样式的哈希值发生了变化,我部署了它。浏览器不会请求新样式,除非我在我的页面上点击 reload。它将服务器缓存的文件。我该如何解决这个问题?
我可以使用 Cache-Control: no-cache
但这不是解决方案,因为浏览器每次都必须检查服务器是否可以使用缓存版本。也就是说每次有人访问该页面时都不需要 4 个 http 请求。
我是这样做的。我为我的客户端和服务器包使用不同的 webpack 配置。对于具有 bundle.js、vendor.js、styles.css... 的客户端包,我使用 chunkhash 和 Cache-Control: public max-age=31536000
,如我的问题所述。对于服务于 html(ejs) 的服务器包,我使用 Cache-Control: no-cache
。这很好用,因为浏览器会在每次重新加载时联系服务器,但这只是一个 http 请求。如果没有任何改变,浏览器将使用所有资产的缓存版本,因为 html 中的 chunkhash 没有改变。
例如,如果我更新样式并且更改了 chunkhash,浏览器将看到在重新加载时联系服务器并且只会下载新样式。
我解决这个问题的方法是在我的文件名中再添加一个数字(Date.now()),如下所示。
文件名:[name].${Date.now().valueOf()}.[chunkhash].js
这在可预见的时间内非常可靠地工作。我看到这种方法的唯一缺点是:每次发布时,这都会强制刷新所有包。
但是,在某些情况下,chunkhash 被渲染会产生问题,即模块未更改但它们的顺序发生更改(因此模块 ID)。模块 ID 和顺序不是 chunkhash 的一部分!请参考:https://github.com/webpack/webpack/issues/1856
其他替代方法是使用命名模块(我相信这会对性能产生一些影响)此外可能涉及命名我不确定的模块。
仅当您的页面加载时,浏览器才会被指示加载您的资产...这就是它的工作方式。您可以轮询或使用任何类型的浏览器推送来检测后端更改,然后强制您的用户刷新他们的浏览器。
这不是缓存问题,也不是浏览器问题...只是当您获得信息时它可能已经过时了。您将不得不忍受它或创建一个解决方法。
将其视为贵公司咖啡机旁边的日历,本周六有活动 'party'。您看到它和 运行 您的同事告诉他们这个好消息。与此同时,在日历上写下活动的人意识到他犯了一个错误,并将活动更改为下周六。你没有这个新信息,所以只要你不去喝咖啡,你就会向你的同事提供错误的信息。了解更改的唯一方法是,如果有人会在你去喝另一杯咖啡之前通知你......例如,在日历上写下事件的人会向所有人发送一封电子邮件,对他的错误表示抱歉,并且派对安排在下周六。