canvas教程

How Rendering Work (in WebKit and Blink)

字号+ 作者:H5之家 来源:H5之家 2017-05-19 18:02 我要评论( )

自从开始从事浏览器内核开发工作以来,已经写过不少跟渲染相关的文章。但是一直想写一篇像 How Browsers Work 类似,能够系统,完整地阐述浏览器的渲染引擎是如何工作的,它是如何对网页渲染性能进行优化的文章,却一直因为畏惧所需要花费的时间和精力,迟迟

自从开始从事浏览器内核开发工作以来,已经写过不少跟渲染相关的文章。但是一直想写一篇像 How Browsers Work 类似,能够系统,完整地阐述浏览器的渲染引擎是如何工作的,它是如何对网页渲染性能进行优化的文章,却一直因为畏惧所需要花费的时间和精力,迟迟无法动笔。不管如何,现在终于鼓起勇气来写了,希望自己能够完成吧…

文章包括的主要内容如下 —

首先明确文中关于渲染的定义,浏览器内核引擎通常又被称为网页渲染引擎,但是这里的渲染实际上是一个泛指,广义的渲染,它包括了浏览器内核所有的主要工作 - 加载,解析,排版,绘制等等。而在本文里面的渲染,指的是跟绘制相关的部分,也就是浏览器是如何将排版后的结果最终显示在屏幕上的这一过程。如果读者希望先对浏览器内核引擎,特别是 WebKit 有一个大概的了解,How Browsers Work,,WebKit for Developers 可以提供不错的入门指引。

其次,本文主要描述 WebKit 引擎的实现,不过因为 Blink 实际上从 WebKit 分支出来的时间并不长,两者在渲染整体架构上还是基本一致的,所以文中不会明确区分这两者。

最后,希望这篇文章能够给从事浏览器内核开发,特别是渲染引擎开发的开发者一个能够快速入门的指引,并给前端开发者优化网页渲染性能提供足够的知识和帮助。

因为文章后续还有可能会持续修订和补充,如果要查看最新的内容,请访问个人博客的原文:,如果有什么疏漏和错误,也欢迎读者来信指正(roger2yi@gmail.com)。

渲染基础 - DOM & RenderObject & RenderLayer

DOM,RenderObject,RenderLayer

图片来自 GPU Accelerated Compositing in Chrome

当浏览器通过网络或者本地文件系统加载一个 HTML 文件,并对它进行解析完毕后,内核就会生成它最重要的数据结构 - DOM 树。DOM 树上每一个节点都对应着网页里面的每一个元素,并且网页也可以通过 JavaScript 操作这棵 DOM 树,动态改变它的结构。但是 DOM 树本身并不能直接用于排版和渲染,内核还会生成另外一棵树 - Render 树,Render 树上的每一个节点 - RenderObject,跟 DOM 树上的节点几乎是一一对应的,当一个可见的 DOM 节点被添加到 DOM 树上时,内核就会为它生成对应的 RenderOject 添加到 Render 树上。

Render Tree

图片来自

Render 树是浏览器排版引擎的主要作业对象,排版引擎根据 DOM 树和 CSS 样式表的样式定义,按照预定的排版规则确定了 Render 树最后的结构,包括其中每一个 RenderObject 的大小和位置,而一棵经过排版的 Render 树,则是浏览器渲染引擎的主要输入,读者可以认为,Render 树是衔接浏览器排版引擎和渲染引擎之间的桥梁,它是排版引擎的输出,渲染引擎的输入。

Layer Tree

图片来自

不过浏览器渲染引擎并不是直接使用 Render 树进行绘制,为了方便处理 Positioning(定位),Clipping(裁剪),Overflow-scroll(页內滚动),CSS Transform/Opacity/Animation/Filter,Mask or Reflection,Z-indexing(Z排序)等,浏览器需要生成另外一棵树 – Layer 树。渲染引擎会为一些特定的 RenderObject 生成对应的 RenderLayer,而这些特定的 RenderObject 跟对应的 RenderLayer 就是直属的关系,相应的,它们的子节点如果没有对应的 RenderLayer,就从属于父节点的 RenderLayer。最终,每一个 RenderObject 都会直接或者间接地从属于一个 RenderLayer。

RenderObject 生成 RenderLayer 的条件,来自 GPU Accelerated Compositing in Chrome – It’s the root object for the page – It has explicit CSS position properties (relative, absolute or a transform) – It is transparent – Has overflow, an alpha mask or reflection
– Has a CSS filter – Corresponds to < canvas> element that has a 3D (WebGL) context or an accelerated 2D context – Corresponds to a < video> element

浏览器渲染引擎遍历 Layer 树,访问每一个 RenderLayer,再遍历从属于这个 RenderLayer 的 RenderObject,将每一个 RenderObject 绘制出来。读者可以认为,Layer 树决定了网页绘制的层次顺序,而从属于 RenderLayer 的 RenderObject 决定了这个 Layer 的内容,所有的 RenderLayer 和 RenderObject 一起就决定了网页在屏幕上最终呈现出来的内容。

软件渲染模式下,浏览器绘制 RenderLayer 和 RenderObject 的顺序,来自 GPU Accelerated Compositing in Chrome

In the software path, the page is rendered by sequentially painting all the RenderLayers, from back to front. The RenderLayer hierarchy is traversed recursively starting from the root and the bulk of the work is done in RenderLayer::paintLayer() which performs the following basic steps (the list of steps is simplified here for clarity):

In this mode RenderObjects paint themselves into the destination bitmap by issuing draw calls into a single shared GraphicsContext (implemented in Chrome via Skia).

WebView,绘制与混合,多线程渲染

WebView

图片来自 [UC 浏览器 9.7 Android版],中间是一个 WebView,上方是标题栏和工具栏

浏览器本身并不能直接改变屏幕的像素输出,它需要通过系统本身的 GUI Toolkit。所以,一般来说浏览器会将一个要显示的网页包装成一个 UI 组件,通常叫做 WebView,然后通过将 WebView 放置于应用的 UI 界面上,从而将网页显示在屏幕上。

一些 GUI Toolkit,比如 Android,默认的情况下 UI 组件没有自己独立的位图缓存,构成 UI 界面的所有 UI 组件都直接绘制在当前的窗口缓存上,所以 WebView 每次绘制,就相当于将它在可见区域内的 RenderLayer/RenderObject 逐个绘制到窗口缓存上。上述的渲染方式有一个很严重的问题,用户拖动网页或者触发一个惯性滚动时,网页滑动的渲染性能会十分糟糕。这是因为即使网页只移动一个像素,整个 WebView 都需要重新绘制,而要绘制一个 WebView 大小的区域的 RenderLayer/RenderObject,耗时通常都比较长,对于一些复杂的桌面版网页,在移动设备上绘制一次的耗时有可能需要上百毫秒,而要达到60帧/每秒的流畅度,每一帧绘制的时间就不能超过16.7毫秒,所以在这种渲染模式下,要获得流畅的网页滑屏效果,显然是不可能的,而网页滑屏的流畅程度,又是用户对浏览器渲染性能的最直观和最重要的感受。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Fireworks制作渐隐线的技巧

    Fireworks制作渐隐线的技巧

    2017-03-05 13:04

  • SolidWorks模型

    SolidWorks模型

    2017-02-03 08:01

  • CSS3 Notes: -webkit-box-reflect完成倒影的实例

    CSS3 Notes: -webkit-box-reflect完成倒影的实例

    2016-12-26 10:02

  • SolidWorks2013 简体中文破解版 (32位/64位)

    SolidWorks2013 简体中文破解版 (32位/64位)

    2016-07-17 10:02

网友点评
{