Vue2 + Webpack3 打包压缩及缓存优化相关方案

一、开启gzip *

  • 客户端访问资源时,服务端先对资源进行压缩,再返回
  • 客户端自动解压,无需另行处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// vue2.6 + webpack3 只能配置compression-webpack-plugin1.1.12
npm install --save-dev compression-webpack-plugin@1.1.12
// webpack4 需要配置更高版本compression-webpack-plugin
var CompressionWebpackPlugin = require('compression-webpack-plugin')
if (config.build.productionGzip) {
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}

部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 直接使用压缩后的文件
http {
# 开启gzip
gzip on;
gzip_static on;
}

//不使用webpack打包后的.gz文件,客户端访问资源时再压缩 会造成一定的解压性能消耗
http {
gzip on;
gzip_static on;
gzip_min_length 10k;
gzip_buffers 4 16k;
gzip_comp_level 8;
# 根据需要添加文件类型
gzip_types application/javascript text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";
}

开启gzip_static 的问题

通过nginx配置开启解压缩静态文件gzip_static on后,启动nginx会提示nginx: [emerg] unknown directive "gzip_static" in,访问页面会发现有些js找不到,在目录下查找文件时发现是已gz结尾的,系统没有自动识别解压。
此时可用在nginx的安装目录的sbin中使用./nginx -V查看当前nginx的配置信息,看有没有配置--with-http_gzip_static_module
通过以上信息中的configure arguments看出我们没有配置该信息。这时需要我们进入原来的nginx解压的目录中,进行配置并重新安装。

1
2
3
4
5
6
## NGINX安装包下配置
./configure --prefix=/usr/local/nginx --with-http_gzip_static_module
## 重新安装
make && make install
## 重载NGINX
./nginx -s reload

二、引入外部库CDN 图床 七牛

部分依赖无需webpack打包处理

index.html引入 静态资源或cdn资源

若是static引入效果不明显

外网项目使用CDN时优选此方案 *

1
2
3
4
5
6
7
8
9
10
11
// webpack.base.conf.js 设置打包忽略
externals: {
'vue' : 'Vue',
'vue-router':'VueRouter',
'vuex':'Vuex',
'axios':'axios',
'element-ui':'ElementUI',
'mockjs': 'Mock',
'echarts': 'echarts',
'ueditor': 'UE'
}

三、缓存处理

1、Hash

hash是跟整个项目的构建相关,只要项目里有文件更改,整个项目构建的hash值都会更改,并且全部文件都共用相同的hash值

2、chunkhash

chunkhash,它根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值。

简单来说这种是根据不同入口来配置的,比如vue-router、vuex、vue等公共入口文件,只要这些没有改变,那么他对应生成的js的hash值也不会改变。

3、contenthash

contenthash主要是处理关联性,比如一个js文件中引入css,但是会生成一个js文件,一个css文件,但是因为入口是一个,导致他们的hash值也相同,所以当只有js修改时,关联输出的css、img等文件的hash值也会改变,这种情况下就需要contenthash了。

1
2
3
4
5
6
7
8
9
10
11
12
13
// webpack.prod.conf.js
// 1 使用hash而不是chunkhash 2 时间戳是为了避免源码无改动下的多次构建

var timeString = new Date().getTime()
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[hash].'+timeString+'.js'),
chunkFilename: utils.assetsPath('js/[id].[hash].'+timeString+'.js'),
publicPath: config.build.assetsPublicPath
}
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[hash].'+timeString+'.css')
})

设置HTML强制清除缓存 (谷歌火狐某些版本会自动忽略此设置 无效)

1
2
3
4
5
6
7
// index.html 
// 通知浏览器 页面不缓存 但存在兼容性问题 谷歌之类的无效
// 或者会被NGINX服务端的一些配置盖掉
<meta http-equiv="Pragram" content="no-cache">
<meta http-equiv="Cache-control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Cache" content="no-cache">
<meta http-equiv="Expires" content="0">

nginx 服务器强制清理缓存

1
2
3
4
5
6
7
8
9
10
location / {
#proxy_cache ...
#如果expires 和 add_header 同时开启的情况下,则add_header优于expires生效
#Cache-Control比Expires可以控制的多一些, 而且Cache-Control会重写Expires的规则
#设置禁止浏览器缓存,每次都从服务器请求
add_header Cache-Control no-cache;
add_header Cache-Control private;
#设置缓存上面定义的后缀文件缓存到浏览器的生存时间
expires -1s;
}

设置缓存

1
2
3
4
5
# 设置服务器内存缓存
open_file_cache max=2000 inactive=20s;
open_file_cache_valid 60s;
open_file_cache_min_uses 5;
open_file_cache_errors off;

四、升级webpack4

…待完善

webpack4对打包构建提速有明显的效果

目前受限于浏览器兼容的影响 未升级w4 有兴趣可百度研究