深入理解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 ...
随机推荐
- 1、gitlab的理论知识
2.1 svn与git对比 . svn git 分布式 不是 是 在线阅读 不支持 不仅支持,而且可以在线编辑 存储方式 按文件 按元数据 完整性 一般 优 离线工作 日志都没法看 完全没问题 分支 ...
- putty提示Network error:Software caused connection abort
在 sshd host 的 /etc/ssh/sshd_config 设定: TCPKeepAlive yes,和将LoginGraceTime的值设为0,默认为2m,然后使用service sshd ...
- android SDK manager 无法获取更新版本的解决办法
http://mirrors.neusoft.edu.cn/eclipse/releases/luna/打开这个网址就可以看到adt的详细信息: http://developer.android.c ...
- jquery——解决鼠标移入移出导致盒子不停移动的bug
使用mouseover().mouseout()时会出现这样一种情况,鼠标快速多次移入移出后这个盒子会在鼠标不动后继续运动 代码如下: <!DOCTYPE html> <html l ...
- Is It A Tree?(hdu1325)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1325 Is It A Tree? Time Limit: 2000/1000 MS (Java/Oth ...
- UnityError 切换场景灯光变黑问题解决
编辑器在当前场景时,它的灯光是已经渲染好了,但重新加载的时候灯光没有进行渲染 解决方法如下: Window>>lighting>>Scene面板>>右下角build ...
- (转)用户管理 之 Linux 用户(user)和用户组(group)管理概述
用户管理 之 Linux 用户(user)和用户组(group)管理概述 原文:http://www.cnblogs.com/licheng/p/6103992.html 一.理解Linux的单用户 ...
- Asp.NET MVC+WebAPI跨域调用
使用jQuery调用WebApi有时会遇到跨域的问题,今天介绍一种可以简单解决跨域问题的方法. 当我们跨域请求WebAPI的时候会提示以下信息: XMLHttpRequest cannot load ...
- onclientclick与onclick的问题.
<script language="javascript" type="text/javascript"> document.getElementB ...
- python.h没有那个文件或目录解决方法
我用的是Deepin Linux,这应该是linux平台的问题,别的linux os也是执行安装,命令不同而已,windows和Mac不太清楚. 如果你使用的是python2.x,那么使用下面的语句: ...