Vue | Vue 开发中的性能优化小技巧,你用过几个

目录

1. 长列表性能优化

2. v-for 遍历避免同时使用 v-if

3. 列表使用唯一 key

4. 使用 v-show 复用 DOM

5. 无状态的组件用函数式组件

6. 子组件分割

7. 变量本地化

8. 第三方插件按需引入

9. 路由懒加载

10. keep-alive缓存页面

11. 事件的销毁

12. 图片懒加载

13. SSR优化


性能优化,是每一个开发者都会遇到的问题,特别是现在越来越重视体验,以及竞争越来越激烈的环境下,对于我们开发者来说,只完成迭代,把功能做好是远远不够的,最重要的是把产品做好,让更多人愿意使用,让用户用得更爽,这不也是我们开发者价值与能力的体现吗?重视性能问题,优化产品的体验,比起改几个无关痛痒的 bug 要有价值得多。

本文记录了在 Vue 项目日常开发中的一些小技巧,废话不多说,我们开始吧!

1. 长列表性能优化

- 1. 不做响应式

比如,会员列表、商品列表之类的,只是纯粹的数据展示,不会有任何动态改变的场景下,就不需要对数据做响应化处理,可以大大提升渲染速度

比如,使用 Object.freeze() 冻结一个对象,​ MDN的描述是该方法冻结的对象不能被修改;即不能向这个对象添加新属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值,以及该对象的原型也不能被修改。

export default {
  data: () => ({
    userList: []
  }),
  async created() {
    const users = await axios.get("/api/users");
    this.userList = Object.freeze(users);
  }
};

Vue2 的响应式源码地址:src/core/observer/index.js - 144行 是这样的

export function defineReactive (...){
    const property = Object.getOwnPropertyDescriptor(obj, key)
    if (property && property.configurable === false) {
        return
    }
    ...
}

可以看到一开始就判断 configurable 为 false 的直接返回不做响应式处理

configurable 为 false 表示这个属性是不能被修改的,而冻结的对象的 configurable 就是为 false

Vue3 里则是添加了响应式flag,用于标记目标对象类型。

★ 番外:在Vue 3中,响应式flag用于标记目标对象的类型,以便Vue的响应式系统能够正确地跟踪和响应式处理不同类型的数据。这是通过使用Proxy来代理对象属性的getter和setter来实现的。

当你尝试使用Vue的响应式系统时,Vue会检查这个flag来决定如何处理这个数据。例如,如果是一个普通的JavaScript对象,Vue会使用Object.defineProperty来实现响应式。如果是一个数组,它会包装数组的prototype。如果是MapSet这样的集合,它会使用Proxy来代理这些数据结构。

以下是一个简单的例子,展示了如何在Vue 3中使用响应式flag:

import { reactive, isReactive } from 'vue';
 
const state = reactive({ count: 0 });
 
console.log(isReactive(state)); // 输出: true
 
// 当state是响应式的时候,Vue可以跟踪其属性的变化
state.count = 1;

- 2. 虚拟滚动

如果是大数据很长的列表,全部渲染的话一次性创建太多 DOM 就会非常卡,这时就可以用虚拟滚动,只渲染少部分(含可视区域)区域的内容,然后滚动的时候,不断替换可视区域的内容,模拟出滚动的效果。

<recycle-scroller
  class="items"
  :items="items"
  :item-size="24"
>
  <template v-slot="{ item }">
    <FetchItemView
      :item="item"
      @vote="voteItem(item)"
    />
  </template>
</recycle-scroller>

参考: vue-virtual-scrollervue-virtual-scroll-list

原理是监听滚动事件,动态更新需要显示的 DOM,并计算出在视图中的位移,这也意味着在滚动过程需要实时计算,有一定成本,所以如果数据量不是很大的情况下,用普通的滚动就行。

2. v-for 遍历避免同时使用 v-if

为什么要避免同时使用 v-for 和 v-if

在 Vue2 中 v-for 优先级更高,所以编译过程中会把列表元素全部遍历生成虚拟 DOM,再来通过 v-if 判断符合条件的才渲染,就会造成性能的浪费,因为我们希望的是不符合条件的虚拟 DOM都不要生成。

在 Vue3 中 v-if 的优先级更高,就意味着当判断条件是 v-for 遍历的列表中的属性的话,v-if 是拿不到的。

所以在一些需要同时用到的场景,就可以通过计算属性来过滤一下列表,如下:

<template>
    <ul>
      <li v-for="item in activeList" :key="item.id">
        {
  { item.title }}
      </li>
    </ul>
</template>
<script>
// Vue2.x
export default {
    computed: {
      activeList() {
        return this.list.filter( item => {
          return item.isActive
        })
      }
    }
}

// Vue3
import { computed } from "vue";
const activeList = computed(() => {
  return list.filter( item => {
    return item.isActive
  })
})
</script>

参考为什么Vue中的v-if和v-for不建议一起用?_vue v-for if-优快云博客 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儒雅的烤地瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值