上文对浏览器渲染页面的过程只是一笔带过,本文将展开讲述一下浏览器拿到html/css等文件资源后是如何对页面进行渲染的,总体可以分为以下几步:
-
解析HTML,构建DOM树。
-
解析CSS,生成CSSOM树。
-
合并DOM树和CSSOM树,生成render树
-
布局render(Layout/reflow),计算各元素尺寸、位置。
-
绘制render树(paint),绘制页面像素信息。
-
浏览器将各层的信息发送给GPU,GPU将各层合成,显示在屏幕上。
对于流程1,浏览器首先经过tokeniser标记化,通过词法分析将输入的html内容解析成多个标记,然后根据识别后的标记进行dom树的构造,在这个过程中会创建document对象,对以document为根节点的dom树不断进行修改,向其中添加各种元素,最后形成完整的DOM树,同理,CSSOM树的生成也是类似。
在得到DOM数和CSSOM树后,就可以将他们合并成render树,而类似head和样式设置了display:none
的标签则不会插入到渲染树中,如下图。
有了渲染树后,就开始真正的渲染了。浏览器会根据渲染树来进行布局,计算每个节点的几何信息,如元素在屏幕上的确切位置和尺寸,最后将图像绘制出来。在这当中,如果通过js动态修改了DOM或CSS,就涉及到了重排和重绘,在之前的文章已经说了什么原因会导致这两种情况的发生,简单来说就是重新触发流程4就是重排,触发流程5则是重绘。至于为什么要避免大量的重排和重绘操作,已经如何避免,这里就涉及到浏览器的线程问题了,会在后面的文章继续说明。