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 ...
随机推荐
- java常用类--与用户互动
运行java的参数: 主方法:public static void main(String[] args){}:为了让JVM可以自由调用main方法,使用public修饰,JVM通过类来调用main方 ...
- Cannot create an instance of OLE DB provider “OraOLEDB.Oracle” for linked server "xxxxxxx".
在SQL SERVER 2008 R2下用Windows 身份认证的登录名创建了一个访问ORACLE数据库的链接服务器xxxxx,测试成功,木有问题,但是其它登录名使用该链接服务器时,报如下错误: 消 ...
- backupMysql.sh
#!/bin/sh #!/bin/bash function backup() { for i in $* do mysqldump -h$hostip -P$port -u$username -p$ ...
- DOM中对象的获得
DOM的所有对象会在页面打开时,由浏览器页面创建. 浏览器把dom定点对象Document对像的引用交给了window对象. 1.document对象的获得 var doc = window.d ...
- 面向切面编程之手动JDK代理方式
需求描述: 抽取dao层开启和提交事物交由代理类一并执行 分析: 假如UserDao接口中有很多方法,例如addUser().deleteUser().updateUser()等等,需要频繁的和数据库 ...
- 包装类和基本类型区别?(integer和int取值范围一样大)
1.声明方式不同,int不需要new .Integer需要new 2.性质上根本不同点:int是基本数据类型.Integer是引用数据类型,它有自己的属性,方法 3.存储位置和方式不同:int是存储在 ...
- Effective Java 之-----精确的答案与double&float
题目: 假设你口袋里有1$,看到货架上有一排美味的糖果,标价分别为0.10$,0.20$,0.30$...1$,你打算从标价为0.10$的糖果开始买起,每种买一颗,一直到不能支付货架上下一种价格的糖果 ...
- git的学习笔记
1. Git介绍 Git是一个开源的分布式版本控制软件,用以有效.高速的处理从很小到非常大的项目版本管理. Git 最初是由Linus Torvalds设计开发的,用于管理Linux内核开发. Git ...
- CentOS(Linux)下安装dmidecode包
安装代码: yum install dmidecode 安装完成后,查看总体信息: dmidecode 查看服务器类型,测试环境为DELL R610: dmidecode -s system-prod ...
- SEO页面优化以及如何对单页面应用进行SEO优化
一.简介 1.何为SEO? SEO(search engine optimization),翻译为搜索引擎优化,是利用搜索引擎的搜索规则来提高在相关搜索引擎的排名以及访问量的方式. 2.目的 为了获取 ...