虚拟DOM-Diff算法详解
假如我们想自己实现一个React
,简单底层实现:
1.state数据
2.JSX 模板
3.数据 + 模板 结合,生成真实的DOM,来显示
4.state 发生改变
5.数据 + 模板 结合,生成真实的DOM,替换原始的DOM
缺陷:
第一次生成了一个完整的DOM片段
第二次生成了一个完整的DOM片段
第二次的DOM替换第一次的DOM,非常耗性能(实际上可能只有片段中的一小部分需要改变)
那我们应该如何改良呢?
1.state数据
2.JSX 模板
3.数据 + 模板 结合,生成真实的DOM,来显示
4.state 发生改变
5.数据 + 模板 结合,生成真实的DOM,并不直接替换原始的DOM
6.新的DOM和原始的DOM做对比,找差异
7.找出发生了变化的地方
8.只用新的DOM中变化的地方,来替换掉老的DOM中的对应位置
缺陷:
性能的提升并不明显
React
提出了第三种方案——虚拟DOM
1.state 数据
2.JSX 模板
3.数据 + 模板结合,生成虚拟DOM(虚拟DOM就是一个JS对象,用它来描述真实DOM)
[ 'div', {id: 'abc'}, [ 'span', {}, 'hello world' ] ]
3.用虚拟DOM的结构生成真实的DOM,来显示
hello world
5.state 发生变化
6.数据 + 模板 生成新的虚拟DOM(极大的提升了性能)
[ 'div', {id: 'abc'}, [ 'span', {}, 'bye bye' ] ]
- 比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span中的内容(极大的提升了性能)
8.直接操作DOM,改变span中的内容
React
的JSX解析过程
JSX -> createElement -> 虚拟DOM(JS对象)->真实的DOM例如:
return item
等同于
return React.createElement('div',{},React.createElement('span',{},item));
虚拟DOM带来了什么好处 1.性能提升了
2.它使得跨端应用得以实现(
React Native
),因为虚拟DOM在原生应用和网页中都能够被识别。Diff算法
同层比对,如果一层不同,则直接替换,不会做下一层的比对,这样性能比较好
setState是异步的 是为了提升底层的性能。假设我连续调用三次
setState
,变更三组数据,由于setState
是异步的,React
可以把三次setState
合并成一次,只去做一次虚拟DOM的比对,就可以省去两次虚拟DOM的比对带来的性能的耗费。key值能用index吗? 【虚拟DOM-Diff算法详解】在
react
中,我们能不用index
做key
值就尽量不用index
做key
值,因为这样是不稳定的,我们应该尽量用稳定的不会改变的key
值。推荐阅读
- 画解算法(1.|画解算法:1. 两数之和)
- Guava|Guava RateLimiter与限流算法
- 一个选择排序算法
- SG平滑轨迹算法的原理和实现
- 《算法》-图[有向图]
- LeetCode算法题-11.|LeetCode算法题-11. 盛最多水的容器(Swift)
- 《数据结构与算法之美》——队列
- 算法回顾(SVD在协同过滤推荐系统中的应用)
- Xshell5|Xshell5 远程连接本地虚拟机Ubuntu16
- 简谈迪克斯特拉算法