浏览器的渲染机制(一)下

简介: 浏览器的渲染机制(一)下

Layout


在构建了DOM并计算了所有样式之后,下一步是确定所有元素的视觉几何形状。对于这个块级元素我们会计算这个矩形的坐标,对应到这个由元素在content区域占有的几何区域。


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


在最简单的情况下,布局按DOM顺序,垂直降序排列一个个块。我们称之为“block flow”。即 块流(如下图)


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


文本以及行内元素比如会生成行内盒,行内盒通常在一行中从左向右流动,这叫做“行内流”,inline-flow。RTL语言,如阿拉伯语和希伯来语,反转了行内流的方向,是从右到左的。


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


布局要求从计算样式使用字体。 布局使用一个名为HarfBuzz的文本形状库来计算每个字形的大小和位置,这决定了文本运行的总体宽度。字体成形必须考虑排版,比如如字距和(ligatures 连体)


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


布局可以为一个元素计算多种类型的边界矩形。 例如,当存在溢出时,布局将计算边框框的矩形和布局溢出矩形。如果节点的溢出是可滚动的,布局还计算滚动边界并为滚动条保留空间。最常见的可滚动DOM节点是document节点本身(dom树的根)。


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


更复杂的布局需要table元素或者更加复杂的布局,例如将内容拆分为多个列,或浮动对象位于一侧,内容在其周围流动,或部分东亚语言的文本是垂直运行而不是水平运行。 注意DOM结构和ComputedStyle值是如何输入到布局算法的。每个管道阶段使用的是前几个阶段的结果。


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


布局操作在一个单独的树上(layout tree),这个树与DOM相关联,layout tree的节点实现yin法,LayoutObject有不同的子类(block,text...),这取决于所需的布局行为。样式的更新阶段也会去构建布局树,布局阶段遍历布局树,计算每个LayoutObject的视觉几何形状,并对每个LayoutObject执行布局。


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


在一般的情况下,一个DOM节点是对应一个LayoutObject,但有时候,一个DOM节点没有对应的LayoutObject,也有的时候一个LayoutObject没有对应的DOM节点,也有的时候,一个DOM节点可以对应多个LayoutObject。(如果一个容器盒子,里面如果有了一个块级盒子,那么,他里面便只能有块级盒子)


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


这个布局树的构造是基于一个叫做FlatTreeTraversal(平面树遍历的算法)。(ps:可以深入研究)


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



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


现在的布局引擎正在重写,现在的布局树中保留着上一代的布局对象和 新一代布局对象(NG = next generation),当然在最后,所有的布局对象都会变成新一代的布局对象,上一代的布局对象中保留着输入输出,以及布局的算法,这可以看到整棵树的状态。在下一代中,布局的输入和输出都是有清晰的分隔的,输出是一个不可更改,可缓存的布局结果。


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


布局结果会指向一个描述物理几何的片段树。


Example


以下举个例子:


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


左上角是代码,右下角是效果,


那么这个代码会对应什么样子的DOM呢。


<div style="max-width: 100px">
  <div style="float: left; padding: 1ex">F</div>
  <br>The <b>quick brown</b> fox
  <div style="margin: -60px 0 0 80px">jumps</div>
</div>


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


没错,就是左侧这样的DOM树,那它会对应怎么样的LayoutTree结构呢。


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


对应的布局树的结果是这样的,这里需要我解释一下,首先这个容器div里面有块级元素div,所以,为了保证容器盒子里面只有块级元素,所以会用一个匿名的块级盒子将其包裹起来,(这里注意,第一个div因为具有浮动属性,所以它也已经不是块级元素了)

下一步是什么,没错,就是上面说到的,他会计算生成一棵片段树,里面会有描述物理几何的信息。


Box (block-flow) at 0,0 100x12
  Box (block-flow children-inline) at 0,0 100x54
    LineBox at 24.9,0 0x18
      Box (floating block-flow children-inline) at 0,0 24.9x34
        LineBox at 8,8 8.9x18
          Text 'F' at 8,8 8.9x17
      Text '\n' at 24.9,0 0x17
    LineBox at 24.9,18 67.1x18
      Text 'The ' at 24.9,18 28.9x17
      Text 'quick' at 53.8,18 38.25x17
    LineBox at 0,36 69.5x18
      Text 'brown' at 0,36 44.2x17
      Text ' fox' at 44.2,36 25.3x17
  Box (block-flow children-inline) at 80,-6 20x18
    LineBox at 0,0 39.125x18
      Text 'jumps' at 0,0 39.125x17


这棵树大概就是这样的,上面会有坐标以及宽高等信息。


Paint绘制


经过上面那一大堆流程,现在我们已经理解了布局对象的几何形状,是时候把他们绘制出来了。Paint这个流程会将绘制的操作记录在显示项(display items)列表中。绘制操作可能类似于“在这些坐标处以这种颜色绘制矩形”。每个布局对象可能有多个显示项(display items),对应其视觉外观的不同部分,如背景、前景、轮廓等。


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


重要的是要按照正确的顺序绘制元素,以便在重叠时能够正确地堆叠。顺序可以通过style来控制(z-index),如下图,举个例子(注意:z-index只能在定位元素上生效,真的是边写例子,变解决知识漏洞,嘿嘿)。


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


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


上面代码对应的DOM树是这样的,但是在Paint绘制的时候,并不是按照DOM顺序,先画黄的,再画绿的,而是按照栈的顺序,如上面效果,是先画的底层的绿色,再去绘制的黄色的方块。


一个元素甚至可以部分在另一个元素的前面,部分在另一个元素的后面。这是因为绘制在多个阶段中运行,每个绘制阶段都对子树进行自己的遍历。每个绘制阶段都是一个堆叠上下文的单独遍历。


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


比如上面这个例子,虽然蓝色是再绿的后面,但是因为foregrounds是在background之后,于是,文字就在最前面了。


Paint - example


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


上面是代码和效果,那么它在绘制阶段的display items是什么样的呢


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


就是首先画 根节点 document,之后对盒子进行绘制,之后绘制前景色。其中文本运行的绘制操作包含一个blob,其中包含每个符号的标识符和偏移量。


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


结语


这样就讲完了浏览器渲染机制的前半段,下一篇会从光栅化开始讲,整个浏览器渲染机制会有2-3篇文章,也会有其他的延申。

相关文章
|
1月前
|
存储 前端开发 开发者
|
25天前
|
缓存 自然语言处理 前端开发
浏览器渲染
【10月更文挑战第28天】浏览器渲染涉及将HTML、CSS和JavaScript代码转换为可视网页,主要步骤包括:解析HTML构建DOM树、解析CSS构建CSSOM树、合并DOM与CSSOM生成渲染树、布局确定元素位置和尺寸、绘制元素到屏幕、合成图层形成最终图像。此过程不断优化以提升性能。
|
1月前
|
前端开发 JavaScript 异构计算
简述浏览器的渲染原理
浏览器渲染原理主要包括以下步骤:1)解析HTML文档生成DOM树;2)解析CSS生成CSSOM树;3)结合DOM与CSSOM生成渲染树;4)布局计算(回流)确定元素大小和位置;5)绘制(Paint)将节点转为图形内容;6)合成(Composite)多层图像。整个过程从文档解析到最终输出完整网页,并通过优化技术提升性能。
|
6月前
|
缓存 JavaScript 前端开发
浏览器渲染:理解页面加载的幕后工作
浏览器渲染:理解页面加载的幕后工作
|
4月前
|
JavaScript 前端开发 开发者
浏览器事件机制详解
浏览器事件机制详解
44 1
|
5月前
|
监控 前端开发 JavaScript
记录浏览器节能机制导致Websocket断连问题
近期,在使用WebSocket(WS)连接时遇到了频繁断连的问题,这种情况在单个用户上每天发生数百次。尽管利用了socket.io的自动重连机制能够在断连后迅速恢复连接,但这并不保证每一次重连都能成功接收WS消息。因此,我们进行了一些的排查和测试工作。
458 1
记录浏览器节能机制导致Websocket断连问题
|
4月前
|
存储 JavaScript 前端开发
在?聊聊浏览器事件循环机制
在?聊聊浏览器事件循环机制
45 0
|
5月前
|
移动开发 前端开发 JavaScript
浏览器端图表渲染技术SVG, VML HTML Canvas
浏览器端图表渲染技术SVG, VML HTML Canvas
40 0
|
6月前
|
前端开发 JavaScript 数据可视化
探索浏览器的内心世界:渲染机制的奥秘
探索浏览器的内心世界:渲染机制的奥秘
探索浏览器的内心世界:渲染机制的奥秘
|
6月前
|
消息中间件 JavaScript 前端开发
前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理)
前端秘法进阶篇----这还是我们熟悉的浏览器吗?(浏览器的渲染原理)
106 0