React——diff算法
react的diff算法基于两个假设:
1.不同类型的元素会产生不同的树
2.通过设置key,开发者能够提示那些子组件是稳定的
diff算法
当比较两个树时,react首先会比较两个根节点,接下来具体的行为取决于根节点的类型。
1.不同类型的元素
如果树的根元素是不同的类型,那么React会拆掉整个旧的书并且用新的树替换。当树被拆掉,DOM节点会被销毁,组件实例会调用componentWillUnmount钩子函数。
当创建出一个新的树,新的DOM节点会被插入到DOM中。组件实例调用componentWillMount钩子和componentDidMount钩子
如从<a>到<img>,从<div>到<from>,<Article
>到<Commit>都会导致重新创建。并且state会被销毁
2.相同类型的DOM元素
当比较两个相同类型的React DOM元素,React会查看它们两个的属性,React仅仅更新被改变的属性,并不会更新底层的DOM节点。当处理完根DOM节点之后,
React又会递归的比较它们的子元素
3.相同类型的组件元素
当组件被更新,组件的实例会保持不变,组件的state还是存在。React更新下面组件实例的props,下面的组件实例调用componentWillReceiveProps钩子和componentWillUpdate钩子。接下来调用render方法并且diff算法在之前的结果和新的结果上递归
在子元素上递归
qq默认情况,当在DOM节点的子元素上递归,React会同时遍历两个列表上的子元素,并且当发现它们不同就会生成一个变化,如下的例子:
将
<ul>
<li>first</li>
<li>second</li>
</ul>
变为
<ul>
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
React会捕获到两个<li>first</li>,两个<li>second</li>,然后将<li>third</li>插入。如果在列表中最开始插入了一个元素,那么性能就会很不好,如下:
将
<ul>
<li>Duke</li>
<li>Villanova</li>
</ul>
变为
<ul>
<li>Connecticut</li>
<li>Duke</li>
<li>Villanova</li>
</ul>
这种情况React会改变每一个子元素。可以通过给元素设置key来解决这个问题。
如果给上面列表中的li设置key
将
<ul>
<li key='1'>Duke</li>
<li key='2'>Villanova</li>
</ul>
变为
<ul>
<li key='3'>Connecticut</li>
<li key='1'>Duke</li>
<li key='2'>Villanova</li>
</ul>
React能够知道<li key='3'>Connecticut</li>是新插入的,并且元素 <li key='1'>Duke</li>和<li key='2'>Villanova</li>仅仅被移动
兄弟元素之间的key需要是唯一的,但是不需要全局唯一。
注:
1.diff算法不会匹配两个不同组件类型的子树,如果你发现你在两个具有非常相似输出的不同组件之间进行交互,你可以把它们写成一个组件
2.key应该是稳定的,可预测的,唯一的。不稳定的key(如:通过Math.random()产生的key)可能会导致组件实例和DOM节点做一些不必要的重建
3.当组件的state或者props改变,React通过把新返回的组件和之前渲染的组件进行比较来确定是否需要更新DOM,如果不相等,就更新DOM
4.在一些情况下,通过重写组件的shouldComponentUpdate钩子函数,可以提高性能。这个钩子函数在重新渲染组件之前被调用,这个钩子的默认行为时返回true,
如果你确定在一些情况下,你的组件不需要更新,那么你可以让shouldComponentUpdate钩子返回false。在组件的shouldComponentUpdate钩子返回false
这样会跳过整个渲染过程,组件不会调用render方法,也不会通过diff算法比较新返回的组件是否也之前的组件相同
React——diff算法的更多相关文章
- React Diff 算法
React介绍 React是Facebook开发的一款JS库,用于构建用户界面的类库. 它采用声明式范例,可以传递声明代码,最大限度地减少与DOM的交互. 特点: 声明式设计:React采用声明范式, ...
- react diff算法浅析
diff算法作为Virtual DOM的加速器,其算法的改进优化是React整个界面渲染的基础和性能的保障,同时也是React源码中最神秘的,最不可思议的部分 1.传统diff算法计算一棵树形结构转换 ...
- React Diff算法
Web界面由DOM树来构成,当其中某一部分发生变化时,其实就是对应的某个DOM节点发生了变化.在React中,构建UI界面的思路是由当前状态决定界面.前后两个状态就对应两套界面,然后由React来比较 ...
- React Diff算法一览
前言 diff算法一直是React系统最核心的部分,并且由于演化自传统diff,使得比较方式从O(n^3)降级到O(n),然后又改成了链表方式,可谓是变化万千. 传统Diff算法 传统diff算法需要 ...
- React基础(Diff算法,属性和状态)
1.React的背景原理 (1)React Diff算法流程 (2)React虚拟DOM机制 React引入了虚拟DOM(Virtual DOM)的机制:在浏览器端用Javascript实现了一套DO ...
- ReactiveNative学习之Diff算法
React 源码剖析系列 - 不可思议的 react diff深入浅出React(四):虚拟DOM Diff算法解析React diff 算法总结链接引用的文章React出于性能的考虑,为了避免频繁操 ...
- React 源码剖析系列 - 不可思议的 react diff
简单点的重复利用已有的dom和其他REACT性能快的原理. key的作用和虚拟节点 目前,前端领域中 React 势头正盛,使用者众多却少有能够深入剖析内部实现机制和原理. 本系列文章希望通过剖析 ...
- 直接操作DOM一定比虚拟DOM操作耗时,diff算法,key值,虚拟 DOM的定义
直接操作DOM一定比虚拟DOM操作耗时吗? 或者一次直接DOM操作一定比一次虚拟DOM操作耗时吗? 1)虚拟DOM的本质就是一个JS对象,虚拟DOM减少了真实DOM的操作,当修改数据的时候,就是修改虚 ...
- diff算法深入一下?
文章转自豆皮范儿-diff算法深入一下 一.前言 有同学问:能否详细说一下 diff 算法. 简单说:diff 算法是一种优化手段,将前后两个模块进行差异化比较,修补(更新)差异的过程叫做 patch ...
随机推荐
- linkin大话java
青春不灭,理想犹存,linkin--勿忘初心! 不知不觉已经和java并肩作战将近了2年,在这2年之中模模糊糊研究了java2ee领域的好多东西,但是都没有做系统的整理.以前写的笔记也是零零散散不成一 ...
- Node-debug方法
本文使用配置node-inspector配合chorme完成debug(编辑器使用SublimeText3). 1.用命令行进入安装node的目录,使用npm install -g node-insp ...
- Event Sourcing pattern
Event Sourcing pattern Instead of storing just the current state of the data in a domain, use an app ...
- 细数Python Flask微信公众号开发中遇到的那些坑
最近两三个月的时间,断断续续边学边做完成了一个微信公众号页面的开发工作.这是一个快递系统,主要功能有用户管理.寄收件地址管理.用户下单,订单管理,订单查询及一些宣传页面等.本文主要细数下开发过程中遇到 ...
- mybatis-generator 根据表生成对应文件
1 创建maven工程 2.编辑.pom文件 <?xml version="1.0" encoding="UTF-8"?> <project ...
- 常系数齐次线性递推 & 拉格朗日插值
常系数齐次线性递推 具体记在笔记本上了,以后可能补照片,这里稍微写一下,主要贴代码. 概述 形式: \[ h_n = a_1 h_{n-1}+a_2h_{n-2}+...+a_kh_{n-k} \] ...
- BZOJ 4195: [Noi2015]程序自动分析 [并查集 离散化 | 种类并查集WA]
题意: 给出若干相等和不等关系,判断是否可行 woc NOI考这么傻逼的题飞快打了一个种类并查集交上了然后爆零... 发现相等和不等看错了异或一下再叫woc90分 然后发现md$a \neq b, a ...
- BZOJ 1982: [Spoj 2021]Moving Pebbles [博弈论 对称]
给你N堆Stone,两个人玩游戏. 每次任选一堆,首先拿掉至少一个石头,然后移动任意个石子到任意堆中. 谁不能移动了,谁就输了... 以前在poj做过已经忘记了... 构造对称,选最多的一堆往其他堆分 ...
- jQuery源码研究——怎么看源码
废话 这几天有想看源码的想法,于是就开始了源码的研究,经过几天的摸索发现看源码还是有点技巧在里面的,想着把这些东东写下来作为一个小总结. 在一个多月前我对Vue源码进行了一次研究,那时看源码的方式基本 ...
- Linux系统Go开发环境搭建
Go 语言是由谷歌的科学家开发的,并开源的新语言,被誉为"21世纪的C语言",它的主要目标是将静态语言的安全性和高效性与动态语言的易开发性进行有机结合,达到完美平衡,从而使编程变得 ...