【精简版】浏览器渲染机制(完整流程概述)(上)

简介: 【精简版】浏览器渲染机制(完整流程概述)(上)

背景


资料:docs.google.com/presentatio…

我们作为工程师,一名开发者,我认为时刻保持好奇心是一件很重要的事情,前端工程师们,不知你们是否好奇过 我们写出的代码究竟是如何变成屏幕上五彩斑斓的像素点的


本文就是来解决上面的这个问题的。


本文目的


但是,浏览器的渲染机制其实是一个很大的研究课题,过去的一个月我做了很多研究,找了很多资料,废了很多心血,越发觉得其中的很多细节可以消耗我很多很多时间,我也仅仅是了解到皮毛,文章中也会有我个人的理解,也可能存在错误,如果有大佬看到,也希望多多指导和批评,我也会积极采纳。


本文的目的是用通俗的语言,为大家介绍浏览器渲染的完整过程,并不会对每一步进行细致深入的讲解,(即让大家读懂是我最大的目标)。所以,阅读本文你可以得到什么呢:


  • 浏览器渲染的大致流程
  • 得到一个和别人喝咖啡的时候的聊天话题
  • 和我变成朋友(这是最关键的一点是吧,嘿嘿)


勘误


流程图 中的主进程 -> 主线程。(画图的时候没注意,抱歉。。。老朽在此认罪)


goal渲染的目标


首先,本文名称是浏览器渲染机制,那我们第一步就是要了解,浏览器渲染的目标是什么?


网络异常,图片无法展示
|


看上图,我们首先要了解一个content的概念,content指的是网页中这个区域,上面的标签栏,地址栏都不属于content。


网络异常,图片无法展示
|


所以,我们知道了整个渲染过程我们的输入是前端的代码,输出是content区域的像素点。好,这样我们渲染的目标就很明确了,即:把前端写出的代码转换成网页content区域的像素点!


下面,我们开始,为中间这个RENDER管道,一点一点的加上内容,让它丰满起来。


Blink(浏览器渲染机制之主线程做了啥)


DOM


往后的阅读,希望大家跟着我的思路,跟着思考,我会解释的很通俗,不要中途离开,拉钩哈。(拉完勾之后,说好的阅读完就要阅读完,一句话,一个字没有读,都不是阅读完~ )


DOM阶段介绍


首先,大家去想,我们的输入是code,但是中间过程的处理是,需要一个数据结构的,

你这个输入的code说白了只是冰冷的字符串,我们第一步要做的肯定是把它转换成有温度的数据结构。


<div>
  <p> hello </p>
  <p> world </p>
</div>

所以,这个数据结构应该是什么样的呢?我们知道,其实html标签其实是可以嵌套的层次结构,比如很常见的一个div里丢了两个p标签。所以,用一个树形结构,对其进行表示再合适不过了。


网络异常,图片无法展示
|


这个树形结构也就如上图所示,他也有一个名字:DOM(Document Object Model)。

那么DOM有什么用呢:


  • DOM是页面的内部表示
  • DOM也为js提供了查询和修改的api接口


DOM阶段总结


这一步,浏览器干了什么事情,解析了html,把html转化成了DOM。

输入:html代码

输出:DOM

目前流程图:


网络异常,图片无法展示
|


STYLE

STYLE阶段介绍


大家现在想一想,现在我们有了DOM,但是这个DOM只是html转化出来的数据结构,上面是没有样式信息的,而我们要得到的数据结构一定是带有样式信息并且能表示标签嵌套层级的数据结构。所以我们在Style这一步,目的是为了可以得到能与DOM有效结合的css结构!!


这一步和DOM的意思也差不多,我们会把css代码转换成CSSOM。所以我们模仿一下前面DOM的话,那么CSSOM有什么作用呢?


  • 能表示css结构的层级
  • 为js提供可以操作css的API,允许用户动态的读取和修改css样式。


下一步,浏览器会再计算出computedStyle,DOM树中的每一个节点都有对应的computedStyle。


STYLE阶段总结


这一步,浏览器干了什么事情,把css解析,转化成了CSSOM,又转换成了和DOM节点一一对应的computedStyle。


输入:css

输出:computedStyle

目前流程图:


网络异常,图片无法展示
|


LAYOUT

LAYOUT阶段介绍


首先,我们回顾一下,我们前面的操作得到了啥,我们得到了DOM,它可以表示标签的嵌套结构,又得到了computedStyle,它存储着样式信息并可以和DOM节点一一对应。于是,我们想法就很简单,把DOM和computedStyle结合起来。于是乎,就有了LAYOUT这个阶段。


layout布局算法的输入就是DOM和computedStyle。


这一步主要就是确定元素的几何形状,坐标和尺寸。其中有以下几点要处理:


  • 【块流】最简单的情况下,布局按dom的顺序,垂直的排列一个有一个块,也叫块流(block flow)
  • 【行内流】还有文本和行内元素比如span,会在一行从左到右流动,叫做行内流,inline-flow。
  • 【字体】布局也要计算字体。(使用HarfBuzz的文本形状库)
  • 【包围矩形】布局可以为一个元素计算多种类型的边界矩形。 例如,当存在溢出时,布局将计算边框框的矩形和布局溢出矩形。如果节点的溢出是可滚动的,布局还计算滚动边界并为滚动条保留空间。最常见的可滚动DOM节点是document节点本身(dom树的根)。
  • 【复杂布局】比如表格,或者由内容包围的浮动元素


网络异常,图片无法展示
|


最后这个阶段会生成Layout Tree,这个Layout Tree与DOM相关联,但是不是一一对应的,比如:


  • 一个容器里面有了 div和span,span是行内元素,div是块级元素,于是,为了保证容器里面只有块级盒子,所以会在span的布局对象外面包裹一层匿名的块级盒子。这就是一个LayoutObject没有对应的DOM节点的情况。(如上图anonymous LayoutBlock)
  • 以及如果一个盒子的计算属性中的display属性是none,那么它也没有对应的LayoutObject。


LAYOUT阶段总结


这一步,我们干了什么事情,我们拿到了上一步的结果(DOM和computedStyle),通过布局算法,将两者进行了结合,我们得到了含有样式信息,布局信息的layout tree。但是注意这个layout tree和DOM不是一一对应的。


输入:DOM,computedStyle


输出:layout tree

目前流程图:


网络异常,图片无法展示
|


paintlayer tree


前面我们得到了Layout Tree,但是现在有一个问题,现在这个东西只能无脑的让文档流靠后的元素覆盖前面的元素。然而浏览器还有个层叠上下文就是决定元素间相互覆盖关系(比如z-index)的东西。这使得文档流中位置靠前位置的元素有可能覆盖靠后的元素。

于是PaintLayer Tree诞生了!!!PaintLayer 这棵树主要用来实现层叠上下文,以保证dom重叠时也能用正确的顺序合成页面,这样才能正确的展示元素的重叠以及半透明元素等等。


我们在此,只需要,为了处理层叠上下文,于是有了paintlayer tree,就ok了。

于是现在的流程图变成了这样:


网络异常,图片无法展示
|


comp.assign

comp.assign阶段介绍


好的,经过前面几个步骤,我们拿到了一个具有样式属性又可以表示嵌套结构的的数据结构了。所以,我们现在可以想一些额外的问题了?


我们的页面是静态的么?是不是有可能经常变动?

所以,如果变动会导致整个渲染过程重新运行一遍,是不是开销巨大?

所以,这个问题是不是要解决? 是的,必须要解决!!!(大喊,并有哭腔)

于是我们引入了图层合成加速的概念。什么是图层合成加速?


  • 图层合成加速是把整个页面按照一定规则划分成多个图层,在渲染的时候,只要操作必要的图层,其他的图层只要参与合成就好了,以这种方式提高了渲染的效率

合成层作用:

  • 合成层的绘制,渲染会交给GPU处理,比CPU更快
  • repaint时,只用repaint自身即可

于是为了页面变动时的性能,我们引入了comp.assign这个阶段,他会把整个页面按照一定规律划分成多个图层。


comp.assign阶段总结


这一步,我们干了什么事情,我们为了页面变动时不重新运行整个渲染的管道,把整个页面拆分成了很多图层。


输入:paintlayer tree/layout tree

输出:GraphicsLayer(图层) Tree

目前流程图:(我们的内容也越来越充实了)


网络异常,图片无法展示
|


Prepaint

Prepaint阶段介绍


在描述属性的层次结构这一块,之前的方式是使用图层树(GraphicsLayer Tree)的方式,如果父图层具有矩阵变换(平移、缩放或者透视)、裁剪或者特效(滤镜等),需要递归的应用到子节点,这在极端情况下会有性能问题。 于是,就有了 属性树这个概念。合成器提供了变换树,裁剪树,特效树等。每个图层都有若干节点id,分别对应不同属性树的矩阵变换节点、裁剪节点和特效节点。 在发生变换的时候,可以直接对这些节点进行操作。


网络异常,图片无法展示
|


Prepaint阶段总结


目的:对这些变换进行单独处理以提高性能。


做了什么:对这些上述变换做了单独处理,构建了 property trees(属性树,注意是trees)

输入:paintlayer tree/layout tree

输出:Property trees

目前流程图:


网络异常,图片无法展示
|


Paint

Paint阶段介绍


paint阶段,我就简单的一笔带过,就是我们去遍历上一阶段结果(即:GraphicsLayers)并把绘制的操作放在一个数据结构里面(DisplayItem)

Paint阶段也是 blink和cc(合成器组件)对接的阶段,会对DisplayItem List再处理为 cc:layer list 并和prepaint阶段产生的Property trees提交给 合成器线程。


网络异常,图片无法展示
|


在此我引用了官方的流程图,大家可以以此回顾,我们之前做了什么。


from layout
  |
  v
+------------------------------+
| LayoutObject/PaintLayer tree |-----------+
+------------------------------+           |
  |                                        |
  | PaintLayerCompositor::UpdateIfNeeded() |
  |   CompositingInputsUpdater::Update()   |
  |   CompositingLayerAssigner::Assign()   |
  |   GraphicsLayerUpdater::Update()       | PrePaintTreeWalk::Walk()
  |   GraphicsLayerTreeBuilder::Rebuild()  |   PaintPropertyTreeBuider::UpdatePropertiesForSelf()
  v                                        |
+--------------------+                   +------------------+
| GraphicsLayer tree |<------------------|  Property trees  |
+--------------------+                   +------------------+
      |                                    |              |
      |<-----------------------------------+              |
      | LocalFrameView::PaintTree()                       |
      |   LocalFrameView::PaintGraphicsLayerRecursively() |
      |     GraphicsLayer::Paint()                        |
      |       CompositedLayerMapping::PaintContents()     |
      |         PaintLayerPainter::PaintLayerContents()   |
      |           ObjectPainter::Paint()                  |
      v                                                   |
    +---------------------------------+                   |
    | DisplayItemList/PaintChunk list |                   |
    +---------------------------------+                   |
      |                                                   |
      |<--------------------------------------------------+
      | PaintChunksToCcLayer::Convert()                   |
      v                                                   |
+--------------------------------------------------+      |
| GraphicsLayerDisplayItem/ForeignLayerDisplayItem |      |
+--------------------------------------------------+      |
  |                                                       |
  |    LocalFrameView::PushPaintArtifactToCompositor()    |
  |         PaintArtifactCompositor::Update()             |
  +--------------------+       +--------------------------+
                       |       |
                       v       v
        +----------------+  +-----------------------+
        | cc::Layer list |  |   cc property trees   |
        +----------------+  +-----------------------+
                |              |
  +-------------+--------------+
  | to compositor
  v



Paint阶段总结


做了什么:处理GraphicsLayers,把绘制操作放在DisplayItem中。因为Paint阶段也是主线程最后一个步骤,也要与合成器线程对接,所以会把数据再处理为 cc:layer list并和prepaint阶段产生的Property trees(也会处理为cc property trees)提交给 合成器线程。


输入:GraphicsLayer Tree,Property trees

中间产物:DisplayItem List

输出: cc:layer list,cc property trees

目前流程图:(一下子就变大了嘿)


网络异常,图片无法展示
|

相关文章
|
6月前
|
Web App开发 Ubuntu 安全
【已解决】ubuntu 16.04安装最新版本google chrome出错, 旧版本chrome浏览器安装流程
【已解决】ubuntu 16.04安装最新版本google chrome出错, 旧版本chrome浏览器安装流程
454 0
|
2月前
|
消息中间件 JavaScript 前端开发
前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理)
前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理)
|
3月前
|
前端开发 JavaScript 数据可视化
探索浏览器的内心世界:渲染机制的奥秘
探索浏览器的内心世界:渲染机制的奥秘
探索浏览器的内心世界:渲染机制的奥秘
|
3月前
|
消息中间件 前端开发 Java
【面试题】前端必修-浏览器的渲染原理
【面试题】前端必修-浏览器的渲染原理
|
7月前
|
Web App开发 存储 监控
浏览器基础原理-安全: 渲染进程-安全沙盒
浏览器基础原理-安全: 渲染进程-安全沙盒
37 0
|
9月前
|
开发框架 安全 .NET
您是否也有想在浏览器中实时的编辑代码并且渲染的想法?
您是否也有想在浏览器中实时的编辑代码并且渲染的想法?
52 0
|
9月前
|
Web App开发 自然语言处理 JavaScript
JS进阶(五)同步异步编程及浏览器的底层渲染机制
浏览器渲染机制 浏览器底层渲染机制 一个页面从服务器访问,拿到页面源代码之后做的事情是什么? 生成Dom树(DOM Tree) => 对HTML文件的处理 基于HTML获取的是流文件 (进制编码) 把进制编码编译为具体的字符 按照令牌TOKEN进行解析 (分词/断词) 生成具体的节点 (元素标签/文本节点....) 按照相互的依赖关系生成一个DOM树 (节点树)
133 0
|
11月前
|
存储 缓存 前端开发
|
11月前
|
Web App开发 JavaScript 算法
深入解析 EventLoop 和浏览器渲染、帧动画、空闲回调的关系
关于 Event Loop 的文章很多,但是有很多只是在讲「宏任务」、「微任务」
|
网络协议 安全 前端开发
【网络小知识】当我在浏览器url输入文本后的解析流程/http协议对比https协议
当我在浏览器url输入文本后的解析流程/http协议对比https协议

热门文章

最新文章