1.概念:
<1>原生DOM:浏览器从服务器端读取html页面,浏览器将html解析成一棵元素嵌套关系的DOM树,用对象来表示页面上的元素,并提供操作DOM对象的api。
<2>虚拟DOM:保存了一棵DOM树被渲染之前所包含的所有信息,而这些信息可以通过对象的形式一直保存在内存中,并通过JavaScript的操作进行维护。
2.对比:
<1>我们先来看看浏览器渲染引擎工作流程:创建DOM树-->创建StyleRules-->创建Render树-->布局layout-->绘制painting,
第一步:用HTML分析器,分析HTML元素,构建一棵DOM树(标记化和树构建)
第二步:用css分析器,分析css文件和元素上的inline样式,生成页面的样式表
第三步:将DOM树和样式表,关联起来,构建一棵Render树(Attachment),每个DOM节点都有attach方法,接受样式信息,返回一个render对象。这些render对象最终会被构建一棵Render树
第四步:有了Render树,浏览器开始布局,为每个Render树上的节点确定一个在显示屏上出现的精确坐标
第五步:render树和节点显示坐标都有了,就调用每个节点paint方法,把它们绘制出来
如图:
webkit渲染引擎工作流程注意:
1>构建DOM树是一个渐进过程,为达到更好用户体验,渲染引擎会尽快将内容显示在屏幕上。
2>CSS解析是从右往左逆向解析的,嵌套标签越慢,解析越慢
<2>由上面分析可以看到传统的开发模式,原生js或者JQ操作DOM时候,浏览器会从构建DOM树开始从头到尾执行一遍流程。比如,在一次操作中,需要更新10个DOM节点,浏览器收到第一个请求后并不知道还有9次更新操作,因此会马上执行流程,最终执行10次。例如,第一次计算完,紧接着下一个DOM更新请求,这个节点的坐标值就变了,前一次计算为无用功。计算DOM节点坐标值等都是白白浪费的性能。即使计算机硬件一直在迭代更新,操作DOM的代价仍旧是昂贵的,频繁操作还是会出现页面卡顿,影响用户体验。
<4>原生dom操作vs通过框架封装的虚拟dom操作,这是一个性能vs可维护性的取舍,框架的意义在于为你掩盖底层的DOM操作,让给你用更声明式的方式来描述你的目的,从而让你的代码更容易维护。注意:没有任何框架可以比手动的优化DOM操作更快!因为dom操作层需要应对任何上层API可能产生的操作,它的实现必须是普适的。