WHAT - CSS Animationtion 动画系列(三)- 动画卡顿分析

news2024/10/5 22:23:47

目录

  • 一、背景
  • 二、动画卡顿具体分析
  • 三、具体优化方法
    • 3.1 JavaScript:优化 JavaScript 代码
      • 1. requestAnimationFrame 优化
      • 2. Web Worker
    • 3.2 Style:减少 DOM 操作
    • 3.3 Layout:避免频繁触发布局的动画
    • 3.4 避免强制同步布局事件
    • 3.5 Paint&Composite:GPU加速

一、背景

自 HTML 和 CSS 诞生以来,开发者在项目中经常使用动画来优化视觉效果,提升用户体验和留存,从远古时期 IE6 的各种滤镜到现在的 CSS3、canvas、SVG,愈发复杂的动画效果在即便是硬件性能快速增长的今天,性能问题一直是困扰我们的难题之一,本文旨在探讨影响动画性能的因素并寻找解决的办法。

动画卡顿可能是由多种原因引起的,下面罗列一些常见的分析和解决方法:

  1. 性能问题:动画卡顿通常是因为动画的渲染速度跟不上帧率的要求,导致画面不流畅。这可能是因为代码执行效率低下、大量 DOM 元素操作、复杂的 CSS 样式计算等原因导致的。解决方法包括优化 JavaScript 代码减少 DOM 操作简化 CSS 样式等。

  2. 内存泄漏:内存泄漏可能导致页面卡顿和性能下降。如果页面中有大量的动态生成的元素或者对象没有被正确地释放,会导致内存占用过高,从而影响页面性能。解决方法包括及时释放不再需要的对象和资源避免创建过多的临时对象等。

  3. 浏览器兼容性问题:不同浏览器对动画的处理方式和性能有所差异,某些浏览器可能不支持某些 CSS 或 JavaScript 特性,导致动画在特定浏览器中出现卡顿或者不流畅的情况。解决方法包括使用浏览器兼容性较好的特性、进行兼容性测试和调整等。

  4. 硬件加速:使用硬件加速可以提高动画的性能和流畅度,尤其是在移动设备上。可以通过 CSS 属性 transformopacityfilter 等来触发硬件加速,从而提高动画的渲染速度和流畅度。

  5. 帧率控制:帧率过高可能会导致动画卡顿,特别是在性能较低的设备上。因为虽然高帧率可以提供更流畅的动画效果,但过高时可能会超出系统计算资源的处理能力,导致页面卡顿。可以通过调整动画的帧率来降低 CPU 和 GPU 的负载,从而提高动画的性能和流畅度。

综上所述,要解决动画卡顿问题,首先需要分析问题的根本原因,然后采取相应的优化和调整措施来提高动画的性能和流畅度。

二、动画卡顿具体分析

参考文档:https://jelly.jd.com/exp/detail?id=5dc38940b73b47015299a49c

大多数设备的刷新频率是 60 帧/秒,也就是 1 秒钟的动画是由 60 个画面连在一起生成的,所以一般要求浏览器对每一帧画面的渲染工作要在 16ms 内完成。当渲染时间超出 16ms 时,1 秒钟内少于 60 个画面生成,就会有不连贯、卡顿的感觉,影响用户体验。

一个页面帧在客户端的渲染分为以下几步:

请添加图片描述

  1. JavaScript。实现动画效果、DOM 操作等
  2. Style。确认每个 DOM 元素应用的 CSS 样式规则
  3. Layout。计算每个 DOM 元素最终在屏幕上的大小和位置
  4. Paint。在多个图层上绘制 DOM 元素的文字、颜色、边框和阴影等效果
  5. Composite。按照合理的顺序合并图层并显示在屏幕上

浏览器在实际渲染页面的时候需要经过一系列的映射,由 HTML 页面构建出来的 DOM 树到最终的图层,映射过程如下图所示:

请添加图片描述

  1. Node -> RenderObject。DOM 树的每一个 Node 都有一个对应的 RenderObject(一对一关系)
  2. RenderObject -> RenderLayer。一个或多个 RenderObject 对应一个 RenderLayer(多对一),RenderLayer 用于保证元素之间的层级关系,一般来说位于同一位置且层级相同的元素处于同一个 RenderLayer。只有某些特殊的 RenderObject 会专门创建一个新的渲染层,其他的 RenderObject 与第一个拥有的 RenderLayer 的祖先元素共用一个,比如上图中的 p 元素和其子元素 div。

常见的生成 RenderLayer 的 RenderObject 拥有如下一种特征:

  1. 页面根元素
  2. 有CSS定位属性(relative, absolute, fixed, sticky)
  3. transparent不为1
  4. overflow不为visible
  5. 有CSS mask属性
  6. 有CSS box-reflect属性
  7. 有CSS filter属性
  8. 3D或硬件加速的2D canvas元素
  9. video元素

可以看出,具有上述特征的 RenderObject 会专门生产新的 RenderLayer,图层能够阻⽌该节点的渲染⾏为影响别的节点,即对页面的某些部分进行独立的处理,从而提升渲染性能,⽐如对于 video 标签来说,浏览器会⾃动将该节点变为图层。但 RenderLayer 过多就会影响页面的渲染速度,也会消耗内存资源,因此应该谨慎使用。

可以使用开发者工具来检查页面的图层信息,以便了解哪些部分被设置为图层,以及优化渲染性能。在 Chrome 浏览器中,在右上角更多工具找到图层

  1. RenderLayer -> GraphicsLayer。一个或多个 RenderLayer 对应一个 GraphicsLayer(多对一)。某些被认为是 Compositing Layer 的 RenderLayer 单独对应一个 GraphicsLayer,其他 RenderLayer将与第一个拥有 GraphicsLayer 的祖先元素共用同一个 GraphicsLayer。对于 GraphicsLayer 来说,每一个 GraphicsLayer 有一个 GraphicsContext 用于绘制其对应的 RenderLayers,合成器 Composite 将 GraphicsContexts 的位图(这个将由GPU实现)合成最终显示在屏幕上。

常见的 RenderLayer 会被提升为 Compositing Layer(单独用一个 GraphicsLayer) 的原因:

  1. 有3D transform属性。使用 translate3d(), translateZ(), scale3d(), rotate3d() 等方法来对元素进行 3D 变换
  2. 有perspective属性。设置元素的透视效果
  3. 3D canvas或硬件加速的2D canvas
  4. 硬件加速的iframe元素(如iframe嵌入的页面有合成层,合成层需要硬件加速)
  5. 使用了硬件加速的插件,如flash
  6. 对opacity/transform属性应用了animation/transition(当animation/transition为active)
  7. 子元素是compositing layer
  8. 兄弟元素是compositing layer,与当前的非composting layer有重叠,层级低于当前层
  9. 有will-change属性。明确告知浏览器该元素将会发生变化,可以预先进行优化处理

注意,提升为 Compositing Layer 可以提高页面的渲染速度。

三、具体优化方法

通过上面分析和学习,我们对优化方向已经有了一定着手点。

3.1 JavaScript:优化 JavaScript 代码

1. requestAnimationFrame 优化

关于 WHAT - requestAnimationFrame 介绍 中我们介绍过“对于动画效果,推荐使用 requestAnimationFrame 方法,它可以更有效地与浏览器的绘制周期同步,提供更流畅的动画效果,并且不会出现页面不可见时的执行问题”。

并且在 HOW - 前端定时器实践(含防抖、interval 模拟) 中我们也详细介绍过计时器存在的问题,计时器无法保证回调函数的执行时机,可能会在一帧内一并执行多次导致多次页面渲染,浪费 CPU 资源甚至产生卡顿,或者是在一帧即将结束时执行导致重新渲染,出现掉帧问题。

而使用 requestAnimationFrame:

  1. 更好的函数节流,其循环间隔是由屏幕刷新频率决定的,保证回调函数在屏幕的每一次刷新间隔中只执行一次
  2. 当页面被隐藏或最小化时,暂停渲染

优化效果比较:推荐在 https://codesandbox.io 调试

  <button id="choice-1">setTimeout</button>
  <button id="choice-2">requestAnimationFrame</button>
  <button id="clear">clearAll</button>
  <div id="result"></div>
  // setTimeout 3次渲染
  document.getElementById('choice-1').addEventListener('click', function () {
   
    document.getElementById('result').innerHTML = '';
    var i = 0;
    while (i < 5000) {
   
      var spanNode = document.createElement('span');
      var txt = document.createTextNode('time');
      spanNode.appendChild(txt);
      document.getElementById('result').appendChild(spanNode);
      i += 1;
    }
    setTimeout(function () {
   
      var j = 0;
      while (j < 200) {
   
        console.log(j);
        j += 1;
      }
      while (j > 0) {
   
        var divNode = document.createElement('div');
        var txt = document.createTextNode('1111111');
        divNode.appendChild(txt);
        document.getElementById('result').appendChild(divNode);
        j -= 1;
      }
      setTimeout(function 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1667317.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

查询新加 字段不返回数据要看 有没有 AllInfoResultMap 有要再里面加字段

查询新加 字段不返回数据要看 有没有 AllInfoResultMap 有要再里面加字段

深度学习+计算机视觉

在旷视 这个ai四小龙 深度学习 是必不可少&#xff0c;而且这年头…… 机器学习:在预定义的可能性空间中&#xff0c;利用反馈信号的指引&#xff0c;在输入数据中寻找有用的表示和规则 原理 a. 对神经网络的权重&#xff08;有时也被称为该层的参数&#xff09;进行随机赋值…

MFC的view视图为何不能拖入控件

在MFC中&#xff0c;View类通常用于显示和处理应用程序的数据&#xff0c;而不是直接用于设计用户界面。因此&#xff0c;默认情况下&#xff0c;MFC的View类是不支持在设计时拖动控件的。 MFC中设计用户界面通常使用的是对话框类&#xff08;Dialog&#xff09;或窗口类&…

C++入门必读-Qt的安装与配置

QT简介 Qt是一个跨平台的C图形用户界面应用程序框架。它为应用程序开发者提供建立图形界面所需的所有功能。它是完全面向对象的&#xff0c;很容易扩展&#xff0c;并且允许真正的组件编程。 QT下载 访问下载网站: Index of /archive/qt 安装编译器 QT安装 建议安装之前将网络断…

从关键新闻和最新技术看AI行业发展(2024.4.22-5.5第二十二期) |【WeThinkIn老实人报】

写在前面 【WeThinkIn老实人报】旨在整理&挖掘AI行业的关键新闻和最新技术&#xff0c;同时Rocky会对这些关键信息进行解读&#xff0c;力求让读者们能从容跟随AI科技潮流。也欢迎大家提出宝贵的优化建议&#xff0c;一起交流学习&#x1f4aa; 欢迎大家关注Rocky的公众号&…

Scoop国内安装、国内源配置

安装配置源可参考gitee上的大佬仓库&#xff0c;里面的步骤、代码都很详细&#xff0c;实测速度也很好 glsnames/scoop-installer 也可以结合其它bucket使用 使用Github加速网站&#xff0c;也可以换做其他代理方式&#xff0c;自行测试 例如&#xff1a;https://mirror.ghprox…

点云DBSCAN聚类,同时获取最多点数量的类,同时删除其他的类并显示

代码的主要目的是处理一个点云文件(从某个巷道或类似环境中获取的),并尝试识别并可视化其中的主要结构(比如墙壁),同时去除可能的噪声和异常点。它首先读取一个点云文件,进行降采样和异常点移除,然后使用DBSCAN聚类算法对剩余的点云进行聚类,最后选择并可视化包含最多…

vscode+clangd阅读Linux内核源码

1. 禁用或卸载官方C/C插件. 2. 安装clangd插件 3. 清除之前的产物 4. 生成.config文件 5.编译生成内核镜像 6.编译内核模块 7.编译设备树文件 8.生成compile_commands.json文件 运行上述命令后&#xff0c;在内核源码根目录生成了compile_commands.json文件 9.设置clangd插…

JAVA抽象类,接口与内部类,常用API知识总结

文章目录 抽象类和抽象方法抽象类的定义格式抽象方法的定义格式注意事项 接口定义和使用成员特点和类之间的关系新增JDK8新增方法JDK9新增方法 总结设计模式 内部类使用场景分类成员内部类获取内部类对象访问成员变量 静态内部类局部内部类匿名内部类格式使用场景 示例 常用API…

Java(三)---逻辑控制

文章目录 前言1.逻辑控制语句的分类1.顺序结构2.分支结构2.1.if结构2.1.1.if...else语句2.2.2.if ... else if... else语句 2.2.switch语句 3.循环结构3.1.while3.2.break3.3.continue3.4.for循环3.5.do while循环 4.输入输出4.1.输入到控制台4.2.从键盘输入 前言 前两篇文章&…

数据分析概念定义和发展前景

数据分析概念定义和发展前景 前言一、数据分析概念二、数据的定义数据的定义数据的分类定性数据定量数据 三、数据的价值数据为什么具有价值 四、数据分析的目的对于企业来说总结 五、数据分析类型的划分描述性统计分析探索性数据分析传统的统计分析方法验证性数据分析 六、 数…

240512-关于如何用VSCode编写C#程序的简单说明

240512-关于如何用VSCode编写C#程序的简单说明 从安装软件开始 &#xff0c;到编写一个HelloWorld的C#文件结束&#xff0c;介绍如何用VSCode编写C#程序 1 上官网下载一个安装包 官网地址&#xff1a;https://visualstudio.microsoft.com/zh-hans/downloads/ 2 打开安装包进…

3D分子生成的定制扩散框架 MolDiff - 评测

MolDiff模型是一种考虑分子键生成的3D分子生成的新模型。MolDiff是清华大学智能产业研究院马剑竹课题组发表在PMLR 2023的工作&#xff0c;第一作者是Xingang Peng&#xff0c;文章题目为&#xff1a;《 Addressing the Atom-Bond Inconsistency Problem in 3D Molecule Genera…

计算机毕业设计 | vue+springboot调查问卷管理系统(附源码)

1&#xff0c;研究目的 在进入21世纪以后&#xff0c;互联网得到了蓬勃的发展&#xff0c;电子问卷调查也开始逐渐流行起来。传统纸质问卷和电子问卷相比较后&#xff0c;传统问卷还存在很多弊端&#xff1a; 问卷分发起来比较困难&#xff0c;并且分发试卷耗费大量的金钱和时…

Vue3项目Easy云盘(二):文件列表+新建目录+文件重命名+文件上传

一、文件列表 1.封装全局组件Table.vue 因为Main.vue等都会用到文件列表table&#xff0c;所以直接封装成组件。 src/components/Table.vue <template><!-- 表格 --><div><el-tableref"dataTable":data"dataSource.list || []":h…

关于在ubuntu18.04中运行ORB_SLAM3时遇到的报错:段错误(核心已转储)的解决方法(踩坑记录)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、段错误&#xff08;核心已转储&#xff09;1. 已放弃(核心已转储)(1) 问题描述(2)原因分析 二、解决方法1. 解决方法一2. 解决方法二 总结 一、段错误&#xff…

Vditor集成于VUE笔记

文章目录 前言一、安装Vditor二、渲染markdown三、options3.1 自建CDN3.2 outline大纲不显示、不跳转问题3.3 upload 图片/视频上传3.4 toolbar提示位置点击事件more中文字 3.5 sv分屏渲染模式隐藏编辑框3.6 after中的insertValue或者setValue 前言 Vditor是一款易于使用的 Ma…

大学生体质测试|基于Springboot+vue的大学生体质测试管理系统设计与实现(源码+数据库+文档)

大学生体质测试管理系统 目录 基于Springboot&#xff0b;vue的大学生体质测试管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 3用户功能模块 4教师功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算…

WebRTC实现多人通话-Mesh架构【保姆级源码教程】

一、Mesh架构 WebRTC&#xff08;Web Real-Time Communications&#xff09;中的Mesh架构是一种将多个终端之间两两进行连接&#xff0c;形成网状结构的通信模式。以下是关于WebRTC的Mesh架构的详细解释&#xff1a; 基本概念&#xff1a;在Mesh架构中&#xff0c;每个参与者…

【QT】QT背景介绍

本专栏内容为&#xff1a;QT学习专栏 通过本专栏的深入学习&#xff0c;你可以了解并掌握QT。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;QT &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &#x1f339;&#x1f…