虚拟DOM
概念
虚拟DOM其实就是一个JS对象,用它来描述真实的DOM
如何重新渲染页面
数据发生变化,如:
<div id='root'>
<span>hello world</span>
</div>
变为:
<div id='root'>
<span>hello Amethsyt~</span>
</div>
步骤:
- state数据
- JSX模板
- 数据+模板,生成虚拟DOM(损耗性能)
['div',{id:'root'},['span',{},'hello world']]
- 用虚拟DOM的结构生成真实的DOM,显示在页面上
<div id='root'><span>hello world</span></div>
- state发生变化
- 数据+模板 生成新的虚拟DOM (极大地提升了性能)
['div',{id:'root'},['span',{},'hello Amethsyt~']]
- 比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span的内容(极大地提升性能)
直接操作DOM会比较损耗性能,而操作JS对象对性能的消耗是极小的,因此性能得到极大地提升
react底层会把JSX语法通过createElement方法将一个js对象转换成虚拟DOM,再渲染成真实的DOM
JSX——>createElement——>虚拟DOM(JS对象)——>真实的DOM
优点
1、性能提升了
2、使得跨端应用得以实现。React Native
用react语法写原生的应用得益于虚拟DOM的存在,在移动端的原生应用里面,是没有DOM概念的,如果没有虚拟DOM,应用就只能运行在浏览器上,有了虚拟DOM之后,我们的代码首先被转换成虚拟DOM(JS对象),JS对象在浏览器、原生的应用里面都可以被识别,虚拟DOM在浏览器上可以转换成真实的DOM,在原生应用里可以生成原生组件,这使得react既可以开发网页应用,也可以开发原生应用。
虚拟DOM中的Diff算法
state发生改变的时候需要生成新的虚拟DOM,此时便需要比对数据,Diff算法就是为了比对新的虚拟DOM和原来的虚拟DOM之间的差异。此外,react将setState设计成一个异步函数,可以把多次setState结合成一次setState,减少比对的速度,提高性能。
Diff算法特点
同层比对,逐层比对,一旦遇到一层不满足条件,将不再进行比对,剩下的直接用新的替换旧的。算法简单,比对速度快。
key值的引入
react在做列表循环的时候在循环里的最外层标签上加一个key属性,结点在原始DOM树上和新的DOM树上key值一致,提高虚拟DOM比对的性能。为了使key值保持稳定,我们一般不使用循环变量index作为key值,而是用item.