每天一个前端面试题之 虚拟DOM
一、浏览器渲染引擎的工作流程
在了解虚拟DOM之前,先来讲一讲浏览器渲染引擎的工作流程。
下图是webkit渲染引擎的工作流程。
从上图中分析,浏览器渲染引擎的工作流程分为5步:
1.创建DOM树: 浏览器会将HTML解析成一个DOM树,DOM 树的构建过程是一个深度遍历过程:当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点。
2.创建StyleRules: 将CSS解析成 CSS Rule Tree,生成页面的样式表 。
3. 创建Render树: 将DOM树和CSSOM关联起来,构造 Rendering Tree。
4. 布局Layout: 有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系。下一步操作称之为layout,顾名思义就是计算出每个节点在屏幕中的位置。
5. 绘制Painting 遍历render树,并使用UI后端层绘制每个节点。
上述过程是逐步完成的,但是为了更高的用户体验,尽早的将页面呈现在用户面前,浏览器并不会等所有的html都解析完了才进行下面的流程,而是解析完一部分内容就显示一部分内容。 创建DOM树、CSSOM树和Render树的过程在实际进行的时候又不是完全独立,而是会有交叉。会造成一边加载,一遍解析,一遍渲染的工作现象。
二、为什么会有虚拟DOM?
虚拟DOM是为了提高浏览器的性能而被设计出来的。当页面发生变化,浏览器一遍又一遍的渲染DOM所消耗的性能是非常大的,还会出现页面卡死的现象。
而虚拟DOM会很好的解决这个问题。若一次操作中有10次更新DOM的动作,虚拟DOM不会立即操作DOM,而是将这10次更新的diff内容保存到本地一个JS对象(虚拟DOM)中,最终将这个JS对象(虚拟DOM)一次性attch到DOM树上,再进行后续操作,避免大量无谓的计算量。所以,用JS对象模拟DOM节点的好处是,页面的更新可以先全部反映在JS对象(虚拟DOM)上,操作内存中的JS对象(虚拟DOM)的速度显然要更快,等更新完成后,再将最终的JS对象映射成真实的DOM,交由浏览器去绘制。
虚拟dom 的真正意义是为了实现跨平台,服务端渲染,以及提供一个性能还算不错 Dom 更新策略
三、虚拟DOM的基本流程
1.构建虚拟DOM树。 用JS对象模拟DOM节点构建虚拟DOM树,在对象中记录节点的类型属性和子节点。
function Element (tagName, props, children) {
this.tagName = tagName
this.props = props
this.children = children
}
module.exports = function (tagName, props, children)