浏览器原理 23 # 分层和合成机制:为什么CSS动画比JavaScript高效?

简介: 浏览器原理 23 # 分层和合成机制:为什么CSS动画比JavaScript高效?

说明

浏览器工作原理与实践专栏学习笔记



显示器是怎么显示图像的


显示器


显示器每秒固定读取 60 次前缓冲区中的图像,并将读取的图像显示到显示器上。

每个显示器都有固定的刷新频率,通常是 60HZ,也就是每秒更新 60 张图片,更新的图片都来自于显卡中一个叫前缓冲区的地方。


显卡


显卡


   显卡(英语:Video card、Display card、Graphics card、Video adapter),是个人电脑最基本组成部分之一,用途是将计算机系统所需要的显示信息进行转换驱动电脑,并提供逐行或隔行扫描信号,控制电脑的正确显示,是连接显示器和个人电脑主板的重要组件,是“人机对话”的重要设备之一。


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


怎么保证显示器能读取到最新显卡合成的图像?


   当显卡把合成的图像写到后缓冲区,系统就会让后缓冲区和前缓冲区互换

通常情况下,显卡的更新频率和显示器的刷新频率是一致的。但有时候,在一些复杂的场景中,显卡处理一张图片的速度会变慢,这样就会造成视觉上的卡顿。



帧 VS 帧率



   帧就是影像动画中最小单位的单幅影像画面。 一帧就是一副静止的画面,连续的帧就形成动画,如电视图像等。 通常说帧数,简单地说,就是在1秒钟时间里传输的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次,通常用FPS(Frames Per Second)表示。每一帧都是静止的图象,快速连续地显示帧便形成了运动的假象。高的帧率可以得到更流畅、更逼真的动画。每秒钟帧数 (fps) 越多,所显示的动作就会越流畅。


帧率(Frame rate)


   帧率(Frame rate)是以帧称为单位的位图图像连续出现在显示器上的频率(速率)。该术语同样适用于胶片和摄像机,计算机图形和动作捕捉系统。帧速率也可以称为帧频率,并以赫兹(Hz)表示。


举个例子:


为什么当你通过滚动条滚动页面,或者通过手势缩放页面时,屏幕上就会产生动画的效果?


   因为在滚动或者缩放操作时,渲染引擎会通过渲染流水线生成新的图片,并发送到显卡的后缓冲区。


如果在一次动画过程中,渲染引擎生成某些帧的时间过久,那么就会感受到页面卡顿,那么怎么处理这种卡顿问题?


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



如何生成一帧图像


在前面的文章渲染流程里面讲过:任意一帧的生成方式,有重排、重绘和合成三种方式


  1. 重排

需要重新根据 CSSOM 和 DOM 来计算布局树,这样生成一幅图片时,会让整个渲染流水线的每个阶段都执行一遍,如果布局复杂的话,就很难保证渲染的效率


20210512160824921.png


  1. 重绘

没有了重新布局的阶段,操作效率稍微高点,但是依然需要重新计算绘制信息,并触发绘制操作之后的一系列操作。


20210512160840137.png


  1. 合成

相较于重排和重绘,合成操作的路径就显得非常短了,并不需要触发布局和绘制两个阶段,如果采用了 GPU,那么合成的效率会非常高。

20210512160851409.png


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



分层和合成


分层和合成通常是一起使用的。


  • 分层:将素材分解为多个图层的操作
  • 合成:将这些图层合并到一起的操作



Chrome 是怎么实现分层和合成机制的?


在 Chrome 的渲染流水线中,分层体现在生成布局树之后,渲染引擎会根据布局树的特点将其转换为层树(Layer Tree)


绘制列表

  • 层树是渲染流水线后续流程的基础结构
  • 层树中的每个节点都对应着一个图层,下一步的绘制阶段就依赖于层树中的节点
  • 绘制阶段其实并不是真正地绘出图片,而是将绘制指令组合成一个列表


比如:下图指向的就是绘制指令列表:


20210512165009751.png


光栅化阶段

光栅化就是按照绘制列表中的指令生成图片。

每一个图层都对应一张图片,合成线程有了这些图片之后,会将这些图片合成为“一张”图片,并最终将生成的图片发送到后缓冲区。


20210512164915369.png


注意:能直接在合成线程中实现的是整个图层的几何变换,透明度变换,阴影等,这些变换都不会影响到图层的内容。

合成操作是在合成线程上完成的,这也就意味着在执行合成操作时,是不会影响到主线程执行的。



分块

合成线程会将每个图层分割为大小固定的图块,然后优先绘制靠近视口的图块,这样就可以大大加速页面的显示速度。


不过有时候, 即使只绘制那些优先级最高的图块,也要耗费不少的时间,因为涉及到一个很关键的因素——纹理上传,这是因为从计算机内存上传到 GPU 内存的操作会比较慢。


为了解决这个问题,Chrome 又采取了一个策略:在首次合成图块的时候使用一个低分辨率的图片。


   比如可以是正常分辨率的一半,分辨率减少一半,纹理就减少了四分之三。在首次显示页面内容的时候,将这个低分辨率的图片显示出来,然后合成器继续绘制正常比例的网页内容,当正常比例的网页内容绘制完成后,再替换掉当前显示的低分辨率内容。




如何利用分层技术优化代码


如果涉及到一些可以使用合成线程来处理 CSS 特效或者动画的情况,就尽量使用 will-change 来提前告诉渲染引擎,让它为该元素准备独立的层。但同时占用的内存也会大大增加,因为从层树开始,后续每个阶段都会多一个层结构。


例子:使用 will-change 来告诉渲染引擎你会对该元素做一些特效变换,CSS 代码如下:

.box {
  will-change: transform, opacity;
}

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



拓展


blinkon:


   https://www.youtube.com/channel/UCIfQb9u7ALnOE4ZmexRecDg


Chromium源码:

  https://chromium.googlesource.com/chromium/src

  https://chromium.googlesource.com/chromium/src/+/master/docs/README.md







目录
相关文章
|
12天前
|
JavaScript 前端开发 Serverless
Vue.js的介绍、原理、用法、经典案例代码以及注意事项
Vue.js的介绍、原理、用法、经典案例代码以及注意事项
27 2
|
19小时前
|
前端开发 开发者 异构计算
CSS进阶-CSS动画关键帧
【6月更文挑战第15天】CSS的`@keyframes`创建细腻动画,定义样式变化阶段以增强网页互动性。通过`animation`属性应用动画,如`fadeIn`示例。常见问题包括动画结束状态、卡顿和浏览器兼容性,解决办法涉及优化关键帧、使用硬件加速和添加前缀。进阶技巧包括多步骤动画和控制播放状态。例如,背景色渐变动画展示了颜色随时间变化的效果。学习和实践关键帧动画,提升Web开发技能。
|
1天前
|
XML 前端开发 JavaScript
前端简介(HTML+CSS+JS)
前端简介(HTML+CSS+JS)
|
4天前
|
前端开发 JavaScript
js遍历添加栏目类添加css,再点击其它删除css
该文章介绍了使用JavaScript遍历添加和删除CSS类的方法。示例代码展示了如何在点击时为当前元素添加类,同时移除其他元素的类。其中包含两个示例:一是遍历`.radio-group .ckselect`并处理点击事件,二是实现点击`.zu-top-nav-userinfo`显示/隐藏`.peoples`层,并处理文档点击以关闭层。代码适用于网页交互效果的实现。
6 0
|
4天前
|
前端开发 安全 数据安全/隐私保护
Web实战丨基于django+html+css+js的在线博客网站
Web实战丨基于django+html+css+js的在线博客网站
10 2
|
4天前
|
数据库 数据安全/隐私保护 Python
Web实战丨基于django+html+css+js的电子商务网站
Web实战丨基于django+html+css+js的电子商务网站
19 3
|
5天前
|
前端开发 JavaScript 开发者
CSS基础-CSS3过渡与动画
【6月更文挑战第11天】本文介绍了CSS3的过渡和动画特性,用于创建平滑的视觉效果。过渡通过`transition`属性实现元素样式改变的缓动效果,常用于按钮悬停、图片切换等场景。易错点包括忘记设置初始和最终样式,以及过渡效果不明显。动画则利用`@keyframes`定义关键帧序列,适用于循环播放的图标旋转等复杂效果。动画的错误可能在于结束状态处理和无限循环的性能问题。通过代码示例和避免常见陷阱,开发者能更好地利用CSS3动画提升网页交互体验。关键在于适度使用,保持界面流畅舒适。
|
10天前
|
缓存 自然语言处理 前端开发
深入剖析JavaScript引擎的工作原理
【6月更文挑战第3天】JavaScript引擎由解析器、解释器、优化器和垃圾回收器组成,它们协同完成代码的解析、编译和执行。解析器将源代码转为抽象语法树(AST),编译阶段进行作用域分析和变量提升。解释器执行AST,优化器在代码频繁执行时进行即时编译以提高性能。垃圾回收器自动回收不再使用的内存,防止泄漏。理解这些原理有助于优化代码和提升Web应用性能。
10 1
|
10天前
|
移动开发 前端开发 JavaScript
[初学者来练]用html+css+javascript个人博客作业需求
【6月更文挑战第3天】该项目旨在通过HTML、CSS和JavaScript创建一个响应式个人博客网站,提升前端开发技术理解与实践能力。主要包括设计简洁页面布局、实现主页展示、文章列表、详情页及评论功能。技术要求使用HTML5/CSS3/JavaScript,可选前端框架,强调代码质量和可维护性。提交内容需包括完整网站、开发文档和测试过的代码。评分标准涉及设计、功能实现、技术应用和文档质量。
12 0
|
10天前
|
JavaScript 前端开发 网络协议
浏览器的工作原理
主要分为导航、获取数据、HTML解析、css解析、执行javaScript、渲染树几个步骤。
16 1