浏览器渲染过程详解

1.RenderObject(绘制可见内容的实体)

  • RenderObject上实现了将对应DOM节点绘制进位图的方法,负责绘制DOM节点可见内容

因为有层的覆盖

2.RenderObject 生成 RenderLayer 的条件(定义层的单位)

  • 每个RenderLayer的子Layer放在两个升序列表

    • negZOrderList储存z-index为负的renderLayer
    • posZOrderList储存z-index为正的renderLayer
  • 根元素

  • 明确的 CSS 定位属性(relative,absolute,transform)

  • 是透明的(transparent)

  • 有 overflow,alpha mask 遮罩,reflection

  • CSS filter

  • 有 3D 上下文或者加速 2D 上下文的画布(canvas)

  • video 元素


因为动画需要快速绘制,单独提取

3.RenderLayer 生成 Graphics Layer(合成层)

  • 3D或透视变换(perspective,transform)
  • 使用加速视频解码的元素
  • 拥有3D上下文或者加速2D上下文
  • 混合插件(flash)
  • 对opacity,transform,fliter,backdropfilter应用了动画或者渐变
  • will-change设置为opacity,transform,top,left,bottom,right
  • 拥有加速CSS过滤器的元素
  • 拥有低z-index且包含一个复合层的兄弟元素
  1. 将不需要特殊处理能合成的直接合成一个 renderLayer
  2. 将不能被直接合成的多个静态 renderLayer 特殊处理后合成为一个 Graphics Layer
  3. 将静态的 Graphics Layer 和动态的 Graphics Layer 进行动静合成成最终的合成

  • Graphics Layer负责将自己的Render Layer及其子代所包含的Render Object绘制到位图里。然后将位图作为纹理交给GPU。所以现在GPU收到了HTML元素的Graphics Layer的纹理,也可能还收到某些因为有3d transform之类属性而提升为Graphics Layer的元素的纹理.
  • 现在GPU需要对多层纹理进行合成(composite),同时GPU在纹理合成时对于每一层纹理都可以指定不同的合成参数,从而实现对纹理进行transform、mask、opacity等等操作之后再合成,而且GPU对于这个过程是底层硬件加速的,性能很好。最终,纹理合成为一幅内容最终draw到屏幕上.

4. 具体实现

  1. 相关进程
  • 渲染进程:每个tab一个,负责执行js和页面渲染
    • 主线程(Main Thread)
    • 合成器线程(Compositor Thread)
    • 瓦片工人线程(Tile Worker)
  • GPU进程:整个浏览器一个,负责将Render进程绘制好的瓦片位图作为纹理上传到GPU,并调用GPU相关方draw到屏幕上
    • GPU线程(GPU Thread)
  1. 相关线程工作
  • 主线程
    JS执行,重新计算样式,更新层树,写进位图,合成层

  • 合成器线程
    接受浏览器发出的垂直同步信号,也接受OS传来的用户交互(滚动,输入,点击)

  • 如果可能,合成器线程会自己处理这些内容,转换为对layer的位移和处理,并将新的帧commit到GPU线程,直接输出页面
  • 如果你在滚轮事件注册了回调,这时合成器线程就会唤醒主线程,让后者执行JS,完成DOM的计算重排,产出新的纹理,再commit到GPU Thread
  • 瓦片线程
    由Compositor 线程创建,专门将瓦片光栅化
  1. 整体流程

  2. 接收到Vsync信号,新的一帧开始

  3. 合成器线程将之前接收到的用户UI交互传给主线程处理
    限定每帧一次

  4. requestAnimationFrame

  5. parse HTML dom变动解析dom

  6. Recalc Styles 重新计算样式

  7. Layout重排,

  8. update layer tree
    处理层变动

  9. Paint
    记录哪些绘画调用,放进一个列表

  10. 主线程计算各种混合参数并把数据交给合成器线程,接着处理input回调

  11. Raster Scheduled and Rasterize
    光栅化

  12. commit
    所有瓦片被光栅化后,合成器线程就会commit到GPU线程,GPU线程把位图作为纹理上到到GPU里,并调用平台对应3DAPI把所有纹理绘制到一个位图里,从而完成纹理的合并

5.具体细节

  1. 重排,强制重排
    大小位置改变会触发重排,如果在标记为dirty的情况下访问了offsetTop等属性就会强制重排

  2. 重绘
    以合成层为单位

你可能感兴趣的:(浏览器渲染过程详解)