原因
在使用vue开发单页面应用时,随着项目页面的增多,你会发现生产环境的build速度会很慢,同时页面初始的js大小越来越大。当你无法忍受的时候就该优化了。
思路
这方面的优化无非就是异步加载、提取一部分长期不需要更新代码的基础js库。
方案
一、异步加载(懒加载)
可以采用vue-router的路由懒加载点击链接进行学习
二、对于提取基础库
可以学习下DllPlugin和DllReferencePlugin两个插件,同时配合(add-asset-html-webpack-plugin)一起完成提取到自动引入。
第一步:新建一个webpack.dll.config.js(名字自己定义)
值得关注的是lib数组(资源依赖包,提前编译)这里根据自己项目的具体引用情况自行添加
const webpack = require(‘webpack‘);
const path = require(‘path‘);
const isDebug = process.env.NODE_ENV === ‘development‘;
const outputPath = isDebug ? path.join(__dirname, ‘../src/common/debug‘) : path.join(__dirname, ‘../src/common/dist‘);
const fileName = ‘[name]_[hash].js‘;
// 资源依赖包,提前编译
const lib = [
‘vue‘,
‘vuex‘,
‘vue-router‘,
‘axios‘,
‘body-parser‘,
‘cookie-parser‘,
‘weixin-js-sdk‘,
‘element-ui‘,
‘vue-scroll‘
];
const plugin = [
new webpack.DllPlugin({
/**
* path
* 定义 manifest 文件生成的位置
* [name]的部分由entry的名字替换
*/
path: path.join(outputPath, ‘manifest.json‘),
/**
* name
* dll bundle 输出到那个全局变量上
* 和 output.library 一样即可。
*/
name: ‘[name]_[hash]‘,
context: __dirname
}),
new webpack.optimize.OccurrenceOrderPlugin()
];
if (!isDebug) {
plugin.push(
// new webpack.DefinePlugin({
// ‘process.env.NODE_ENV‘: JSON.stringify(‘production‘)
// }),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
})
)
}
module.exports = {
devtool: ‘#source-map‘,
entry: {
lib: lib
},
output: {
path: outputPath,
filename: fileName,
/**
* output.library
* 将会定义为 window.${output.library}
* 在这次的例子中,将会定义为`window.vendor_library`
*/
library: ‘[name]_[hash]‘,
libraryTarget: ‘umd‘,
umdNamedDefine: true
},
plugins: plugin
}
第二步:执行构建
简单的方式是在package.json文件中添加(需要注意的使用的是webpack2)
"dll-production": "NODE_ENV=production webpack --config build/webpack.dll.config.js --progress",
"dll-test": "NODE_ENV=development webpack --config build/webpack.dll.config.js --progress",
然后通过npm run dll-production 和 npm run dll-test进行构建
正如NODE_ENV的值一样不同环境引用不同路径下的lib.js
构建后目录如下图
第三步:引入lib.js
#安装add-asset-html-webpack-plugin
$ npm install --save-dev add-asset-html-webpack-plugin
修改开发环境webpack.dev.config.js
#初始化
const AddAssetHtmlPlugin = require(‘add-asset-html-webpack-plugin‘)
在plugins中添加
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require(path.join(__dirname, ‘../src/common/debug/manifest.json‘))
}),
new AddAssetHtmlPlugin({ filepath: path.resolve(__dirname, ‘../src/common/debug/lib_*.js‘) }),
执行npm run dev
修改生产环境webpack.prod.config.js
#初始化
const AddAssetHtmlPlugin = require(‘add-asset-html-webpack-plugin‘)
在plugins中添加
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require(path.join(__dirname, ‘../src/common/dist/manifest.json‘))
}),
new AddAssetHtmlPlugin({ filepath: path.resolve(__dirname, ‘../src/common/dist/lib_*.js‘) }),
执行npm run build(同时与以前的构建速度对比,你会发现节省了很多时间,目前我的项目省了1/3时长)
dll-plugin与CommonsChunkPlugin(webpack4中替换为SplitChunksPlugin)区别
共同点:都是提取公共模块到父模块中,利用缓存来提高访问速度(第一次加载除外)
区别:dll-plugin需要手动去配置和打包公共模块,CommonsChunkPlugin则是每次构建时按照配置打包公共模块。
使用 DllPlugin 将更改不频繁的代码进行单独编译。这将改善引用程序的编译速度,即使它增加了构建过程的复杂性。
webpack文档也推荐使用dll-plugin进行公共模块的分离。