加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 服务器 > 系统 > 正文

从 Chromium 源码来窥视浏览器的渲染

发布时间:2022-02-16 20:48:42 所属栏目:系统 来源:互联网
导读:传统面试题我们在各种面试题以及面试中都大概率看到过这个题目,浏览器在拿到数据后到最终呈现在面上经历了哪些过程? 这绝不是浏览器刷的一下就把页面给渲染出来了,中间经历了非常复杂的流程,我们一点点由浅入深来窥探浏览器渲染的整个过程。 首先我们可
          传统面试题我们在各种面试题以及面试中都大概率看到过这个题目,浏览器在拿到数据后到最终呈现在⻚面上经历了哪些过程?
 
          这绝不是浏览器“刷”的一下就把页面给渲染出来了,中间经历了非常复杂的流程,我们一点点由浅入深来窥探浏览器渲染的整个过程。
  
         首先我们可以看下比较传统的回答方式,我们不去考虑 js 文件对⻚面解析造成的影响,在最简单的⻚面中,浏览器仅仅拿到 HTML 文件 和 CSS 文件 ,便可以渲染出一个⻚面。在浏览器引擎中,会分别使用 HTML 解析器以及 CSS 解析器将接收到的二进制流数据转化为浏览器能够识别的 DOM 树和 CSS 规则树,随后将两者进行结合生成 Render(Layout Object)树,浏览器在拿到 (Layout Object)树后再经历分层,绘制等,我们才能在屏幕上看到最终的⻚面。
 
Chrome 多进程机制
我们从另一个⻆度,Chrome 多进程的⻆度也可以进行探索,大家都知道 Chrome 采用的是一个 多进程架构。 详情参考现代浏览器架构。例如浏览器进程,负责浏览器主框架,提供一些通用的能力,GPU 进程则负责将渲染进程上传到 GPU 中的位图纹理进行处理随后呈现到屏幕上等。而浏览器渲染关联的渲染进程,当然是我们最关心的,它究竟是由哪些线程组成的,以及各个线程之间是如何通信合作来完成渲染的呢?
 
渲染进程组成
渲染进程主要由如下几个线程组成:
 
GUI 渲染主线程: 解析 html,css,构建 DOM 树和 LayoutObject。
JS 引擎线程: 执行,解析 JS 代码。
合成器线程:进行分块操作,同时也负责接受用戶的滚动,输入,分发回调事件等。
栅格化线程:将绘制命令转换为位图或者 GPU 能识别的纹理。
我们可以通过 chrome://tracing 记录在一个⻚面渲染过程中,各个线程之间的通信:
  
如上所示:CRFRenderMain 表示的是渲染主线程,主要进行一些计算的操作。Compositior 表示合成器线程,主要进行合成操作。Compositior Tile Workder 表示栅格化线程,现代浏览器往往有 2-4 个栅格化线程,浏览器会根据资源情况合理分配栅格化线程资源。
  
整体的渲染流程如下:
 
合成器线程接收到Vsync信号,开始新的一帧绘制。
我们知道合成器线程可以处理用戶的输入,如果一些输入事件中存在一些回调事件,例如滚动的回调事件,那么合成器线程在上一帧收集完这些事件之后,会在当前帧将这些事件交给渲染主线程进行处理。
执行 requestAnimationFrame 相关的动画操作。
解析 HTML 数据,形成 DOM 树,这是 HTML 解析器(HTMLParser)的主要工作。浏览器接收到的html 数据也是字节流,因此要将其转换成浏览器能认识及转换的 token 标签,在这之中主要经历了如下步骤:
4.1. 解码:浏览器将接收的字节流(Bytes)基于编码方式解析为字符(characters)。
 
4.2. 分词:通过分词器(词法分析)将字符转换为 Token,分为 Tag Token 和文本 Token。详情可参考 vue 源码中的模板解析过程,大部分还是相同的。
 
4.3. 将 tokens 标签转换为 nodes 节点,随后将 nodes 节点添加至 DOM 树上,这两步是并行执行的,在这期间,主要是通过栈的数据结构来进行维护(类似于常⻅面试题-括号匹配),当遇到开标签时,将对应 node 推入栈中,并且添加至 DOM 树上,当遇到文本标签时,就直接将文本 node 添加至 DOM 树上即可,当遇到闭合标签时,就进行出栈操作。另外 html 是一⻔友好语言,对于开闭标签不匹配的场景,或者是自定义的标签,都有自己的处理方式,在这里就不做具体展开。
 
 

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读