虚拟Dom是一种很广泛的概念。只要你能用某种数据结构来描述出一个真实Dom,那么他就是虚拟Dom。
虚拟Dom是由React最先提出来的概念。
React是用这种结构来描述Dom
{
"type": "h1",
"key": null,
"ref": null,
"props": {
"children": "Hello"
},
}
只要你能某种将数据结来构描述真实的Dom,那么他就是虚拟Dom。
虚拟Dom就是个概念,不是特指某种数据类型!!!
为什么需要虚拟 DOM
主要是因为他有两个优势
- 比真实Dom性能更好,体积小,速度快。
- 具备强大的抽象渲染能力
浏览器渲染机制
浏览器在渲染UI经过了很多个操作。其中最复杂的就是解析和计算HTML了。我们发起一个get请求去获取一个网页。响应的内容仅仅是个字符串,然后将标签字符串解析出来,并且创建对应的dom对象。然后去解析样式,布局。计算出每个像素点的内容。
这个过程是很消耗性能的。看下面的例子:
document.getElementById('root').innerHTML = `
<div>
<h1>hi</h1>
</div>
`;
上面的代码虽然写起来简单,但是会有性能问题。直接用字符串来赋值,浏览器还是要先解析字符串,然后创建对应的元素节点,然后在进行重排。
const div = document.createElement('div');
const h1 = document.createElement('h1');
h1.innerText = 'hi';
div.append(h1)
document.getElementById('root').append(div)
而上面的例子就不会再去解析,直接重排即可。所以很多时候我们不推荐使用innerHTML。如果有很多元素的时候还需要用document.createDocumentFragment
来减少重排次数,节省性能。
虚拟Dom和真实Dom的差异
再看虚拟Dom和真实Dom。
一个真实dom他有以下属性:
而虚拟Dom只有寥寥几个
{
"type": "h1",
"key": null,
"ref": null,
"props": {
"children": "Hello"
},
}
体积上的优势瞬间就体现出来了。
渲染抽象能力
- 在浏览器环境 虚拟Dom被描述成HTML节点
- 在Native环境 虚拟dom被描述成ReactNative包
- 在Canvas,SVG被描述成ReactArt包
所以虚拟Dom在任何环境都可以工作。