【Vue/React】浅谈Vue/React中的Diff算法以及key的作用和index不适合作为key的原因

Diff算法

Vue 和 React 都是基于 vdom 的前端框架,组件渲染会返回 vdom,渲染器再把 vdom 通过增删改的 api 同步到 dom。

当状态发生改变时,react会根据【新的状态】生成【新的虚拟DOM】

然后将新旧虚拟DOM进行 diff比较,比较规则如下:

旧虚拟DOM 中找到了与 新虚拟DOM 相同的 key

若虚拟DOM中的内容没变,则直接使用之前的真实DOM

若虚拟DOM中的内容变了,则生成新的真实DOM并进行替换

旧虚拟DOM 中未找到与 新虚拟DOM 相同的 key,则根据数据创建新的真实DOM,然后渲染到页面

这里对比两棵 vdom 树,找到有差异的部分的算法,就叫做 diff 算法。

key的作用

key用于唯一标识dom,提高渲染性能

1.在列表循环中,react/vue都要求加入一个key值来提升性能。key值为是否重新渲染列表项的唯一标识。如果更新前后key值相同,那么就采用就地复用策略,而不是重新去渲染,大大提高了性能。

2.不添加key,diff算法进行的只是浅层比较,例如在新旧DOM对比时,两处引用的是一样的组件component,但它比较到父节点span与div不同就停止比较了,重新渲染span和div下的所有子节点,这样重复渲染太多,效率极低。

虚拟DOM拥有key的更新逻辑

  1. 简单的说: key是虚拟DOM对象的标识,在更新显示时key起着极其重要的作用
  2. 详细的说:当状态中的数据发生变化时,react会根据【新数据】生成新的虚拟DOM
    随后React进行了【新虚拟DOM】和【旧虚拟DOM】的比较,比较规则如下:
    a:旧虚拟DOM找到了与新虚拟DOM相同的key:
    (1).若虚拟DOM中内容没变,直接使用之前的真实DOM
    (2).若虚拟DOM中内容变了,则生成新的真实DOM,随后替换页面中之前的真实DOM
    b:旧虚拟DOM中未找到与新虚拟DOM相同的key
    根据数据创建新的真实DOM随后渲染到页面

用index作为key可能会引发的问题:

  1. 若对数据进行:逆序添加、逆序删除等破坏顺序的操作:会产生没有必要的真实DOM更新 ===>界面效果没问题 但效率低
  2. 如果结构中还包含输入类的DOM,会产生错误的DOM更新 ===>界面有问题
  3. 注意:如果不存在对数据的逆序添加 逆序删除等破坏顺序的操作,仅用于渲染列表展示,使用index作为key是没有问题的。

开发中如何选择key

  1. 最好每条数据的唯一标识作为key,比如id
  2. 如果只是简单的展示数据,index也可以
相关推荐
对空六课1 小时前
两个统计平台数据不同:用同一时间窗和事件样本做差异定位
大数据·前端·网络·数据库
lpfasd1239 小时前
node-sass 停止维护!老项目迁移 Dart Sass 完整教程
前端·rust·sass
Data analyse45611 小时前
rnweb 回放数据量太大怎么办?分片存储与断点续传的实现思路
前端·网络·算法·数据分析
xiaogai_gai11 小时前
金蝶收料通知单查询策略实战教程:从源系统拉取到中间层落地的完整路径
java·前端·数据库
环境栈笔记12 小时前
指纹浏览器 WebRTC 怎么设置?从 ICE 候选、代理出口到功能验证
前端·人工智能·后端·自动化
赵大仁13 小时前
官网性能优化实战:LCP 3.2s → 2.1s、CLS 0.107 → 0,以及被我推翻的 6 个判断
前端·性能优化·cls·lcp·core web vitals
xiancai_xianyu13 小时前
Text2SQL落地生产库前,SQL要过哪三道闸
前端·数据库·sql·sql注入·text2sql·ai agent开发·企业级ai框架
小羊没烦恼!13 小时前
T-SQL查询进阶--理解SQL SERVER中的分区表
服务器·开发语言·前端·javascript·html
史瓦辛格13 小时前
给 DeepSeek Harness 写费用插件:把「这次会话花了多少钱」算准
前端·deepseek
星光不问赶路人13 小时前
Vue 3 + TypeScript 中 enum 的使用实践
前端·vue.js