webpack打包优化的几个方法总结
为什么要优化打包?
- 项目越做越大,依赖包越来越多,打包文件太大
- 单页面应用首页白屏时间长,用户体验差
我们的目的
- 减小打包后的文件大小
- 首页按需引入文件
- 优化webpack打包时间
优化方式
1、按需加载
1.1路由组件按需加载
constrouter=[
{
path:'/index',
component:resolve=>require.ensure([],()=>resolve(require('@/components/index')))
},
{
path:'/about',
component:resolve=>require.ensure([],()=>resolve(require('@/components/about')))
}
]
1.2第三方组件和插件。按需加载需引入第三方组件
//引入全部组件
importElementUIfrom'element-ui'
import'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
//按需引入组件
import{Button}from'element-ui'
Vue.component(Button.name,Button)
1.3对于一些插件,如果只是在个别组件中用的到,也可以不要在main.js里面引入,而是在组件中按需引入
//在main.js引入
importVuefromvue
importVuelidatefrom'vuelidate'
Vue.use(Vuelidate)
//按组件按需引入
import{Vuelidate}from'vuelidate'
2、优化loader配置
- 优化正则匹配
- 通过cacheDirectory选项开启缓存
- 通过include、exclude来减少被处理的文件。
module:{
rules:[
{
test:/\.js$/,
loader:'babel-loader?cacheDirectory',
include:[resolve('src')]
}
]
}
3、优化文件路径——省下搜索文件的时间
- extension配置之后可以不用在require或是import的时候加文件扩展名,会依次尝试添加扩展名进行匹配。
- mainFiles配置后不用加入文件名,会依次尝试添加的文件名进行匹配
- alias通过配置别名可以加快webpack查找模块的速度。
resolve:{
extensions:['.js','.vue','.json'],
alias:{
'vue$':'vue/dist/vue.esm.js',
'@':resolve('src'),
}
},
4、生产环境关闭sourceMap
- sourceMap本质上是一种映射关系,打包出来的js文件中的代码可以映射到代码文件的具体位置,这种映射关系会帮助我们直接找到在源代码中的错误。
- 打包速度减慢,生产文件变大,所以开发环境使用sourceMap,生产环境则关闭。
5、代码压缩
- UglifyJS:vue-cli默认使用的压缩代码方式,它使用的是单线程压缩代码,打包时间较慢
- ParallelUglifyPlugin:开启多个子进程,把对多个文件压缩的工作分别给多个子进程去完成
两种方法使用如下:
plugins:[
newUglifyJsPlugin({
uglifyOptions:{
compress:{
warnings:false
}
},
sourceMap:true,
parallel:true
}),
newParallelUglifyPlugin({
//缓存压缩后的结果,下次遇到一样的输入时直接从缓存中获取压缩后的结果并返回,
//cacheDir用于配置缓存存放的目录路径。
cacheDir:'.cache/',
sourceMap:true,
uglifyJS:{
output:{
comments:false
},
compress:{
warnings:false
}
}
})
]
6、提取公共代码
- 相同资源重复被加载,浪费用户流量,增加服务器成本。
- 每个页面需要加载的资源太大,导致网页首屏加载缓慢,影响用户体验。
webpack3使用CommonsChunkPlugin的实现:
plugins:[
newwebpack.optimize.CommonsChunkPlugin({
name:'vendor',
minChunks:function(module,count){
console.log(module.resource,`引用次数${count}`)
//"有正在处理文件"+"这个文件是.js后缀"+"这个文件是在node_modules中"
returnmodule.resource&&/\.js$/.test(module.resource)&&module.resource.indexOf(path.join(__dirname,'./node_modules'))===0
}
}),
newwebpack.optimize.CommonsChunkPlugin({
name:'common',
chunks:'initial',
minChunks:2
})
]
webpack4使用splitChunks的实现:
module.exports={
optimization:{
splitChunks:{
cacheGroups:{
vendor:{
priority:1,//添加权重
test:/node_modules/,//把这个目录下符合下面几个条件的库抽离出来
chunks:'initial',//刚开始就要抽离
minChunks:2//重复2次使用的时候需要抽离出来
},
common:{
//公共的模块
chunks:'initial',
minChunks:2
}
}
}
}
}
7、CDN优化
- 随着项目越做越大,依赖的第三方npm包越来越多,构建之后的文件也会越来越大。
- 再加上又是单页应用,这就会导致在网速较慢或者服务器带宽有限的情况出现长时间的白屏。
1、将vue、vue-router、vuex、element-ui和axios这五个库,全部改为通过CDN链接获取,在index.html里插入相应链接。
2、在webpack.config.js配置文件
module.exports={
···
externals:{
'vue':'Vue',
'vuex':'Vuex',
'vue-router':'VueRouter',
'element-ui':'ELEMENT',
'Axios':'axios'
}
},
3、卸载依赖的npm包,npmuninstallaxioselement-uivuevue-routervuex
4、修改main.js文件里之前的引包方式
//importVuefrom'vue'
//importElementUIfrom'element-ui'
//import'element-ui/lib/theme-chalk/index.css'
//importVueRouterfrom'vue-router'
importAppfrom'./App.vue'
importroutesfrom'./router'
importutilsfrom'./utils/Utils'
Vue.use(ELEMENT)
Vue.use(VueRouter)
constrouter=newVueRouter({
mode:'hash',//路由的模式
routes
})
newVue({
router,
el:'#app',
render:h=>h(App)
})
8、使用HappyPack多进程解析和处理文件
- 由于运行在Node.js之上的Webpack是单线程模型的,所以Webpack需要处理的事情需要一件一件的做,不能多件事一起做。
- HappyPack就能让Webpack把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程。
- HappyPack对file-loader、url-loader支持的不友好,所以不建议对该loader使用。
使用方法如下:
1、HappyPack插件安装:npmi-Dhappypack
2、webpack.base.conf.js文件对module.rules进行配置
module:{
rules:[
{
test:/\.js$/,
use:['happypack/loader?id=babel'],
include:[resolve('src'),resolve('test')],
exclude:path.resolve(__dirname,'node_modules')
},
{
test:/\.vue$/,
use:['happypack/loader?id=vue']
}
]
}
3、在生产环境webpack.prod.conf.js文件进行配置
constHappyPack=require('happypack')
//构造出共享进程池,在进程池中包含5个子进程
constHappyPackThreadPool=HappyPack.ThreadPool({size:5})
plugins:[
newHappyPack({
//用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
id:'babel',
//如何处理.js文件,用法和Loader配置中一样
loaders:['babel-loader?cacheDirectory'],
threadPool:HappyPackThreadPool
}),
newHappyPack({
id:'vue',//用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
loaders:[
{
loader:'vue-loader',
options:vueLoaderConfig
}
],
threadPool:HappyPackThreadPool
})
]
总结
- 比较实用的方法:按需加载,优化loader配置,关闭生产环境的sourceMap,CDN优化。
- vue-cli已做的优化:代码压缩,提取公共代码,再优化空间不大。
- 根据项目实际需要和自身开发水平选择优化方法,必须避免因为优化产生bug。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。