前言
虚拟DOM作为现在最流行的框架Vue和React的核心机制之一,为这两个框架带来了极大的性能提升。掌握这个概念,能使我们对框架的理解更近一步。
传统DOM解析流程
1.分析html元素生成DOM树
2.分析css元素生成CSSOM树
3.将CSSOM树与DOM树结合成渲染树
4.浏览器根据渲染树确定每个节点生成的位置然后进行布局
5.浏览器绘制页面到屏幕上
JS操作DOM流程
1.JS操作DOM,DOM发生变化
2.将新DOM与旧DOM进行比对
3.根据新DOM进行绘制
当JS操作一个dom元素时将会重新触发一遍上面的解析流程,每次一个DOM变化就会重新绘制一次,如果有多个DOM发生变化就会绘制多次,如果一次需要绘制的DOM元素过多将会造成页面卡顿,影响用户体验。
虚拟DOM绘制流程
1.生成state数据
2.生成jsx模板
3.将数据和模板结合成虚拟DOM(用一个JS对象描述真实DOM)
比如将
<div id="1"><span>hello</span></div>
转换为虚拟DOM
生成的对象为['div',{id:'1'},['span',{},'hello']]
对象结构:['nodeName',{attribute},childNode]
第一部分:父节点名称。第二部分:父节点属性值。第三部分:子节点,如果为节点再嵌套数组,如果为文本,则为字符串。
4.根据虚拟DOM生成DOM然后绘制
虚拟DOM操作流程
1.state发生变化,其中几个节点需要更新。
2.生成新的虚拟DOM,将新的虚拟DOM与旧的虚拟DOM进行比对。
3.生成新DOM,然后绘制
jsx模板
class App extends React.Component{
render(){
return (
<div className="myDiv">
<span>span1</span>
<span>span2</span>
</div>
)
}
}
复制代码
上面的代码是react中特别熟悉的组件创建过程,生成了一个div和两个span
var div=React.createElement('div',{className:'myDiv'},child1,child2) //也可写成数组形式[child1,child2]
let child1=React.createElement('span',null,'span1')
let child2=React.createElement('span',null,'span2')
ReactDom.render(div,document.getElementById('app')
复制代码
我们平时写的上面那种创建组件的方法其实是React.createElement的语法糖,最后都会转化为createElement这种方法创建
性能提升原因
1.将以前的DOM比对变成虚拟DOM比对,提升了性能。
2.将以前的多少个节点更新就渲染多少次,变成了只渲染一次,极大的提升了性能
需要更详细的了解DOM解析流程,以及为什么操作DOM损耗性能,可以查看我的上一篇博客:浏览器渲染机制