资讯专栏INFORMATION COLUMN

React——diff算法

iliyaku / 414人阅读

摘要:组件层面节点算法只会在相同的组件类型上进行,意味着如果一个组件被替换成了这时前后节点树不会进行对比。

这篇文章只是个人理解,有什么差异和谬误还望大家指出:

原文:http://calendar.perfplanet.com/2013/diff/

不知道是从什么时候开始,写JavaScript的时候,脑袋里面就会一直回响着一句话,尽量避免DOM操作,原因是DOM操作比较消耗性能,特别是在复杂的DOM结构中进行DOM操作。而当我们使用各种各样前端模板引擎的时候,更是无法避免不停地操作DOM。

虚拟DOM

React出于性能的考虑,为了避免频繁操作DOM,采用了虚拟DOM结构(virtual DOM):

每当虚拟DOM树发生变化树发生变化时,React会将当前DOM树和之前的虚拟DOM树进行diff算法对比,得到虚拟DOM结构的区别,然后仅仅渲染差异部分。

    var MyComponent = React.createClass({ 
        render: function() {
            if (this.props.first) { 
                return 
A Span
; } else { return

A Paragraph

; } } });

这里MyComponent执行render方法的结果并不是一个真实的DOM节点,而是一个轻量级的JavaScript对象,即虚拟DOM。

如果我们先插入组件:
React会创建真实DOM节点:

A Span

将之前的组件替换为:
React会替换之前节点的属性:className="first"为className="second",同时替换子节点A Span为<p>A Paragraph</p>

最后移除组件;
React会移除节点

<p>A Paragraph</p>

如果将所有虚拟节点进行改变前后的diff算法比较,这同样是一件消耗性能的过程(两个树的比较复杂度为O(n^3)),React采用了以下优化方案,将性能优化到O(n)。

分层比较

React将虚拟树进行分层比较,这是因为节点操作很少存在跨层级的(比如将子节点移动到父节点外,变成父节点的兄弟节点),大多操作多是在兄弟节点之间的。如下图中,比较只会在相同颜色的兄弟节点之间进行,一旦节点被删除,则所有子节点都会被删除,不会进行比较。

节点列表

假设有这样的情况,一个组件初始化时渲染了5个子节点,第二个时钟周期时向这5个子节点中间插入一个新的组件。这时,如果直接对比前后两个子节点树,新插入节点之后的所有子节点都会被重新渲染(C被替换为F,D被替换为C,E被替换为D),因为他们和之前的节点树不匹配。如同下图的情况:

React在组件插入的过程中,只会将同级子节点按前后顺序排列起来,但是,如果给予每个子节点一个唯一的key值,这样每个子节点都能找到与之对应的节点进行比较。

组件层面

节点diff算法只会在相同的组件类型上进行,意味着如果一个

组件被替换成了,这时前后节点树不会进行对比。React做出这样的取舍是因为耗费大量计算去匹配两个几乎不会相似的组件是一种浪费。而事实上,大多数用户会用大量的div去构建一个节点树,React在不会匹配不同class的组件。

参考文章: http://www.infoq.com/cn/articles/react-dom-diff?from=timeline&isappinstalled=0

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78769.html

相关文章

  • 谈谈ReactDiff算法的策略及实现

    摘要:并且处理特殊属性,比如事件绑定。之后根据差异对象操作元素位置变动,删除,添加等。当节点数过大或者页面更新次数过多时,页面卡顿的现象会比较明显。基于注意使用来减少组件不必要的更新。 1、什么是Diff算法 传统Diff:diff算法即差异查找算法;对于Html DOM结构即为tree的差异查找算法;而对于计算两颗树的差异时间复杂度为O(n^3),显然成本太高,React不可能采用这种...

    Scliang 评论0 收藏0
  • 谈谈ReactDiff算法的策略及实现

    摘要:并且处理特殊属性,比如事件绑定。之后根据差异对象操作元素位置变动,删除,添加等。当节点数过大或者页面更新次数过多时,页面卡顿的现象会比较明显。基于注意使用来减少组件不必要的更新。 1、什么是Diff算法 传统Diff:diff算法即差异查找算法;对于Html DOM结构即为tree的差异查找算法;而对于计算两颗树的差异时间复杂度为O(n^3),显然成本太高,React不可能采用这种...

    HmyBmny 评论0 收藏0
  • React diff原理探究以及应用实践

    摘要:但是加了一定要比没加的性能更高吗我们再来看一个例子现在有一集合渲染成如下的样子现在我们将这个集合的顺序打乱变成。不加操作修改第个到第个节点的如果我们对这个集合进行增删的操作改成。 抛砖引玉 React通过引入Virtual DOM的概念,极大地避免无效的Dom操作,已使我们的页面的构建效率提到了极大的提升。但是如何高效地通过对比新旧Virtual DOM来找出真正的Dom变化之处同样也...

    EasonTyler 评论0 收藏0
  • react虚拟dom机制与diff算法

    摘要:的一个突出特点是拥有极速地渲染性能。该功能依靠的就是研发团队弄出的虚拟机制以及其独特的算法。在的算法下,在同一位置对比前后节点只要发现不同,就会删除操作前的节点包括其子节点,替换为操作后的节点。 React的一个突出特点是拥有极速地渲染性能。该功能依靠的就是facebook研发团队弄出的虚拟dom机制以及其独特的diff算法。下面简单解释一下react虚拟dom机制和diff算法的实现...

    jzman 评论0 收藏0
  • React 源码剖析系列 - 不可思议的 react diff

    摘要:目前,前端领域中势头正盛,使用者众多却少有能够深入剖析内部实现机制和原理。当发现节点已经不存在,则该节点及其子节点会被完全删除掉,不会用于进一步的比较。 目前,前端领域中 React 势头正盛,使用者众多却少有能够深入剖析内部实现机制和原理。本系列文章希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然。 React diff 作为 Virtual DOM 的加速...

    shuibo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<