浏览器渲染原理-绘制阶段

256 阅读2分钟

流程总览

布局阶段得到布局树,其中包含各个渲染对象的位置、几何、样式等信息。

布局树为绘制阶段的输入数据,将布局树转化为屏幕像素的一个过程

绘制阶段分为4个部分

  1. 构建展示列表
  2. 分层
  3. 光栅化
  4. 合成

image.png

构建展示列表

展示列表通过遍历布局树得到。

每个列表项都是一组绘制指令集,记录着元素的矩形、文本、图像等。

整个列表构成一组高级指令集合,记录绘制顺序。

分层

根据展示列表的渲染先后顺序,以及特殊布局样式属性,实现分层

  • z-index
  • position absolute fixed
  • opacity
  • transform 3D转换

分层后的数据结构参考:

const layerTree = {
  type: 'root',
  children: [
    {
      type: 'layer',
      element: '.container',
      position: { top: 0, left: 0 },
      size: { width: 400, height: 300 },
      backgroundColor: 'lightgray',
      children: [
        {
          type: 'layer',
          element: '.box',
          transform: 'translateZ(0)',
          position: { top: 50, left: 50 },
          size: { width: 100, height: 100 },
          backgroundColor: 'lightblue',
          children: []
        },
        {
          type: 'node',
          element: '.text',
          position: { top: 200, left: 100 },
          content: 'Hello, World!',
          style: {
            color: 'darkred',
            fontSize: '20px'
          }
        }
      ]
    }
  ]
};

重点参考其中每个节点的type属性,如果为root,表示是根级,会创建一个层级;如果为layer,表示此层及其之后的子孙层级存在独立的层级(相对此层级的父级);如果为node,则其层级和它的父级在同一层级(不分层)。

光栅化

分层后得到一个标记层级关系的分层树,每一个分层都会独立进行光栅化。

光栅化是将图层转化为位图(矢量图像转化为图像像素网格)。

位图包含屏幕各个位置的展示样式(颜色)。

合成

通过光栅化,能够得到每个层级在屏幕中的像素样式,但布局树中存在多个图层,它们存在渲染先后顺序,每个层级在每一个像素点都有一个独立的展示样式,但屏幕只有一个像素点,需要展示哪一个层级呢?这就是合成需要做的事。

每个层级按照先后顺序依次从上到下合成,这是一个覆盖的过程(opacity需要特殊计算样式),得到屏幕每个像素样式。

整个屏幕的像素样式缓存到GPU中,由GPU映射渲染到物理屏幕的每个像素点。