背景:由于目前线上版本的h5加载一直很慢,于是趁着最近有空就打算优化一下,首先打开network分析影响加载速度的文件有哪些。
看原文件大小有接近1.4m,不能忍!!!
注意:
1、博主这里用的vue-cli2.x版本,webpack为3.6.0版本。
2、vendor文件一般放的是长时间不怎么更新的库,比如vue、vuex、vue-router等等。
开始搞事情。
1、删除多余的第三方库。
检查自己package.json文件下dependencies里面有哪些是安装引用了但是没用的。因为里面可能存在当时做项目测demo引入的库忘记删除,挨个挨个筛选,找到以后执行下面的命令将其卸载。
npm un xxxx
这一步执行完后博主的vendor文件体积减少了接近400k。
2、拆分体积较大的文件为多个小文件
// webpack.base.conf.js
// entry: {
// app: './src/main.js'
// },
// webpack.dev.conf.js
entry: {
app: './src/main.js'
},
// webpack.prod.conf.js
entry: {
vendor1: ["vue-router", "vuex", "vue"]],
vendor2: ["js-cookie", "v-viewer", "clipboard"],
vendor3: ["element-ui"],
app: './src/main.js'
},
new webpack.optimize.CommonsChunkPlugin({
// 这里要跟entry配置的顺序反着来,否则不能成功
names: ["vendor3", "vendor2", "vendor1"],
minChunks: Infinity
// 下面是cli默认配置
// name: 'vendor',
// minChunks (module) {
// // any required modules inside node_modules are extracted to vendor
// return (
// module.resource &&
// /\.js$/.test(module.resource) &&
// module.resource.indexOf(
// path.join(__dirname, '../node_modules')
// ) === 0
// )
// }
}),
配置完后重新打包,very nice!!! 结果如下:
体积是小了很多,但是这个element-ui也太大了不,光这一个库就有600k,我们给它再处理一下。
3、第三方ui库使用按需加载
使用官方提供的按需加载插件babel-plugin-component,安装
npm install babel-plugin-component -D(等同于--save-dev)
在 .babelrc
里配置 plugins如下 (如果是vue-cli3.x版本的话,则在babel.config.js
文件添加,其他操作一样)
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": [
"transform-vue-jsx",
"transform-runtime",
/************* 添加下面的代码 start ****************/
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
/*************** end **************/
]
}
在src下新建element文件夹,再在element下建一个index.js文件,用于配置element-ui的按需加载,如下:
// src/element/index.js
import { Carousel, Rate, Dialog, Form, FormItem, Checkbox, CarouselItem, InfiniteScroll, Switch, Collapse, CollapseItem, Timeline, TimelineItem } from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import Vue from 'vue'
Vue.use(InfiniteScroll)
Vue.component(Carousel.name, Carousel)
Vue.component(Rate.name, Rate)
Vue.component(Dialog.name, Dialog)
Vue.component(Form.name, Form)
Vue.component(FormItem.name, FormItem)
Vue.component(Checkbox.name, Checkbox)
Vue.component(Switch.name, Switch)
Vue.component(CarouselItem.name, CarouselItem)
Vue.component(Collapse.name, Collapse)
Vue.component(CollapseItem.name, CollapseItem)
Vue.component(Timeline.name, Timeline)
Vue.component(TimelineItem.name, TimelineItem)
在main.js引入该文件,如下:
import './element/index'
再修改webpack.prod.conf.js文件配置如下:
// webpack.prod.conf.js
entry: {
vendor1: ["vue-router", "vuex", "vue"]],
vendor2: ["js-cookie", "v-viewer", "clipboard"],
element: './src/element/index.js',
app: './src/main.js'
},
new webpack.optimize.CommonsChunkPlugin({
// 这里要跟entry配置的顺序反着来,否则不能成功
names: ["element", "vendor2", "vendor1"],
minChunks: Infinity
}),
再次npm run build
走一波,结果如下,可以看到,干了这么多的事,还是很有效果的,element体积只有100k了。
4、gzip压缩
这里还有一个就是gzip
压缩,如果没有启用这个方案的赶紧试一下,据说可以压缩接近70%的体积
,因为博主这里一开始就是配置好的,不受这个影响,也就没写详细过程,想知道自己是否已经开启gzip压缩,可通过如下方式查看:
有gzip就表示开启了的,另外也可以在Reponse Headers查看,如下:
5、图片压缩同时采用cdn引入
图片压缩入口,你们去试一下就知道有多爽,至少可以压缩一半的体积,还高保真,强烈安利!!!
6、设置路由懒加载
// 方法一
{
path: '/demo',
name: 'demo',
component: resolve => require(['@/components/demo'],resolve)
}
方法二:
const Demo= () => import('@/components/demo')
{
path: '/demo',
component: Demo
},
7、禁止打包生成.map文件
// webpack.config.js 与publicPath同级
module.exports = {
...
productionSourceMap: false, // 是否在构建生产包时生成.map文件
...
}
8、预渲染或设置骨架屏
这个方案很多,百度一下你就知道。
注意:预渲染也是有弊端的,需要根据自己的情况酌情使用。