最近基于 Vue-cli3 打包的项目进行了一次整体优化,在这里分享下一些心得。
本 Chat 你将学到以下内容:
- Vue 项目首屏加载优化
- Vue 项目代码层面优化细节
- 注:本文只适用于 vue-cli 初始化的项目或依赖于 webpack 打包的项目 *
背景:基于 vue-cli3 创建的项目编译后发布测试,发现有个文件 chunk-vendors 文件大小达到 846kb,加载耗时达到 7.38s 左右,首屏白屏时间过长。针对这个进行以下优化:
这个我在项目里已经做到了,但是针对这个汇总再简单总结下
{ path: '/', name: 'home', component: () => import(/* webpackChunkName: "home" */ './views/home/index.vue'), meta: { isShowHead: true }}
我这里是结合 ES 提出的 import
方法和 webpack 魔法注释 /* webpackChunkName: "group-foo" */
轻松实现路由懒加载
尽管第一步已经做到了,但仍然有 846k 的大小,所以需要继续优化。开启 Gzip 就是一种压缩技术,需要前端提供压缩包,然后在服务器开启压缩,文件在服务器压缩后传给浏览器,浏览器解压后进行再进行解析。首先安装 webpack 提供的compression-webpack-plugin
进行压缩,然后在 vue.config.js:
const CompressionWebpackPlugin = require('compression-webpack-plugin')const productionGzipExtensions = ['js', 'css']......plugins: [ new CompressionWebpackPlugin({ algorithm: 'gzip', test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'), threshold: 10240, minRatio: 0.8 })]....
然后在 Nginx 配置
gzip_min_length 1k; gzip_comp_level 9; gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; gzip_vary on; gzip_disable "MSIE [1-6]\.";
此时我们再看 chunk-vendors 文件大小达到 227k,耗时 1.7s
我们继续采用 cdn 的方式来引入一些第三方资源,就可以缓解我们服务器的压力,原理是将我们的压力分给其他服务器点。首先在 index.html 中:
然后在 vue.config.js 中通过 externals 外部扩展,可以忽略不需要打包的库:
module.exports = { ...... configureWebpack: (config) => ({ externals: { 'vue': 'Vue', 'vue-router': 'VueRouter', 'axios': 'axios', 'element-ui': 'ElementUI' } })......}
main.js
import Vue from 'vue' // 下面有用到所以没注释// import ElementUI from 'element-ui' // 注释// import axios from 'axios' // 注释
store.js
// import Vue from 'vue' // 注释// Vue.use(Vuex) // 注释import Vuex from 'vuex'
router.js
// import Vue from 'vue' // 注释// Vue.use(Router) // 注释import Router from 'vue-router'
这个时候我们再来看下效果:可以看到 chunk-verdors 文件已减小到 20.9kb,耗时 172ms,基本项目秒开无压力了。
——在 vue.config.js 中设置 productionSourceMap:false 这样打包后 map 文件就没了,map 文件的作用在于:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。有了 map 就可以像未加密的代码一样,准确的输出是哪一行哪一列有错。如果不需要的话可以这样操作。
——修改 uglifyOptions 去除 console 来减少文件大小,如果代码中打了很 log,这个优化还是有点效果的。
代码层面优化针对 vue 项目代码层面优化就得回归到.vue 文件中对 HTML、CSS、javascript 进行优化,那么主要就是、
、
中可优化的点:
- computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值。当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算;
- watch:类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show 则适用于需要非常频繁切换条件的场景。这里要说的优化点在于减少页面中 dom 总数,我比较倾向于使用 v-if,因为减少了 dom 数量。
v-for 遍历必须为 item 添加 key,且避免同时使用 v-if- v-for 遍历必须为 item 添加 key,循环调用子组件时添加 key,key 可以唯一标识一个循环个体,可以使用例如 item.id 作为 key
- 避免同时使用 v-if,v-for 比 v-if 优先级高,如果每一次都需要遍历整个数组,将会影响速度。
vue-lazyload)可参考下官方介绍,不再赘述。
style 方面- style 文件按照模块划分,无论放在内外都
锁住样式,目的就是避免多人开发样式混乱,锁住之后内部的命名也可以很简短。
- 全局样式抽象化,将公共组件以及 elementUI 修改的样式建议都放到公共样式,抽象做的越好说明你的样式文件体积越小,复用率越高。
- 使用重复率高的模块尽量封装成组件,包括布局的封装,按钮,表单,提示框,弹出框等,封装的组件只处理类似业务,复用率越高越好
- 封装组件配置的 props 细化到一个字段,不要一个对象传进去,这样只传需要修改的参数,在子组件 props 里加数据类型,是否必传,以及默认值,便于排查错误,让传值更严谨。
结尾:另外还有诸如 SSR(服务端渲染),首页骨架屏加载等优化方法都可以考虑下,还有其他优化点铁子们可以评论区一块讨论下~
阅读全文: http://gitbook.cn/gitchat/activity/5e8ef824cac0955c24ce9630
您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。