如何打造更快更轻的 Vue 应用

本文主要针对自己最近项目中遇到的一些问题,并参照网上的一些文章,整理了部分 Vue 性能优化上的点。

代码优化

v-show 和 v-if 的使用

使用了v-if的时候,如果值为false,那么页面将不会有这个 html 标签生成,而v-show则不管值为 true 还是 false,html 元素都会存在,只是 CSS 中的 display 显示或隐藏, 因此需要频繁切换的用 v-show。

Object.freeze()

Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改,冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。而在 vue 中,对于 data 或 vuex 里使用 freeze 冻结了的对象,vue 不会做 getter 和 setter 的转换,因此如果你有一个巨大的数组或者 Object,并且确信数据不会修改,使用 Object.freeze() 可以让性能大幅提升。

谨慎使用 deep watch

根据本人血与泪的教训,当你对一个巨大的 Object 或者数组使用 deep watch 时,性能的开销是你无法想象的痛。

watch, computed, update 或 beforeUpdate 中避免复杂的逻辑

复杂的逻辑可能会触发额外的组件渲染,甚至可能会引起循环渲染的问题。常见的一些情况如下:

  • 在计算属性中去设置数据。
  • beforeUpdate 中去设置数据,可能会让组件重新渲染。
  • watch 中去修改一些值,一不小心可能会重新触发 watch。

打包优化

分析包大小

我们可以通过 webpack-bundle-analyzer 来分析我们打包后文件的组成及大小。

  • 安装

    1
    npm install webpack-bundle-analyzer --save-dev
  • 使用

  1. 配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

    configureWebpack: {
    ...,
    plugins: [
    new BundleAnalyzerPlugin({
    analyzerMode: 'disabled',
    generateStatsFile: true,
    statsOptions: { source: false }
    })
    ]
    }
  2. package.json中添加脚本

    1
    "bundle-report": "webpack-bundle-analyzer --port 8888 dist/stats.json"
  3. 打包后执行

    1
    npm run bundle-report

    浏览器会自动打开分析页面:http://127.0.0.1:8888

谨慎使用第三方库

从上面的分析图中不难发现,我的项目中引用的第三方库占用了极大的比例,而其中 codemirror, lodash, moment, element-ui 等库都是比较常见的库。但是针对这些库,我们并没有使用他们全部的组件或功能,我们使用的也许仅仅是其中的部分甚至可能只是很小的一个方法,比如我的代码中,其实只使用了 lodash 的 cloneDeep 方法。
针对以上情况,我们可以采取以下措施:

  1. 删除完整的 lodash,自己实现 cloneDeep 方法

  2. 用轻量级的 vueCodeMirrorLite 替代 codemirror

  3. 使用插件摆脱 moment 自带的语言环境

    1
    2
    3
    plugins: [
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
    ]

    或者用轻量级的 date-fns 代替。

  4. 自己实现项目的组件库,摆脱 element 的依赖。

这里,推荐 Bundle Phobia 来查看引用库的大小。

路由懒加载

这个在官网中也有描述,这里就不再展开了。

总结

以上是个人的一点总结和想法,当然这也仅仅是 vue 性能优化中的冰上一角,还有很多网络,图像,缓存等等 web 实践相关的优化值得我们去思考。

查看评论