文章      动态     相关文章     最新文章     手机版动态     相关动态     |   首页|会员中心|保存桌面|手机浏览

3i225

http://sjzytwl.xhstdz.com/com3i225/

相关列表
文章列表
  • 暂无文章
推荐文章
【前端】浏览器展示页面的渲染流程,重排、重绘和合成
发布时间:2024-12-21        浏览次数:16        返回列表

【前端】浏览器展示页面的渲染流程,重排、重绘和合成

  1. 输⼊HTML⽂件,由HTML解析器解析,输出树状结构的DOM。
  1. 渲染引擎接收到CSS⽂本,执⾏转换操作,将CSS⽂本转换为浏览器可以理解的结构——styleSheets。该结构同时具备了查询和修改功能,这会为后⾯的样式操作提供基础

  2. 对styleSheets中样式的属性值标准化,使浏览器能读懂。

  3. 样式计算阶段遵守CSS的继承和层叠两个规则计算出DOM节点中每个元素的具体样式,最终输出每个DOM节点的样式保存在ComputedStyle的结构内。

  1. 构建布局树: 遍历DOM树种所有可见节点,将他们加到布局中。

  2. 布局计算:计算布局树节点的坐标位置。

  1. 生成图层:元素有了层叠上下⽂的属性或者需要被剪裁,满足这任意⼀点,就会被提升成为单独⼀层。

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

绘制列表只是用来记录绘制顺序和绘制指令的列表,而实际上绘制操作是由渲染引擎中的合成线程来完成的,当图层的绘制列表准备好之后主线程会把该绘制列表提交(commit)给合成线程

  1. 合成线程会将图层划分为图块(tile

通常一个页面可能很大,但是用户只能看到其中的一部分,我们把用户可以看到的这个部分叫做视口(viewport

  1. 线程将视口附近的图块来优先生成位图,将图块转换为位图实现栅格化。

    渲染进程维护了⼀个栅格化的线程池,所有的图块栅格化都是在线程池内执⾏的,通常,栅格化过程都会使⽤GPU来加速⽣成,那么最终⽣成位图的操作是在GPU中完成的,这就涉及到了跨进程操作。

    渲染进程把生成图块的指令发送给GPU进程,然后在GPU中执行生成图块的位图,并保存在GPU的内存中。

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

  2. 绘制:浏览器进程里叫viz的组件,接收合成线程发过来的“DrawQuad”命令,然后根据“DrawQuad”命令,将其页面内容绘制到内存中,最后再将内存显示在屏幕上。

有了上面介绍渲染流水线的基础,我们再来看看三个和渲染流水线相关的概念⸺“重排”“重绘”和“合成”。

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

显卡的职责就是合成新的图像,并将图像保存到后缓冲区中,⼀旦显卡把合成的图像写到后缓冲区,系统就会让后缓冲区和前缓冲区互换,这样就能保证显⽰器能读取到最新显卡合成的图像。

显卡的职责是合成新图像,保存到后缓冲区中。

显示器

每个显⽰器都有固定的刷新频率,通常是60HZ,也就是每秒更新60张图⽚,更新的图⽚都来⾃于显卡中⼀个叫前缓冲区的地⽅,显⽰器所做的任务很简单,就是每秒固定读取60次前缓冲区中的图像,并将读取的图像显⽰到显⽰器上。

显示器使用固定的刷新频率(一般为60HZ)读取显卡中的前缓冲区图片,将其更新到显示器上。

1.显卡按60HZ频率合成新图像–图像保存到后缓冲区中

2.显示器按60HZ频率读取前缓冲区图片–显示到显示器上

与此同时,系统会不断互换前后缓冲区

显卡的更新频率和显示器的刷新频率是一致的。显卡处理图片变慢会视觉上卡顿。

我们把渲染流水线生成的每一副图片称为一帧,把渲染流水线每秒更新了多少帧称为帧率。

要解决显示卡顿问题,就要解决每帧生成时间过久的问题,为此Chrome对浏览器渲染⽅式做了大量的工作,其中最卓有成效的策略就是引入了分层和合成机制。分层和合成机制代表了当今最先进的渲染技术。

关于其中任意⼀帧的生成方式,有重排重绘合成三种方式。

这三种方式的渲染路径是不同的,通常渲染路径越长,生成图像花费的时间就越多。

Chrome中的合成技术,可以⽤三个词来概括总结:分层、分块和合成。

将素材分解为多个图层的操作就称为分层,最后将这些图层合并到⼀起的操作就称为合成。

需要重点关注的是,合成操作是在合成线程上完成的,这也就意味着在执⾏合成操作时,是不会影响到主线程执⾏的。

在写Web应⽤的时候,你可能经常需要对某个元素做⼏何形状变换、透明度变换或者⼀些缩放操作,如果使⽤Javascript来写这些效果,会牵涉到整个渲染流⽔线,所以Javascript的绘制效率会非常低下。
这时你可以使⽤ will-change来告诉渲染引擎你会对该元素做⼀些特效变换,CSS代码如下

 

这段代码就是提前告诉渲染引擎box元素将要做⼏何变换和透明度变换操作,这时候渲染引擎会将该元素单独实现⼀帧,等这些变换发生时,渲染引擎会通过合成线程直接去处理变换,这些变换并没有涉及到主线程,这样就大大提升了渲染的效率。这也是CSS动画比Javascript动画高效的原因。