前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘

马肤

温馨提示:这篇文章已超过470天没有更新,请注意相关的内容是否还可用!

摘要:本文探讨了浏览器的进阶知识,重点介绍了浏览器的渲染原理。文章指出,随着技术的发展,浏览器已经发生了巨大的变化,其渲染机制也变得更加复杂和高效。文章深入解析了浏览器如何处理HTML、CSS和JavaScript等前端资源,让读者了解浏览器如何将网页呈现给我们。本文帮助读者打破对浏览器的传统认知,进一步探索前端开发的奥秘。

目录

一.浏览器渲染原理

二.渲染时间点

三.渲染流水线

1.解析html(Parse HTML)

1.1解析成DOM树(document object model)

1.2解析成CSSOM树(css object model)

2.样式计算(Recalculate Style)

3.布局(Layout)

4.分层(Layer)

5. 绘制(Paint)

6.分块(Tiling)

7. 光栅化(Raster)

8. 画(Draw)

四.附加面试题

1.什么是 reflow?

2.什么是 repaint?

3.为什么 transform 的效率高?


一.浏览器渲染原理

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第1张

浏览器是如何渲染页面的?

当浏览器的网络线程收到 HTML 文档后,会产生一个渲染任务,并将其传递给渲染主线程的消息队列。

在事件循环机制的作用下,渲染主线程取出消息队列中的渲染任务,开启渲染流程。

整个渲染流程分为多个阶段,分别是: HTML 解析、样式计算、布局、分层、绘制、分块、光栅化、画

每个阶段都有明确的输入输出,上一个阶段的输出会成为下一个阶段的输入。

这样,整个渲染流程就形成了一套组织严密的生产流水线。

二.渲染时间点

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第2张

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

三.渲染流水线

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第3张

1.解析html(Parse HTML)

首先将html和css分别解析成DOM树和CSSOM树

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第4张

1.1解析成DOM树(document object model)

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第5张

为什么要先解析成树状结构内,因为HTML文档是很多杂乱的字符,为了更清楚它们之间的逻辑,更好地进行后续的渲染步骤,浏览器先选择将它们解析成更加清晰的逻辑结构

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第6张

1.2解析成CSSOM树(css object model)

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第7张

解析过程中遇到 CSS 解析 CSS,遇到 JS 执行 JS。为了提高解析效率,浏览器在开始解析前,会启动一个预解析的线程,率先下载 HTML 中的外部 CSS 文件和 外部的 JS 文件。

如果主线程解析到`link`位置,此时外部的 CSS 文件还没有下载解析好,主线程不会等待,继续解析后续的 HTML。这是因为下载和解析 CSS 的工作是在预解析线程中进行的。这就是 CSS 不会阻塞 HTML 解析的根本原因。

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第8张

如果主线程解析到`script`位置,会停止解析 HTML,转而等待 JS 文件下载好,并将全局代码解析执行完成后,才能继续解析 HTML。这是因为 JS 代码的执行过程可能会修改当前的 DOM 树,所以 DOM 树的生成必须暂停。这就是 JS 会阻塞 HTML 解析的根本原因。

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第9张

第一步完成后,会得到 DOM 树和 CSSOM 树,浏览器的默认样式、内部样式、外部样式、行内样式均会包含在 CSSOM 树中。

2.样式计算(Recalculate Style)

主线程会遍历得到的 DOM 树,依次为树中的每个节点计算出它最终的样式,称之为 Computed Style。

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第10张

在这一过程中,很多预设值会变成绝对值,比如`red`会变成`rgb(255,0,0)`;相对单位会变成绝对单位,比如`em`会变成`px`

这一步完成后,会得到一棵带有样式的 DOM 树。

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第11张

3.布局(Layout)

接下来是布局,布局完成后会得到布局树。

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第12张

布局阶段会依次遍历 DOM 树的每一个节点,计算每个节点的几何信息。例如节点的宽高、相对包含块的位置。

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第13张

大部分时候,DOM 树和布局树并非一一对应。

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第14张

比如`display:none`的节点没有几何信息,因此不会生成到布局树;又比如使用了伪元素选择器,虽然 DOM 树中不存在这些伪元素节点,但它们拥有几何信息,所以会生成到布局树中。还有匿名行盒、匿名块盒等等都会导致 DOM 树和布局树无法一一对应。

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第15张

4.分层(Layer)

下一步是分层

主线程会使用一套复杂的策略对整个布局树中进行分层。

分层的好处在于,将来某一个层改变后,仅会对该层进行后续处理,从而提升效率。

滚动条、堆叠上下文、transform、opacity 等样式都会或多或少的影响分层结果,也可以通过`will-change`属性更大程度的影响分层结果。
前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第16张

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第17张

5. 绘制(Paint)

再下一步是绘制

主线程会为每个层单独产生绘制指令集,用于描述这一层的内容该如何画出来。
前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第18张

渲染主线程的工作到这里就结束了,剩下的工作交给其他线程来完成

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第19张

6.分块(Tiling)

完成绘制后,主线程将每个图层的绘制信息提交给合成线程,剩余工作将由合成线程完成。

合成线程首先对每个图层进行分块,将其划分为更多的小区域。

它会从线程池中拿取多个线程来完成分块工作。
前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第20张

这是csdn网页的分块图

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第21张

分块工程是交给多个线程同时进行的

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第22张

7. 光栅化(Raster)

分块完成后,进入光栅化阶段。

优先处理靠近视口的块

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第23张

合成线程会将块信息交给 GPU 进程,以极高的速度完成光栅化。

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第24张

GPU 进程会开启多个线程来完成光栅化,并且优先处理靠近视口区域的块。

光栅化的结果,就是一块一块的位图

8. 画(Draw)

最后一个阶段就是画了

合成线程拿到每个层、每个块的位图后,生成一个个「指引(quad)」信息。

指引会标识出每个位图应该画到屏幕的哪个位置,以及会考虑到旋转、缩放等变形。

变形发生在合成线程,与渲染主线程无关,这就是`transform`效率高的本质原因。

合成线程会把 quad 提交给 GPU 进程,由 GPU 进程产生系统调用,提交给 GPU 硬件,完成最终的屏幕成像。

前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理),前端进阶探索,浏览器秘术——渲染原理揭秘 第25张

四.附加面试题

1.什么是 reflow?

reflow 的本质就是重新计算 layout 树。

当进行了会影响布局树的操作后,需要重新计算布局树,会引发 layout。

为了避免连续的多次操作导致布局树反复计算,浏览器会合并这些操作,当 JS 代码全部完成后再进行统一计算。所以,改动属性造成的 reflow 是异步完成的。

也同样因为如此,当 JS 获取布局属性时,就可能造成无法获取到最新的布局信息。

浏览器在反复权衡下,最终决定获取属性立即 reflow。

2.什么是 repaint?

repaint 的本质就是重新根据分层信息计算了绘制指令。

当改动了可见样式后,就需要重新计算,会引发 repaint。

由于元素的布局信息也属于可见样式,所以 reflow 一定会引起 repaint。

3.为什么 transform 的效率高?

因为 transform 既不会影响布局也不会影响绘制指令,它影响的只是渲染流程的最后一个「draw」阶段

由于 draw 阶段在合成线程中,所以 transform 的变化几乎不会影响渲染主线程。反之,渲染主线程无论如何忙碌,也不会影响 transform 的变化。


0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码