浏览器渲染原理

一、渲染时间点。

        当浏览器的网络线程收到html文档后,会产生一个渲染任务,并将其传递给渲染主线程的消息队列。在事件循环机制的作用下,渲染线程取出消息队列中的渲染任务,开启渲染流程Renderer(线程是Theread)。

二、渲染流水线。

         

三、解析HTML——Parse HTML

        将HTML解析为DOM树和CSSOM树。

(一)HTML标签解析生成DOM节点,构建DOM树。

(二)CSS被解析为样式表,构建CSSOM树。          

(三)问题 

        HTML 解析过程中遇到 CSS 代码怎么办?

为了提⾼解析效率,浏览器会启动⼀个预解析器率先下载和解析 CSS 

        HTML 解析过程中遇到 JS 代码怎么办?

渲染主线程遇到 JS 时必须暂停⼀切⾏为,等待下载执⾏完后才能继续 预解析线程可以分担⼀点下载 JS 的任务 

三、计算样式——Recalculate Style

        根据构建的DOM树和CSSOM树计算样式,构建渲染树

四、布局——Layout

        在渲染树上运行布局以计算每个节点的几何体,确定呈现树中所有节点的宽度、高度和位置,以及确定页面上每个对象的大小和位置,构建Layout树。

       DOM树和Layout树不一定是一 一对应的。原因:

        1.可能会包含display:none

        2.可能会存在::before和::after伪元素。

        3.存在匿名盒

 

 

五、分层——Layer

六、绘制 - Paint

        这⾥的绘制,是为每⼀层⽣成如何绘制的指令

        渲染主线程的⼯作到此为⽌,剩余步骤交给其他线程完成 

七、分块——Tiling

        分块会将每⼀层分为多个⼩的区域 

        分块的⼯作是交给多个线程同时进⾏的 

八、光栅化 - Raster

        光栅化是将每个块变成位图,优先处理靠近视⼝的

        此过程会⽤到 GPU 加速 

九、画 - Draw 

         合成线程计算出每个位图在屏幕上的位置,交给 GPU 进⾏最终呈现

 


完整过程

十、常见问题。

1.什么是 reflow (回流)?

        当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性(其他元素的几何属性和位置也会因此受到影响),然后再将计算的结果绘制出来。这个过程就是回流(也叫重排)。【重新排列布局,即打碎重组】

        reflow 的本质就是重新计算 layout 树。当进行了会影响布局树的操作后,需要重新计算布局树,会引发 layout。为了避免连续的多次操作导致布局树反复计算,浏览器会合并这些操作,当 JS 代码全部完成后再进行统一计算。所以,改动属性造成的 reflow 是异步完成的。也同样因为如此,当 JS 获取布局属性时,就可能造成无法获取到最新的布局信息。浏览器在反复权衡下,最终决定获取属性立即 reflow。

 

2.什么是 repaint(重绘) ? 

        当我们对 DOM 的修改导致了样式的变化、却并未影响其几何属性(比如修改了颜色或背景色)时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式。这个过程叫做重绘。

        repaint 的本质就是重新根据分层信息计算了绘制指令。当改动了可见样式后,就需要重新计算,会引发 repaint。由于元素的布局信息也属于可见样式,

        所以 reflow 一定会引起 repaint。

3.为什么 transform 效率⾼?

        

        因为 transform 既不会影响布局也不会影响绘制指令,它影响的只是渲染流程的最后一个「draw」阶段。由于 draw 阶段在合成线程中,所以 transform 的变化几乎不会影响渲染主线程。反之,渲染主线程无论如何忙碌,也不会影响 transform 的变化。