前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浏览器渲染(线程视角2)

浏览器渲染(线程视角2)

原创
作者头像
醉酒鞭名马
发布2020-05-24 21:47:23
1.9K0
发布2020-05-24 21:47:23
举报

上篇文章介绍了渲染进程主线程上DOM构建的过程,此篇文章将介绍样式计算、布局树、分层树、绘制、合成、显示

渲染流水线
渲染流水线

样式计算(Recalculate Style)

样式计算主要目的是计算出dom各个节点的样式,计算样式需要经过如下三个步骤:

  • 结构转换:css文件主要有三中数据来源,通过link引用的css文件、style标签内、通过style属性引入,类似于html文档转换成dom树一样,css文件也要转换成浏览器可以理解的styleSheets,如下图就是最终的结构化styleSheet表
styleSheets
styleSheets
  • 属性值标准化:将样式表的属性值进行标准化处理,例如将颜色,单位转换成同一的标准值,如下图的颜色,最终转换为rgb

属性值计算
属性值计算
  • 计算节点的样式:根据css继承和层叠样式规则来算出dom每个节点的样式,如果节点没有写任何样式,将继承浏览器默认的节点样式,如下图是计算最终得到的节点样式:
层叠样式集成
层叠样式集成

布局阶段(Layouttree)

布局就是计算出DOM树中可见元素的几何位置,布局要经过如下操作:

  • 创建布局树:遍历DOM树中的可见节点,把节点添加到布局树中,不可见节点忽略
  • 布局计算:将节点对应的styleSheet对象合并,计算出展示节点的样式具体样式
生成布局树
生成布局树

分层阶段(Layertree)

页面中有很多复杂的效果,例如内容溢出滚动、3D动画、定位z-index等,为了更加方便的实现这些效果,渲染引擎需要为特定的节点生成专用的图层,把图层组合起来就是一颗图层树,元素被提升为单独一层需要具备如下两个条件:

分层
分层
  • 拥有层叠上下文属性的元素会被单独提升为一层,例如z-index,opacity,filter,positon
  • 内容溢出、需要裁剪的元素导致出现的滚动条也需要被提升为单独一层

图层
图层

图层绘制(Paint)

分成树生成后,渲染引擎会创建绘制列表,进行图片绘制,过程如下:

绘制列表
绘制列表
  • 创建绘制列表:将绘制指令按照顺序创建绘制列表
  • 栅格化(将图块转换为位图):当图层绘制列表准备好后,主线程会把该绘制列表提交给合成线程,合成线程将图层划分为图块(tile),图块的大小通常为256*256,或者512*512,合成线程会优先视口附近的图块生成位图,生成位图的操作有栅格化线程池完成。栅格化过程会使用GPU加速生成位图,生成的位图保存在GPU内存中

视口、图层、图块
视口、图层、图块

合成阶段(Draw quad指令)

所有的图块被光栅化转化为位图后,合成线程会生成一个绘制图块的命令DrawQuad,然后该指令提交给浏览器进程,浏览器接收到DrawQuad命令,从GPU内存中读取图片输出到显卡后缓冲区,显卡将后缓冲区内容交换至前缓冲区,由屏幕已60HZ的频率刷新显示图片

显示图像(Display)

看下渲染引擎的图像是如何显示到显示器的,先来看下如下概念

  • 帧、帧率:渲染流水线生成一张图片为一帧,每秒渲染帧数称为帧率,如果每秒帧率为60,则为60FPS,
  • 显卡:显卡的职责就是合成新的图像,并将图像保存在后缓冲区,显卡中维护了两块区域,前缓冲区和后缓冲区。
  • 前缓冲区:显示器都由固定的刷新频率,通常是60HZ,也就是每秒刷新60张图片,更新的图片都来自于显卡的前缓冲区,显示器固定每秒60次的读取速度读取前缓冲区的图像,并显示在显示器上。
  • 后缓冲区:一旦显卡把合成的图像保存到后缓冲区,后缓冲区和前缓冲区交换,当滚动或缩放时,渲染引擎通过渲染流水线产生图片并发送到显卡的后缓冲区,显示器刷出图像,显卡更新的频率和显示器刷新频率是一致的,但复杂场景,会出现显卡处理一张图片的速度变慢,造成视觉卡顿

总结

本节主要介绍渲染流程样式计算、布局、分层、绘制、合成及最终显示输出

  • 样式计算:css文件主要来源于link引入,style插入,和行内style属性,渲染引擎解析到css时,要先将其转化为浏览器可以理解的styleSheet结构,转换过程需要经过属性值得标准化过程,和继承层叠规则计算出每个dom节点的样式,styleSheet也为之后js脚本提供操作接口
  • 布局:布局阶段将dom树与样式表styleSheet进行合并计算出最终展示的节点的样式和内容
  • 分层:当界面内元素出现层叠上下文属性时,并且出现了内容溢出,需要裁剪出现滚动条时,就会提升为独立的一层,用层来优化渲染合成图片的速度
  • 绘制:当分层树生成后,渲染引擎会创建绘制列表,绘制的过程中需要使用合成线程来完成
  • 分块:合成线程会将图层划分为图块,视口附近的图块会优先进行合成
  • 栅格化:图块是栅格化的最小单位,将图块生成位图的操作称为栅格化,渲染进程维护了栅格化线程池,来完成图块到位图的转换,在栅格化过程中,还用到了GPU进程来加速位图的生成,使用GPU生成位图保存在GPU内存中,这个过程为快速栅格化的过程。
  • 发出Draw Quad指令:所有图块被光栅化转化为位图后,合成线程会生成一个绘制图块的命令DrawQuad发送给浏览器进程。
  • 输出显示:浏览器进程将图像发送给显卡的后缓冲区,后缓冲区和前缓冲区不断的交替使用,已到达显示器60HZ的速率刷出图像

完。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 样式计算(Recalculate Style)
  • 布局阶段(Layouttree)
  • 分层阶段(Layertree)
  • 图层绘制(Paint)
  • 合成阶段(Draw quad指令)
  • 显示图像(Display)
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档