Life of a Pixel 学习笔记

前言

Life of a Pixel 演讲的学习笔记。浏览器的渲染过程极为的复杂,演讲的语速也特别的快,因此若有错误请及时指出。css

Content

前端的全部代码统称为Content,好比html,js,css,图片,视频等。html

在Chromium代码架构上Content命名空间包含了,黄色框内的全部内容。在Chromium代码中由WebContent类表示,WebContent类中封装了渲染进程。前端

image.png

Chromium

Chromium是Google的开源项目,Chrome浏览器就是基于Chromium代码实现,Edge,Opera也是基于Chromium代码。git

Blink 浏览器排版引擎

Blink是浏览器排版引擎,属于Chromium中的一部分。Blink属于Content中渲染过程代码的子集。github

总结一下:在Chromium中WebContent类负责Content的渲染,渲染过程交由Blink实现web

初次渲染阶段

parsing(解析HTML)-> style (生成样式规则模型) -> layout(生成布局对象)-> compositing update (输入合成)-> paint(绘制)-> commit(提交)-> tiling(切割)-> raster(栅格化)-> draw quads -> display(显示到屏幕上)浏览器

open gl

浏览器并不能只靠本身将网页渲染到屏幕上,浏览器的渲染须要使用底层操做系统提供的图形库,好比OpenGL API。可是OpenGL并不认识Html,Css这些内容,因此须要经过浏览器的Web Content须要将Html,Css转换成OpenGL能够识别的内容,而后经过OpenGL渲染到屏幕上。缓存

在渲染到屏幕以后,须要监听并响应,JavaScript,用户输入,异步加载,动画,滚动,缩放,而后进行渲染更新。对于一些更新渲染,是不须要从头走彻底部的渲染流程的。网络

parsing

从网络请求开始,最早获取的是html文件,因此浏览器渲染的起点,是HTML解析器。同时HTML中引入了CSS,JS,图片等资源,浏览器也会加载它们。架构

HTML文件的解析过程:

HTML文件 -stream-> HTMLDocumentParser(HTML文档解析器)-> HTMLTreeBuilder(HTML树构建器)-> DOM

DOM(Document Object Model) 文档对象模型

DOM是基于HTML的倒着的树形结构,DOM有两个做用:

  1. 做为Chrome的内部表示
  2. DOM树通过v8引擎的包装。将更新,查询的API,暴露给js。

style

CSS样式表的解析过程:

CSS样式表 -> CSSParser(CSS解析器)-> 样式规则模型(Style Rule Model)

CSS样式是如何做用与DOM的?

根据已经解析的样式规则(Style Rule),和浏览器的默认样式,计算出每个DOM的样式。样式和属性值存储在一个巨大的ComputedStyle对象中。ComputedStyle对象是属性和属性值的映射。ComputedStyle对象中会挂载元素,应对应不一样元素的不一样样式。

layout

在构建完DOM并完成样式计算后,须要肯定全部元素的几何形状(几何形状所占的区域以及坐标),这些布局信息称为LayoutObject对象,

布局对象(LayoutObject)保存布局树中,并与DOM关联。不一样的节点,对应不一样的布局类。可是不一样布局类都继承自LayoutObject这个父类。

image.png

image.png

LayoutObject对象和DOM元素并非一一对应的。好比当DOM元素的样式是display: none时,是没有LayoutObject对象的。

compositing update

输入合成阶段,咱们在下面讲🍵

paint

根据布局对象(LayoutObject),绘制操做会将绘制操做记录在一个待显示项目列表(display items list)中。

什么是绘制操做?好比,根据布局对象(LayoutObject)在指定区域绘制一个红色的矩形。这就是绘制操做。

每个布局对象(LayoutObject)对应多个待显示项目,由于可能涉及到绘制不一样的部分。目前只是记录绘制操做,还没有执行绘制操做。绘制的顺序,受控于z-index属性。

commit,tiling

提交,分割阶段,咱们在下面讲🍵

raster

待显示项目列表中绘制的实际操做,是由栅格化进程执行的。

栅格化会将待显示项,转换为颜色值的位图(将图像的信息,以像素为单位记录,记录每个像素点的颜色信息rgba值)。位图信息保存在内存中(一般是显存中)。gpu也能够将待显示项目列表栅格化,咱们称为gpu加速。此时位图信息还保存在显存中,没有输出到屏幕上。

对于图像信息,栅格化会对图像进行解码,获取位图信息。

栅格化的过程是经过SKIA库调用OpenGL API完成的。

SKIA

SKIA是一个开源的图形引擎,SKIA能够实现栅格化,PDF输出,GPU加速。

draw quads

draw quads阶段,咱们在下面讲🍵

gpu(display阶段)

SKIA产生OpenGL调用,使用命令缓存区的形式,传输到GPU进程,GPU接受到命令缓存,产生GL调用。像素被渲染到屏幕上了。

更新渲染阶段

commit(提交)-> tiling(切割)-> raster(栅格化)-> draw quads -> display(显示到屏幕上)

渲染不是静态的,JavaScript,用户输入,异步加载,动画,滚动,缩放,都会改变渲染。从头执行渲染流程代价会很昂贵。若是每一秒低于60fps,就会变得卡顿。

优化1: Invalidation

为了不从头执行整个渲染流程,经常使用的优化方法就是标记出,发生了改变的部分,复用没有改变的部分。好比一个节点须要从新计算样式,在下一帧的时候,只从新计算该节点的样式。

优化2: enter: compositing 输入合成

Chrome另外的优化手段是分层

  1. 将页面分解成多个图层,每个图层能够单独进行栅格化。
  2. 另外单独线程进行图层的合成

image.png

Layers 分层

动画,滚动,缩放,操做都会建立图层。单独的合成线程,会对滚动输入操做,进行单独处理。

while(true) {
}
复制代码

当咱们使用js阻塞主线程时,因为单独的合成线程的存在,合成线程会对用户的滚动操做进行处理,虽然主线程被阻塞可是页面依然能够滚动

Layers tree 图层树

图层的存储结构也是树的形式,图层树间接的基于布局树。

image.png

compositing update 输入合成

compositing update(输入合成)阶段发生在Layout(布局)阶段以后,Paint(绘制)阶段以前。对页面进行分层,每一个图层被分别绘制。绘制阶段存在的待显示项目列表(display items list),其实不一样的图层拥有不一样的待显示项目列表(display items list)

image.png

commit

image.png

绘制完成后,经过同步主线程的状态,更新合成线程图层的状态,最后同步回主线程

tiling

Raster会将待显示项目列表(display items list)转换为位图,可是有时候图层会很大,Raster又是一个开销很大的步骤,合成线程会将图层分割为图块,图块是Raster的基本单位。距离视口越近,会优先建立图块优先被栅格化。

图块会在单独Raster线程中栅格化

image.png

draw

在绘制完全部图块以后,合成器线程将生成draw quadsdraw quads是绘制图块的指令,draw quads被包装在合成器框架对象中,提交给浏览器进程。

display

浏览器进程,运行显示合成器的组件,合成器组件调用OpenGL绘制draw quads,最后像素在用户的屏幕上可见。

参考

相关文章
相关标签/搜索