-
Notifications
You must be signed in to change notification settings - Fork 0
Description
一、保证CDN加载最新资源
hash
和contentHash
的区别
hash
一般是结合CDN
缓存来使用,通过webpack构建之后,生成对应文件名自动带上对应的MD5值。如果文件内容改变的话,那么对应文件哈希值也会改变,对应的HTML引用的URL地址也会改变,触发CDN服务器从源服务器上拉取对应数据,进而更新本地缓存。
hash
hash是跟整个项目的构建相关,只要项目里有文件更改,整个项目构建的hash值都会更改,并且全部文件都共用相同的hash值
chunkhash
采用hash计算的话,每一次构建后生成的哈希值都不一样,即使文件内容压根没有改变。这样子是没办法实现缓存效果,我们需要换另一种哈希值计算方式,即chunkhash
。
chunkhash
和hash
不一样,它根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk
,生成对应的哈希值。我们在生产环境里把一些公共库
和程序入口文件区分开,单独打包构建,接着我们采用chunkhash
的方式生成哈希值,那么只要我们不改动公共库的代码,就可以保证其哈希值不会受影响。
contenthash
在chunkhash
的例子,我们可以看到由于index.css
被index.js
引用了,所以共用相同的chunkhash
值。但是这样子有个问题,如果index.js
更改了代码,css
文件就算内容没有任何改变,由于是该模块发生了改变,导致css
文件会重复构建。
这个时候,我们可以使用extra-text-webpack-plugin
里的contenthash
值,保证即使css文件所处的模块里就算其他文件内容改变,只要css文件内容不变,那么不会重复构建。只有文件自身内容发生变化,contenthash
才会更新。
var extractTextPlugin = require('extract-text-webpack-plugin'),
path = require('path')
module.exports = {
...
...
output:{
path:path.join(__dirname, '/dist/js'),
filename: 'bundle.[name].[chunkhash].js',
},
plugins:[
new extractTextPlugin('../css/bundle.[name].[contenthash].css')
]
}
html文件设置缓存方式
<!-- 设置缓存2小时,max-age指最大缓存的秒数 -->
<meta http-equiv="Cache-Control" content="max-age=7200" />
<!-- 或者这样设置永远不缓存 -->
<meta http-equiv="Cache-Control" content="no-cache" />
如何保证发布后 CDN 代码是最新的?
- 每个文件打包输出时加上
contentHash
,文件内容变化时文件名必定变化。 index.html
不要设置缓存,因为打包后index.html
内引用的scirpt url
发生了变化(因为 contentHash),因此可以知道最新的 js 文件。- CDN 配置了监听 OSS 的更新事件,文件更新时触发回源更新。
二、CDN预热
什么是预热?
首次发布的文件,主动从源站推送到CDN
,让用户访问到CDN时不用回客户的源站命中。
为什么要预热?
主动从源站推送到CDN,让用户访问到CDN时不用回客户的源站命中。
假如某游戏首次发布,玩家抢着赶紧下载游戏客户端(3GB
)。如果没有预热,第一批玩家在访问官网下载时,官网CNME记录解析到CDN。由于是第一次访问,CDN中缓存也没有,因此需要回源站
去获取游戏客户端(3GB
)
影响:
首批下载的用户体验很差,因为都集中访问源站主机,源站主机的CPU利用率和带宽会跑的很高。第一批玩家下载完成后,CDN中也能够缓存了一份,第二批玩家下载就直接在CDN中命中,速度比第一批快得多。
但是等CDN缓存好完整一份游戏客户端,可能半天到1天的时间就过去了。因为第一批下载时,源站压力非常大,CDN回源的带宽可能只有几KB,几KB的速度下载2GB的文件,可能要好几天了。那么游戏开服的头几天连游戏客户端都下载不了。
在开服前,通过预热功能,将游戏安装包(3GB
)从源站推送到各CDN节点,提前先缓存起来。等开服的时候,第一个玩家也能从CDN中快速获取到游戏安装包。