一次Vue2.0项目打包优化之旅
兴致冲冲地把网站打包上线,却发现首屏加载超时,查看了一下控制台的请求信息,发现vendor.js文件竟然达到了1M的大小。百度一下后发现vue-cli npm run build
命令默认把dependencies中的依赖统一打包到vendor.js文件里面。
定位vendor.js大的原因
使用webpack-bundle-analyzer—— Webpack 插件和 CLI 实用程序,她可以将内容束展示为方便交互的直观树状图,让你明白你所构建包中真正引入的内容;我们可以借助她,发现它大体有哪些模块组成,找到不合时宜的存在,然后优化它。
安装
shell
npm i -D webpack-bundle-analyzer
使用
在webpack.base.conf.js
里面作如下配置
js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
}
为了方便运行她(npm run analyz
),我们可以在package.json
注入以下的命令,默认会打开 http://127.0.0.1:8888 作为展示。
json
"analyz": "NODE_ENV=production set npm_config_report=true npm run build"
在windows下运行npm run analyz
会报 “NODE_ENV 不是内部或外部命令,也不是可运行的程序,或者批处理文件” 的错误,(这种操作在powershell中不被支持,在cmd中也不被支持,这是Mac中bash或Linux的shell中的独特操作)在windows下我们可以
json
"analyz": "set NODE_ENV=production && set npm_config_report=true && npm run build"
这样就很方便地查看哪个模块太长,可以针对性的优化他们。
解决方法
1.引用外部CDN
引用https://www.unpkg.com 里面的CDN地址
使用方法:
在地址栏输入https://www.unpkg.com/你的模块名称,然后回车,就能查找到你的模块的CDN地址了,
比如https://www.unpkg.com/highlight.js就会访问到https://www.unpkg.com/highlight.js@9.13.0/lib/index.js
然后在index.html
里面引用
html
<body>
<div id="app"></div>
<script src="https://www.unpkg.com/highlight.js@9.13.0/lib/index.js"></script>
</body>
配置webpack.base.conf.js
,在module.exports
里面加入externals,具体的externals配置可以查看https://webpack.js.org/configuration/externals/#src/components/Sidebar/Sidebar.jsx
js
externals: {
'highlight.js': 'hljs'
}
删除main.js
里面的import hljs from 'highlight.js'
,若没有删除webpack还是会把对应的依赖进行打包。
另外就是,在开启了eslint的环境下会报一个no-undef
错误,所以需要在.eslintrc.js
里面配置
js
rules: {
'no-undef': 0, // http://eslint.cn/docs/4.0.0/rules/no-undef
}
这样,再次打包之后,highlight.js就不会被打包进vendor.js里面了。其他的模块也可以使用这样的方式引用外部的CDN,减轻服务器的压力。
js
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios',
'vue-meta': 'VueMeta',
'highlight.js': 'hljs',
'vue-awesome-swiper': 'VueAwesomeSwiper'
}
2.路由按需加载
具体配置可以查看vue-router官网
我的配置router/index.js
之前
js
import Home from '@/pages/home/Home'
const routes = [
{
path: '/',
name: 'home',
component: Home
}
]
现在
js
// import Home from '@/pages/home/Home'
const routes = [
{
path: '/',
name: 'home',
component: resolve => require(['@/pages/home/Home'], resolve)
}
]
然后配置一下chunk的名称webpack.base.conf.js
js
output: {
// 以文件名和8位哈希值作为最终打包的名称
chunkName: '[name]-[chunkhash:8].js'
}
3.开启gzip压缩
首先安装插件compression-webpack-plugin
shell
npm i -D compression-webpack-plugin@1.1.12
我安装的1.1.12版本,其他版本会报错,具体原因未明
然后在config/index.js
里面把productionGzip
改为true
js
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
// productionGzip: false,
productionGzip: true,
productionGzipExtensions: ['js', 'css'],
之后npm run build执行后会发现每个js和css文件会压缩一个gz后缀的文件夹,浏览器如果支持g-zip 会自动查找有没有gz文件 找到了就加载gz然后本地解压 执行。