上篇讲了首屏优化,具体文章详见移动spa商城优化记(一)---首屏优化篇,此次来分享一下打包速度的一些优化经验,由于在实际项目开发中,随着项目的不断增大,依赖项不断增多,咱们会发现webpack打包速度会愈来愈慢,有时候npm run一下可能出去上个厕所的时间都够了,在这快速发展的时代,这么拖节奏的事情毫不容许,本篇仍是以公司spa商城为例,详细介绍一下优化打包速度方面的经验。css
公司这个项目的起手模板是vue-cli的webpack模板,项目完成大概有将30个页面,未经优化前打包时间如图: html
接下来开始优化,优化主要分四方面:减小打包文件数量,减小没必要要的功能开销,优化打包方式,升级打包工具。前端
指导思想:要打包的东西少了速度天然就快了。
vue
webpack.DllPlugin + webpack.DllReferencePlugin这组插件应该是借鉴了dll的思想因此叫dllplugin这个名字,目的就是将vue,vue-router,react,jquery等等这些体积较大,项目中不常更新的第三方包抽离出来单独打包,而后告诉webpack这些包我以前已经打包过了,你每次打包直接用就好了,不用每次再去从新打包一次了。
node
使用方法:
react
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry:{
//这地方写你想抽离的包,能够参考你的package.json文件下的dependencies
vue:['vue','vue-router']
},
output:{
//这地方写你打包后生成文件的路径
path:path.join(__dirname,"../src/dll"),
filename:'[name].dll.js',
library:'[name]'
},
plugins:[
//这个插件是重点,用于打包上面entry里配置的包
new webpack.DllPlugin({
path:path.join(__dirname,"../src/dll",'[name]-manifest.json'),
name:'[name]',
}),
new webpack.optimize.UglifyJsPlugin()
]
}
复制代码
webpack --config build/webpack.dll.conf.js
打包生成抽离的公共包。plugins: [
new webpack.DllReferencePlugin({
//这里写上一步打包出的json路径
manifest:require('../src/dll/vue-manifest.json')
})
......
]
复制代码
如今,再次打包就能够了,你提取出的第三方包越多,打包速度优化的越明显。若是想让打包出的html能够自动引入第二步打包出的dll.js文件,可使用add-asset-html-webpack-plugin或者本身修改HtmlWebpackPlugin的配置实现打包出的html内自动引入dll.js文件。
jquery
关于HtmlWebpackPlugin详细配置能够看这篇文章:
html-webpack-plugin用法全解
关于add-asset-html-webpack-plugin详细配置能够看这篇文章:
add-asset-html-webpack-plugin配置webpack
另外使用cdn引入包而后加 externals配置的方式也能够,思路和dll一致,都是抽离第三方包,只打包业务代码,只不过这种方式第三方包直接引用cdn上的。git
extensions: ['.js', '.vue', '.json','.scss','.css'],
写这么多自动补全写代码的时候是省了后缀名了,可是这须要webpack打包时去自动查询后缀增长了时间开销。import './components/scroll/index.js'
而不是import './components/scroll
,减小webpack的路径查询。指导思想:减小打包过程当中要作的额外的工做
github
咱们的目的就是优化打包速度,那么与这个无关的没必要要的功能能够先暂停掉,用到时再开。
sourcemap有如下几个配置值:
eval: 生成代码 每一个模块都被eval执行,而且存在@sourceURL
cheap-eval-source-map: 转换代码(行内) 每一个模块被eval执行,而且sourcemap做为eval的一个dataurl
cheap-module-eval-source-map: 原始代码(只有行内) 一样道理,可是更高的质量和更低的性能
eval-source-map: 原始代码 一样道理,可是最高的质量和最低的性能
cheap-source-map: 转换代码(行内) 生成的sourcemap没有列映射,从loaders生成的sourcemap没有被使用
cheap-module-source-map: 原始代码(只有行内) 与上面同样除了每行特色的从loader中进行映射
source-map: 原始代码 最好的sourcemap质量有完整的结果,可是会很慢
复制代码
当咱们不须要调试时,能够关掉sourcemap或下降sourcemap的级别来加快打包的速度。
指导思想:并行打包速度固然快。
这个比较好配置,UglifyJSPlugin插件下加一个属性parallel设为true便可。
new UglifyJSPlugin({
parallel: true
......
})
复制代码
还能够设置打包缓存,具体见下面的配置
Happypack经过多进程模型,来加速代码构建。
好比说之前使用vue-loader处理vue文件,之前是串行处理,如今利用happypack能够并行使用vue-loader处理vue文件。
npm install --save-dev happypack
const HappyPack = require('happypack');
const vueLoaderConfig = require('./vue-loader.conf')
exports.module = {
rules: [
{
test: /\.vue$/,
//vue-loader替换为happypack/loader,若是遇到vue文件就用happypack,id指定为vue
loader: 'happypack/loader?id=vue'
},
{
test: /\.js$/,
//babel-loader替换为happypack/loader,若是遇到js文件就用happypack,id指定为js
loader: 'happypack/loader?id=js'
}
......
]
};
exports.plugins = [
new HappyPack({
id:'vue',
//同时开多少线程进行打包,也能够用ThreadPool控制
threads: 4,
loaders: [{
//这是真实的处理loader,具体配置和rules里本来的一致,options也照搬过来就行
loader:'vue-loader',
options:vueLoaderConfig
}]
}),
new HappyPack({
id: 'js',
threads: 3,
loaders: [{
loader:'bable-loader',
}]
})
......
];
复制代码
通过以上配置,咱们就可使用happypack愉快的进行打包了。
更多高级配置能够看文档:Happypack文档
另外,想了解happypack原理的能够看淘宝团队的这篇文章:happypack 原理解析
指导思想:鸟枪换大炮,升级打包工具。
不少时候,大神们在冥冥之中已经帮咱们在底层作了优化,咱们根本不须要作什么配置,咱们只须要升级工具便可,固然,升级的同时要保证项目的健壮性。
一图胜千言,这是通过优化后的打包时间:
打包时间从原来的的120s减小到了如今的34s,优化率70%以上。不再用每次npm run 一下就先去上个厕所了。。。