深入理解React虚拟DOM
一、什么是虚拟DOM
虚拟DOM可以看做一棵模拟了DOM树的JavaScript对象树。比如:
var element = {
element: 'ul',
props: {
id:"ulist"
},
children: [
{ element: 'li', props: { id:"first" }, children: ['这是第一个List元素'] },
{ element: 'li', props: { id:"second" }, children: ['这是第二个List元素'] }
]
}
二、为什么使用虚拟DOM
在传统的 Web 应用中,我们往往会把数据的变化实时地更新到用户界面中,于是每次数据的微小变动都会引起 DOM 树的重新渲染。
虚拟DOM的目的是将所有操作累加起来,统计计算出所有的变化后,统一更新一次DOM。

三、虚拟DOM的原理
当Node节点的更新,虚拟DOM会比较两棵DOM树的区别,保证最小化的DOM操作,使得执行效率得到保证。
计算两棵树的常规算法是O(n^3)级别,所以需要优化深度遍历的算法。React diff算法的时间复杂度为O(n)。
React diff 算法

React 分别对 tree diff、component diff 以及 element diff 进行算法优化。
1、tree diff

DOM 节点跨层级的移动操作少到可以忽略不计,针对这一现象,
React 通过 updateDepth 对 Virtual DOM 树进行层级控制,
只会对相同颜色方框内的 DOM 节点进行比较,即同一个父节点下的所有子节点。
当发现节点已经不存在,则该节点及其子节点会被完全删除掉,不会用于进一步的比较。
这样只需要对树进行一次遍历,便能完成整个 DOM 树的比较。
2、component diff
如果是同一类型的组件,按照原策略继续比较 virtual DOM tree。
如果不是,则将该组件判断为 dirty component,从而替换整个组件下的所有子节点。
对于同一类型的组件,有可能其 Virtual DOM 没有任何变化,如果能够确切的知道这点那可以节省大量的 diff 运算时间,因此 React 允许用户通过 shouldComponentUpdate() 来判断该组件是否需要进行 diff。

当 component D 改变为 component G 时,即使这两个 component 结构相似,
一旦 React 判断 D 和 G 是不同类型的组件,就不会比较二者的结构,
而是直接删除 component D,重新创建 component G 以及其子节点。
3、element diff
节点处于同一层级时,React diff 提供了三种节点操作,分别为:INSERT_MARKUP(插入)、MOVE_EXISTING(移动)和 REMOVE_NODE(删除)。

新老集合所包含的节点,如下图所示,新老集合进行 diff 差异化对比,
通过 key 发现新老集合中的节点都是相同的节点,因此无需进行节点删除和创建,
只需要将老集合中节点的位置进行移动,更新为新集合中节点的位置,
此时 React 给出的 diff 结果为:B、D 不做任何操作,A、C 进行移动操作,即可。
总结
React 通过制定大胆的 diff 策略,将 O(n3) 复杂度的问题转换成 O(n) 复杂度的问题;
React 通过分层求异的策略,对 tree diff 进行算法优化;
React 通过相同类生成相似树形结构,不同类生成不同树形结构的策略,对 component diff 进行算法优化;
React 通过设置唯一 key的策略,对 element diff 进行算法优化;
深入理解React虚拟DOM的更多相关文章
- React虚拟DOM浅析
在Web开发中,需要将数据的变化实时反映到UI上,这时就需要对DOM进行操作,但是复杂或频繁的DOM操作通常是性能瓶颈产生的原因,为此,React引入了虚拟DOM(Virtual DOM)的机制. 什 ...
- React虚拟DOM具体实现——利用节点json描述还原dom结构
前两天,帮朋友解决一个问题: ajax请求得到的数据,是一个对象数组,每个对象中,具有三个属性,parentId,id,name,然后根据这个数据生成对应的结构. 刚好最近在看React,并且了解到其 ...
- react虚拟dom diff算法
react虚拟dom:依据diff算法 前端:更新状态.更新视图:所以前端页面的性能问题主要是由Dom操作引起的,解放Dom操作复杂性 刻不容缓 因为:Dom渲染慢,而JS解析编译相对非常非常非常快! ...
- React 虚拟 DOM 的差异检测机制
React 使用虚拟 DOM 将计算好之后的更新发送到真实的 DOM 树上,减少了频繁操作真实 DOM 的时间消耗,但将成本转移到了 JavaScript 中,因为要计算新旧 DOM 树的差异嘛.所以 ...
- 关于react虚拟DOM的研究
1.传统的前端是这样的,我在学校也都是这样做的,html(jsp)主要负责提供所有的DOM节点,而javascript负责动态效果,比如按钮点击,图片轮播等,这样的话javascript如何组织结构是 ...
- react系列一,react虚拟dom如何转成真实的dom
react,想必作为前端开发一定不陌生,组件化以及虚拟dom使得react成为最受欢迎额前端框架之一.我们知道react是基于虚拟dom的,但是什么是虚拟dom呢,其实就是一组js对象,那么我们今天就 ...
- 浅谈React虚拟DOM
为什么要使用虚拟DOM 因为浏览器的DOM渲染是非常消耗性能的,很低效,我们使用虚拟DOM是为了提高DOM的渲染性能: 什么是虚拟DOM 虚拟DOM就是把真实的DOM树通过createElement转 ...
- React/虚拟DOM
在说虚拟DOM之前,先来一个引子,从输入url到展现出整个页面都有哪些过程? 1.输入网址 2.DNS解析 3.建立tcp连接 4.客户端发送HTPP请求 5.服务器处理请求 6.服务器响应请求 7. ...
- REACT——虚拟DOM
深入了解虚拟DOM 实际顺序 jsx->createElemnt ->虚拟DOM(JS 对象)->真实DOM 虚拟DOM中的Diff算法 :当react查找差异的时候,就会采用dif ...
随机推荐
- ubuntu命令错误集
1.在ubuntu命令行使用rz从windows传输文件时出现乱码 解决方法:使用 rz -e 选项进行传输,一般小文件传输不用加 -e 选项,大文件传输需要.
- MySQL常用配置和性能压力测试:MySQL系列之十五
一.MySQL常用配置 以下所有配置参数以32G内存的服务器为基 1.打开独立的表空间 innodb_file_per_table = 1 2.MySQL服务所允许的同时会话数的上限,默认为151,经 ...
- 手写的select 下拉菜单
我们在进行表单设计时,可能要用到select下拉选项控件,遗憾的是,IE浏览器默认的select控件外观非常丑陋,而且不能用样式来控制,不能在选项中添加图片等信息.今天我将通过实例来讲解如何用CSS和 ...
- 008-数据类型(Dictionary)
数据类型(Dictionary) 一.定义 字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值 key=>value 对用冒号:分割,每个键值对之间用逗号,分割,整个字典包括在花括 ...
- springBoot实现socketio
https://github.com/mrniko/netty-socketio-demo https://github.com/mrniko/netty-socketio
- 013 Roman to Integer 罗马数字转整数
给定一个罗马数字,将其转换成整数. 返回的结果要求在 1 到 3999 的范围内. 详见:https://leetcode.com/problems/roman-to-integer/descript ...
- HttpResponseCache的使用缓存cache
为什么要用cache? 我们可以通过传递类似上次更新时间这样的参数来制定查询某些数据.同样,在下载图片的时候,server那边最好能够减少图片的大小,而不是让我们下载完整大小的图片. 之前我们在软件开 ...
- mac-httpd
mac 的httpd mac 自带了apache2, 但是不推荐使用, 因为它的目录在/Library/WebServer/Documents/下 使用brew install apache-http ...
- 如何配置阿里Maven镜像
1.下载maven的zip解压,官方下载地址为:http://maven.apache.org/download.cgi 选择需要下载maven的版本就好了 2.到下载的maven路径下,conf/s ...
- Department Highest Salary
The Employee table holds all employees. Every employee has an Id, a salary, and there is also a colu ...