浏览器渲染流程

渲染流程: 构建 DOM 树、样式计算、布局阶段、分层、绘制、光栅化 和 合成。

构建 DOM 树

   这是因为浏览器无法直接理解和使用 HTML,所以需要将 HTML 转换为 浏览器能够理解的结构—— DOM 树。

Dom tree
DOM树构建过程⽰意图

样式计算

    当渲染引擎接收到 CSS 文本时,会执行⼀个转换操作,将 CSS 文本转换为浏览器可以理解的结构—— styleSheets;

    css 的来源只要有三种:通过link引用的外部 CSS 文件;<style > 标签内的 CSS;元素的 style 属性内嵌的 CSS。

   样式计算的目的是为了计算出 DOM 节点中每个元素的具体样式,这个阶段可以分为三步来完成:

   1. 把 CSS 转换为浏览器能够理解的结构;

   2. 转换样式表中的属性值,使其标准化, 比如 2em 解析文 32px, color:green 解析为 rpg;

   3. 计算出DOM树中每个节点的具体样式;

       这就涉及到 CSS 的 继承规则层叠规则 

           继承规则 :CSS 继承就是每个 DOM 节点都包含有父节点的样式;

           层叠规则:层叠是 CSS 的⼀个基本特征,它是⼀个定义了如何合 并来自多个源的属性值的算法。它在 CSS 处于核心地位,CSS 的全称“层叠样式表”正是强调了这 ⼀点。

样式计算
计算后DOM的样式

布局阶段

    我们有 DOM 树和 DOM 树中元素的样式,接下来就需要计算出 DOM 树中 可见元素 几何位置,我们把这个计算过程叫做布局。

    Chrome 在布局阶段需要完成两个任务:创建布局树布局计算

    创建布局树的过程:

        遍历DOM树中的所有 可见节点,并把这些节点加到布局中;

        而不可见的节点会被布局树忽略掉,如 head 标签下面的全部内容, body.p.span 这个元素,因为它的属性包含 dispaly:none,所以这个元素也没有被包进布局树。

布局树构造过程⽰意图

分层

    页⾯中有很多复杂的效果,如⼀些复杂的3D变换、页面滚动,或者使用 z-indexing 做 z 轴排序等,为了更加方便地实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成⼀棵对应的图层树(LayerTree)。

    浏览器的页面实际上被分成了很多图层,这些图层叠加后合成了最终的页面

layout tree
布局树和图层树关系⽰意图

    并不是布局树的每个节点都包含⼀个图层,如果⼀个节点没有对应的层,那么这个节点就从属于父节点的图层。

    如何创建层?

        1 拥有层叠上下⽂属性的元素会被提升为单独的⼀层, 比如 明确定位属性的元素(position)、定义透明属性的元素、使⽤CSS滤镜的元素等,参考层叠上下文

        2 需要剪裁(clip)的地方也会被创建为图层。


图像绘制

    渲染引擎实现图层的绘制会把一个图层的绘制拆分成很多小的绘制指令,然后再把这些指令按照顺序组成⼀个待绘制列表

    我们可以通过开发工具来查看。

Layers
图像绘制

光栅化

    绘制列表只是用来记录绘制顺序和绘制指令的列表,而实际上绘制操作是由渲染引擎中的合成线程来完成的。

    当图层的绘制列表准备好之后,主线程会把该绘制列表提交(commit)给合成线程。

渲染进程中的合成线程和主线程

     合成线程 会按照 视口(用户能看到的那部分叫视口  viewport) 附近的图块(合成线程会将图层划分为图块 tile)来优先生成位图,实际生成位图的操作是由栅格化来执行的所谓栅格化是指将图块转换为位图,简单来说就是我们需要做的是把这些信息转化为 显示器中的像素,这个转化的过程,叫做光栅化。

视⼝附近的图块来优先⽣成位图

    我们要绘制一个页面,最简单的做法是只光栅化视口内(viewport)的网页内容,如果用户进行了页面滚动,就移动光栅帧(rastered frame)并且光栅化更多的内容以补上页面缺失的部分。(我们没有必要一开始就全部 绘制所有的内容,产生开销太大,影响性能)。

合成和显示

    一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令--- DrawQuad 命令,然后将改命令提交给浏览器进程。

    浏览器进程里面有一个叫 viz 的组件, 用来接受合成线程发过来 DrawQuad 命令,然后根据 DrawQuad 命令, 将其页面内容绘制到内存中, 最后在将内存显示在屏幕上。


完整的流程

完整的渲染流⽔线⽰意图

    1. 渲染进程将HTML内容转换为能够读懂的 DOM 树结构。

    2. 渲染引擎将CSS样式表转化为浏览器可以理解的 styleSheets,计算出DOM节点的样式。

    3. 创建布局树,并计算元素的布局信息。

    4. 对布局树进行分层,并生成分层树

    5. 为每个图层生成绘制列表,并将其提交到合成线程

    6. 合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图

    7. 合成线程发送绘制图块命令 DrawQuad 给浏览器进程。

    8. 浏览器进程根据 DrawQuad 消息生成页⾯,并显示到显示器上。


 重排、重绘 和 合成

     更新了元素的几何属性(例如改变元素的宽度、高度等)-----> 重排 

            重排需要更新完整的渲染流⽔线,所以开销也是最大的

更新元素的几何属性

     更新了元素的绘制属性(比如更改了某些元素的背景颜色)-----> 重绘  

更新元素背景

        如果修改了元素的背景颜⾊,那么布局阶段将不会被执行,因为并没有引起⼏何位置的变换,所以就直接进⼊了绘制阶段,然后执⾏之后的⼀系列⼦阶段,这个过程就叫重绘。相较于重排操作,重绘省去了布局和分层阶段,所以执行效率会⽐重排操作要高⼀些。


    直接合成阶段

            如果更改⼀个既不要布局也不要绘制的属性,渲染引擎将跳过布局和绘制,只执行后续的合成操作,我们把这个过程叫做合成。

避开重排和重绘

    我们使用了 CSS 的 transform 来实现动画效果,这可以避开重排和重绘阶段,直接在非主线程上执行合成动画操作。这样的效率是最高的,因为是在非主线程上合成,并没有占用主线程的资源,另外也避开了布局和绘制两个子阶段,所以相对于重绘和重排,合成能大大提升绘制效率。


引用资料

    浏览器工作原理与实践

    Inside look at modern web browser

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342