VUE项目优化汇总

  • 注:本文只适用于 vue-cli 初始化的项目或依赖于 webpack 打包的项目 *

首屏加载优化

背景:基于vue-cli3创建的项目编译后发布测试,发现有个文件chunk-vendors文件大小达到846kb,加载耗时达到7.38s左右,首屏白屏时间过长。


1.png

针对这个进行以下优化:

  1. 路由懒加载
    这个我在项目里已经做到了,但是针对这个汇总再简单总结下
{
      path: '/',
      name: 'home',
      component: () => import(/* webpackChunkName: "home" */ './views/home/index.vue'),
      meta: { isShowHead: true }
}

我这里是结合ES 提出的 import方法和webpack魔法注释 /* webpackChunkName: "group-foo" */轻松实现路由懒加载

  1. 开启服务器Gzip
    尽管第一步已经做到了,但仍然有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


2.jpg
  1. 启动CDN加速
    我们继续采用cdn的方式来引入一些第三方资源,就可以缓解我们服务器的压力,原理是将我们的压力分给其他服务器点。
    首先在index.html中:
 <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
  <script src="https://cdn.bootcss.com/vue-router/3.0.3/vue-router.min.js"></script>
  <script src="https://cdn.bootcss.com/element-ui/2.8.2/index.js"></script>
  <script src="https://cdn.bootcss.com/axios/0.19.2/axios.js"></script>

然后在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'

这个时候我们再来看下效果:


3.png

可以看到chunk-verdors文件已减小到20.9kb,耗时172ms,基本项目秒开无压力了。

  1. 其他优化点
    ——在vue.config.js中设置productionSourceMap:false这样打包后map文件就没了,map文件的作用在于:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。有了map就可以像未加密的代码一样,准确的输出是哪一行哪一列有错。如果不需要的话可以这样操作。
    ——修改uglifyOptions去除console来减少文件大小,如果代码中打了很log,这个优化还是有点效果的。

代码层面优化

针对vue项目代码层面优化就得回归到.vue文件中对HTML、CSS、javascript进行优化,那么主要就是<template><style><script>中可优化的点:

  1. computed 和 watch 区分使用场景
    • computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值。当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算;
    • watch:类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
  2. v-if 和 v-show 区分使用场景
    v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show则适用于需要非常频繁切换条件的场景。这里要说的优化点在于减少页面中 dom 总数,我比较倾向于使用 v-if,因为减少了 dom 数量。
  3. v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
    • v-for 遍历必须为 item 添加 key,循环调用子组件时添加 key,key 可以唯一标识一个循环个体,可以使用例如 item.id 作为 key
    • 避免同时使用 v-if,v-for 比 v-if 优先级高,如果每一次都需要遍历整个数组,将会影响速度。
  4. 图片懒加载
    vue-lazyload可参考下官方介绍,不再赘述。
  5. style方面
    • style文件按照模块划分,无论放在内外都<style lang="scss" scoped> 锁住样式,目的就是避免多人开发样式混乱,锁住之后内部的命名也可以很简短。
    • 全局样式抽象化,将公共组件以及elementUI修改的样式建议都放到公共样式,抽象做的越好说明你的样式文件体积越小,复用率越高。
  6. 合理组件化
    • 使用重复率高的模块尽量封装成组件,包括布局的封装,按钮,表单,提示框,弹出框等,封装的组件只处理
      类似业务,复用率越高越好
    • 封装组件配置的 props 细化到一个字段,不要一个对象传进去,这样只传需要修改的参数,在子组件 props 里加数据类型,是否必传,以及默认值,便于排查错误,让传值更严谨。

结尾:另外还有诸如SSR(服务端渲染),首页骨架屏加载等优化方法都可以考虑下,还有其他优化点铁子们可以评论区一块讨论下~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • 主要分为三个方面来优化 Vue 代码层面的优化 webpack 配置层面的优化 基础的 Web 技术层面的优化 一...
    alanwhy阅读 786评论 0 10
  • 前言 Vue 框架通过数据双向绑定和虚拟 DOM 技术,帮我们处理了前端开发中最脏最累的 DOM 操作部分, 我们...
    一个正在努力的人类阅读 562评论 0 4
  • ## 框架和库的区别?> 框架(framework):一套完整的软件设计架构和**解决方案**。> > 库(lib...
    Rui_bdad阅读 2,890评论 1 4
  • Vue.js是什么 Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的 渐进式框架。与其...
    鱼鱼吃猫猫阅读 3,229评论 1 12
  • 响应式布局的理解 响应式开发目的是一套代码可以在多种终端运行,适应不同屏幕的大小,其原理是运用媒体查询,在不同屏幕...
    懒猫_6500阅读 779评论 0 0