react面试:react diff算法的演化(三)

react的diffi算法一直优化升级,现在又改为链表方式,diffi算法核心就是对比和修改,它的工作原理据于以下两条需求:

  • 两个不同类型的元素将产生两个不同的树;
  • 同一级的一组子节点,可以从中埋入一个key属性用于区分;

一、传统的diff算法是两棵树进行循环比较,那么它的比较次数就是O(n^2),n*n。

二、React 15的Diff算法,针对以上两个需求,它有三种策略:

  (一)Tree Diff算法:

Tree Diff 是两颗新旧虚拟树按照层级对应关系,把同一父节点的同一层级的节点遍历一遍,找到差异节点。

这种比较适用于DOM节点跨层级操作少的情形,这样就可以忽略不计层级带来的影响。它的分层比较,层级控制非常高效,当发现子节点不在了将会直接删除该节点以及它下面的所有子节点,也就是只需要遍历一遍。

  (二)Component Diff算法:

React构建的应用是以组件组合而成的,以组件为单位的差异对比策略也类似。

对于类型相同的组件,可以根据VDOM树按照原来的策略继续比较Tree即可。

对于类型不同的组件,React会将整个组件内部的所有的子节点重新替换。

  (三)Element Diff算法:

React在遇到类型相同的组件时,会继续对组件内部元素进行对比,检查内部元素的异同,这就是Element Diff。

不带key的组件,即使是相同节点,而且只是位移,还是需要删除并重写,无疑这种操作很繁琐并且低效。

在React中,可以给每个同层组件设置一个唯一的key,用来做标记。这样diff出不同的时候,只需要将节点集合进行位移即可。

具体的执行是,先将新节点集合进行遍历,然后通过唯一的key去老节点集合中寻找是否有命中的标记,如果有就执行移动操作。

总结:

  • Tree diff:采用分层求异的策略,将新旧两棵DOM树按照层级关系进行比较,这样只需要遍历一遍,就能搞找到那些元素需要更新。
  • Component diff:查看组件类型是否相同。如果类型不同,则需要更新,更新时先把旧组件删除,再创建一个新的组件插入之前删除的位置。
  • Element diff:通过唯一key,对元素diff进行优化。元素发生了改变,则找到需要修改的元素,有针对性进行修改。

三、Fiber的算法:

(一)Fiber Reconciler 在阶段一进行 Diff 计算的时候,会生成一棵 Fiber 树。这棵树是在 Virtual DOM 树的基础上增加额外的信息来生成的,它本质来说是一个链表。

Fiber 树在首次渲染的时候会一次过生成。在后续需要 Diff 的时候,会根据已有树和最新 Virtual DOM 的信息,生成一棵新的树。这颗新树每生成一个新的节点,都会将控制权交回给主线程,去检查有没有优先级更高的任务需要执行。如果没有,则继续构建树的过程:

如果过程中有优先级更高的任务需要进行,则 Fiber Reconciler 会丢弃正在生成的树,在空闲的时候再重新执行一遍。

在构造 Fiber 树的过程中,Fiber Reconciler 会将需要更新的节点信息保存在Effect List当中,在阶段二执行的时候,会批量更新相应的节点。

(二)reconcile过程分为2个阶段(phase):

  1. (可中断)render/reconciliation 通过构造workInProgress tree得出change,    即requestIdleCallback 可以中断的

  2. (不可中断)commit 应用这些DOM change  ,即commit   不可中断的,一口气完成。

(三)生命周期函数变了:

生命周期函数也被分为2个阶段了:

第1阶段的生命周期函数可能会被多次调用,默认以low优先级(后面介绍的6种优先级之一)执行,被高优先级任务打断的话,稍后重新执行

// 第1阶段 render/reconciliation
componentWillMount
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate

// 第2阶段 commit
componentDidMount
componentDidUpdate
componentWillUnmount

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值