一、什么是虚拟DOM?
使用javascript模拟了DOM结构的树形结构(对象表示),这个树结构包含整个DOM结构的信息
使用虚拟DOM有什么好处?
操作数据要大大的减少性能损耗,提高渲染效率
越多的真实dom操作,越损耗性能
2.虚拟DOM为什么会提高性能?
虚拟DOM提高性能,不是说不操作DOM,而是减少操作DOM的次数,减少回流和重绘
虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能
1)用 JavaScript 对象结构表示 DOM 树的结构;
2)然后用这个树构建一个真正的 DOM 树,插到文档当中
3)当状态变更的时候,重新构造一棵新的对象树
4)然后用新的树和旧的树进行比较,记录两棵树差异
5)所构建的真正的 DOM 树上,视图就更新了
虚拟dom的实现:
let element={
tagName:'div',//节点标签名
props:{//dom的属性,用一个对象存储键值对
id:'list'
},
children:[//该节点的子节点
{tagName:'li',props:{class:'item'},children:['aa']},
{tagName:'li',props:{class:'item'},children:['bb']},
{tagName:'li',props:{class:'item'},children:['cc']}
]
}
对应的html写法是:
<div id='list'>
<li class='item'>aa</li>
<li class='item'>aa</li>
<li class='item'>aa</li>
</div>
二、实现虚拟DOM
使用diff算法比较新旧虚拟DOM----即比较两个js对象不怎么耗性能,而比较两个真实的DOM比较耗性能,从而虚拟DOM极大的提升了性能!
let myp = document.getElementById("myp")
console.time("temp")
for(var i=0;i<10000;i++){
let num = myp.innerHTML*1
myp.innerHTML = ++num
}
console.timeEnd("temp")
let myp = document.getElementById("myp")
let num = 1
console.time("temp")
for(var i=0;i<10000;i++){
num++
}
myp.innerHTML = num
console.timeEnd("temp")
diff算法:
diff算法指的就是两个虚拟DOM作比对,在diff算法中有个概念就是同级比对,首先比对顶层虚拟DOM节点是否一致,如果一样就接着比对下一层,如果不一样,就停止向下比对,将原始页面中这个DOM及 下面的DOM全部删除掉,重新生成新的虚拟DOM,然后替换掉原始页面的DOM
左图:简单粗暴的做法是:卸载C,装载F,卸载D,装载C,卸载E,装载D,装载E。虽然程序运行不会有错,但效率太低
右图:增加上key后,React就能根据key,直接找到具体的位置进行操作,效率比较高
列表中key的作用:
1)key是React用于跟踪哪些元素是增加、删除、修改的辅助标记,需要保证在同级元素中key的唯一性
2) React Diff 算法借助元素的 Key 值判断元素是新增、删除、修改,从而减少不必要的元素重渲染。
3)React 还需要借助 Key 值来判断元素与本地状态的关联关系