zoukankan      html  css  js  c++  java
  • 渲染树结构、布局和绘制

    在页面的加载过程中,CSSOM树和DOM树会被合并成一棵渲染树,用于计算每个可视元素的布局。同时,它也会作为绘制过程的输入参数,用于绘制屏幕上的每个像素点。优化其中的每一步都对优化页面的渲染性能至关重要。

    在前面的章节中,我们介绍了对象模型的构建,也就是根据加载的HTML和CSS代码构建DOM树和CSSOM树。然而它们本质上是两个互相独立的东西,各自描述了页面文档的一个不同方面:前者描述了内容,后者描述了应用于内容的样式规则。那么浏览器是如何将两者结合起来并在屏幕上画出每个像素点的呢?

    学习重点

    • DOM树和CSSOM树合并在一起构成一棵渲染树
    • 渲染树只包含渲染所需要的节点
    • 布局的过程中会计算每个对象的精确位置和尺寸
    • 最后的绘制过程以渲染树为输入参数,在屏幕上画出每个像素点

    对浏览器而言,第一步便是将DOM树和CSSOM树合并成一棵渲染树。渲染树既包含了页面上所有的可视DOM节点,又包含了CSSOM中每个节点的样式信息。
    render-tree-construction
    为了创建渲染树,浏览器大致需要如下的步骤:

    1. 从DOM树的根节点开始,遍历所有的可视节点
      • 有些不可见元素(比如脚本标签,元数据标签之类)会被忽略,因为它们不影响渲染的结果
      • 有些通过CSS隐藏掉的元素也会被忽略,比如上图中的span元素。由于该元素上显式地设置了属性“display:none”,所以不会出现在渲染树上
    2. 对于每个可视节点,从CSSOM中寻找对应的样式规则,并付诸节点
    3. 输出可视的节点,以及每个节点计算出来的样式

    小贴士

    简要提示一下,CSS中“visibility:hidden”和“display:none”是不同的。前者将元素隐藏起来,但是隐藏元素仍然会在页面最终的布局中占据相应的空间(其实就是一块空白)。然而后者会直接将元素从渲染树中删除,不仅不可见,也不属于最终布局的一部分。

    最终的渲染树既包含了所有可视的内容,又包含了相应的样式信息。快要大功告成了!有了这棵渲染树,我们就能进入下一步,布局。

    在此之前,我们已经计算了什么节点是可视的以及它们对应的样式是什么,但是我们还没有计算它们在当前设备中准确的位置和尺寸。这正是布局阶段要做的的工作,该阶段在英语中也被称为“回流”(reflow)。

    为了算出每个对象的准确大小和位置,浏览器从渲染树的根节点开始遍历,计算页面中每个对象的几何样式。下面就让我们看一个简单的例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <html>
          <head>
            <meta name="viewport" content="width=device-width,initial-scale=1.0">
            <title>Critial Path: Hello world!</title>
          </head>
          <body>
            <div style=" 50%">
              <div style=" 50%">Hello world!</div>
            </div>
          </body>
    </html>

    完整的例子在这儿

    上面的页面中包含两个嵌套的div元素:第一个(父元素)设定了显示宽度为窗口的50%,第二个元素(子元素)设定了宽度为父元素的50%,即窗口宽度的25%。
    layout-viewport

    布局阶段的输出结果称为 “盒模型”(box model)。盒模型精确表达了窗口中每个元素的位置和大小,而且所有的相对的度量单位都被转化成了屏幕上的绝对像素位置。

    在最后阶段,已经知道了哪些节点是可视的、它们的样式和它们的几何外观,我们终于能够将这些信息渲染为屏幕上每个真实的像素点了。这个阶段称为“绘制”,或者“格栅化”(rasterizing)。

    到这里,各位读者理解了没?上述每一步中浏览器都需要进行大量的计算工作,也就是说需要消耗相当的时间。幸好,Chrome DevTools工具能够帮我们深入了解上述每一步。让我们一起看一看之前例子中“hello world”页面在布局阶段的数据:
    layout-timeline

    • 布局阶段的时间轴中捕获了渲染树的构建,以及元素位置和尺寸的计算过程
    • 一旦布局阶段完成,浏览器便开始绘制阶段,将渲染树转化为屏幕上的每个像素点

    渲染树的构建、页面布局以及绘制所花费的时间取决于页面的尺寸、样式的规则以及运行的设备。页面越大,浏览器的工作就越多;规则越复杂,就需要更多的时间来绘制(绘制单色比较方便,相比之下阴影的计算和渲染就麻烦的多了)。
    一旦上述步骤都完成了,我们的页面就会呈现在屏幕上。

    device-dom-small

    让我们来快速回顾一下浏览器处理过程中的每一个步骤:

    1. 处理HTML脚本,生成DOM树
    2. 处理CSS脚本,生成CSSOM树
    3. 将DOM树和CSSOM树合并为渲染树
    4. 对渲染树中的内容进行布局,计算每个节点的几何外观
    5. 将渲染树中的每个节点绘制到屏幕中

    我们的例子页面也许看起来很简单,但是也需要浏览器做一系列计算来呈现出来。读者们觉得当我们修改DOM和CSSOM的时候会发生什么呢?浏览器需要重复上述步骤来确定哪些像素点需要重新进行渲染。

    优化关键渲染路径就是减少上述步骤1至步骤5所花费的总时间。如此,我们才能尽快将内容渲染到屏幕上,缩短初次加载之后每次刷新的时间间隔,以更快的速度展现页面中的交互式内容。

  • 相关阅读:
    jvisualm 结合 visualGC 进行jvm监控,并分析垃圾回收
    linux 查看服务器cpu 与内存配置
    arthas 使用总结
    selinux contexts 安全上下文的临时更改
    Android 8.1 Doze模式分析(五) Doze白名单及Debug方式
    Window 任意窗口置顶软件Window TopMost Control
    Android ApkToolPlus一个可视化的跨平台 apk 分析工具
    SVN Please execute the 'Cleanup' command.
    Android 如何在64位安卓系统中使用32位SO库
    Android cmd命令查看apk是32位还是64位?
  • 原文地址:https://www.cnblogs.com/jymz/p/4398291.html
Copyright © 2011-2022 走看看