【Vue】性能优化

使用 key

对于通过循环生成的列表,应给每个列表项一个稳定且唯一的 key,这有利于在列表变动时,尽量少的删除和新增元素。

使用冻结的对象

冻结的对象(Object.freeze(obj))不会被响应化,不可变。

使用函数式组件

参见函数式组件 | Vue.js (vueframework.com)

使用计算属性

如果模板中某个数据会使用多次,并且该数据是通过计算得到的,使用计算属性以缓存它们。

非实时绑定的表单项

当使用v-mode1绑定一个表单项时,当用户改变表单项的状态时,也会随之改变数据,从而导致vue发生重渲染(rerender),这会带来一些性能的开销。

特别是当用户改变表单项时,页面有一些动画正在进行中,由于JS执行线程和浏览器渲染线程是互斥的,最终会导致动画出现卡顿。

我们可以通过使用lazy或不使用v-model的方式解决该问题,但要注意,这样可能会导致在某一个时间段内数据和表单项的值是不一致的。

但是不使用 v-model 不符合 Vue 的设计理念,只能通过 e.target.value 去进行数据的修改。

保持对象引用稳定

在绝大部分情况下,vue 触发 rerender 的时机是其依赖的数据发生变化。

若数据没有发生变化,哪怕给数据重新赋值了,vue 也是不会做出任何处理的。

下面是vue判断数据没有变化的源码:

js 复制代码
//value为l旧值,newValue为新值
if (newVal == value || (newVal != newVal && value != value)) {
    return 
}

因此,如果需要,只要能保证组件的依赖数据不发生变化,组件就不会重新渲染。

对于原始数据类型,保持其值不变即可。

对于对象类型,保持其引用不变即可。

从另一方面来说,由于可以通过保持属性引用稳定来避免子组件的重渲染,那么我们应该细分组件来尽量避免多余的渲染(只要组件对应的对象 地址不发生改变,则不会重新渲染)。

但是这种也会存在问题,就是数据不是实时的。数据库那边有其他更新操作,而这里页面并没有相应的请求。

那么如何解决这个问题呢?可以使用 websockect,也可以使用发送请求的方式(但是要利用一些对比数据差异的算法)。

使用 v-show 替代 v-if

对于频繁切换显示状态 的元素,使用v-show可以保证虚拟dom树的稳定,避免频繁的新增和删除元素,特别是对于那些内部包含大量dom元素的节点。

使用延迟装载 (defer)

首页白屏时间主要受到两个因素的影响:

  • 打包体积过大

    巨型包需要消耗大量的传输时间,导致JS传输完成前页面只有一个 <div id="app"></ div>

    有可显示的内容。

  • 需要立即渲染的内容太多

    JS传输完成后,浏览器开始执行JS构造页面。

    但可能一开始要渲染的组件太多,不仅JS执行的时间很长,而且执行完后浏览器要渲染的元素过多,从而导致页面白屏。

打包体积过大需要自行优化打包体积。

这里着重说一下渲染内容太多问题:

一个可行的办法就是延迟装载组件,让组件按照先后顺序依次一个一个渲染。

本质上使用 requestAnimationFrame 事件分批渲染内容

keep-alive

长列表渲染

相关推荐
恋猫de小郭1 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅9 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅10 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊10 小时前
jwt介绍
前端