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

目录

  • 一、背景
  • 二、动画卡顿具体分析
  • 三、具体优化方法
    • 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 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

十一、Redis持久化-RDB、AOF

Redis提供了两种持久化数据的方式。一种是RDB快照&#xff0c;另一种是AOF日志。RDB快照是一次全量备份&#xff0c;AOF日志是连续的增量备份。RDB快照是以二进制的方式存放Redis中的数据&#xff0c;在存储上比较紧凑&#xff1b;AOF日志记录的是对内存数据修改的指令文本记录…

c++ 入门2

目录 五. 函数重载 1、参数类型不同 2、参数个数不同 3、参数类型顺序不同 C支持函数重载的原理--名字修饰(name Mangling&#xff09; 为什么C支持函数重载&#xff0c;而C语言不支持函数重载呢&#xff1f; 六. 引用 6.1 概念 6.2 引用特性 6.3 常引用 6.4 使用场景 …

网络基础-ICMP协议

ICMP&#xff08;Internet Control Message Protocol&#xff0c; Internet控制消息协议&#xff09; ICMP协议是IP协议的辅助协议&#xff0c;用于在IP网络上发送控制消息&#xff0c;它通常被用于诊断网络故障、执行网络管理任务以及提供一些错误报告&#xff1b;对于收集各…

【MySQL】SQL基本知识点DML(2)

目录 1.DML添加数据 2.DML-修改数据 &#xff08;1&#xff09;改​编辑 &#xff08;2&#xff09;删​编辑​编辑 3.DQL-基本查询 &#xff08;1&#xff09;查询多个字段​编辑​编辑​编辑 &#xff08;2&#xff09;设置别名 &#xff08;3&#xff09;去重操作 4…

别的项目都有 awesome 仓库,RT-Thread 也要有!

awesome 仓库是 GitHub 上用于收集某个项目或者某个语言相关的优质内容的仓库&#xff0c;例如中间件、新闻资讯、网站等。 作为 RT-Thread 开发者&#xff0c;看到别的项目都有 awesome 仓库&#xff0c;我想 RT-Thread 也应该有&#xff01; 于是&#xff0c;我创建一个 aw…

【Python基础】装饰器(3848字)

文章目录 [toc]闭包什么是装饰器装饰器示例不使用装饰器语法使用装饰器语法 装饰器传参带参数的装饰器类装饰器魔术方法\__call__()类装饰器示例带参数类装饰器property装饰器分页操作商品价格操作 个人主页&#xff1a;丷从心 系列专栏&#xff1a;Python基础 学习指南&…

从0开始学python(七)

目录 前言 1 break、continue和pass函数 1.1 break 1.2 continue 1.3 pass 2、序列的索引及切片操作 2.1字符串的索引和切片 2.1.1 字符串索引 2.1.2 字符串切片 总结 前言 上一篇文章我们介绍了python中的循环结构&#xff0c;包括for和while的使用。本章接着往下讲。…

中仕公考:要报深圳教师编的考生们要注意了,往届、应届都可报!

2024上半年广东深圳市(区)属公办中小学教师招聘公告已发布 5月13日10:00至5月17日17:00报名&#xff0c;6月2日笔试。

基于SSM+Vue的物流管理系统

运行截图 获取方式 Gitee仓库

智慧公厕解决了什么问题?

在现代城市生活中&#xff0c;公厕是一个不可忽视的环节。然而&#xff0c;过去的公共厕所常常存在管理不力、环境脏乱差等问题&#xff0c;给人们的生活带来了许多不便和困扰。为了解决这些问题&#xff0c;智慧公厕应运而生&#xff0c;成为了公共厕所使用、运行、管理、养护…

Linux-进程管理类命令实训

实训1&#xff1a;进程查看&#xff0c;终止&#xff0c;挂起及暂停等操作 1.使用ps命令显示所有用户的进程 2.在后台使用cat命令。查看进程cat&#xff0c;并杀死进程 3.使用top命令只显示某一用户的进程。 4.执行命令cat&#xff0c;把Ctrlz挂起进程&#xff0c;输入jobs命令…

Excel办公技巧之下拉菜单

在日常办工中&#xff0c;经常需在单元格中输入特定的值&#xff0c;此时我们可以使用下拉菜单解决&#xff0c;输入错误和错误值&#xff0c;可以一劳永逸的解决固定数据输入问题。 使用Excel下拉菜单时&#xff0c;它在数据输入和验证方面发挥着重要作用通过点击单元格的下拉…

时序分解 | Matlab实现LMD局域均值分解

时序分解 | Matlab实现LMD局域均值分解 目录 时序分解 | Matlab实现LMD局域均值分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 时序分解 | Matlab实现LMD局域均值分解 Matlab语言 1.算法新颖小众&#xff0c;用的人很少&#xff0c;包含分解图 2.直接替换数据即可用…

iOS 安装cocoapds

注意 CocoaPods安装是基于ruby环境的&#xff0c;所以要安装CocoaPods先要安装Ruby环境&#xff0c;国内不能直接安装&#xff0c;只能通过VPN或淘宝的Ruby镜像来访问。 安装过程 gem sources --remove https://rubygems.org/ ** (注意是两个“-”&#xff0c;否则会移除失败) …

【分立元件】一起读读10/100 Base-T网络变压器规格书

网络变压器亦称为网络隔离变压器或数据泵。广泛应用于太网交换机、路由器、网络机顶盒、智能电视、网络摄像机、网络刻录机、笔记本电脑、无线AP、智能网关等设备,起到信号耦合、高压隔离、阻抗匹配、波形修复、电磁干扰抑制等作用。 下面我们一起读一读网络变压器规格书,来看…

计算机网络实验3:路由器安全防控配置

实验目的和要求 理解标准IP访问控制列表的原理及功能理解CHAP、DHCP配置原理了解家用式无线路由配置方法实验项目内容 标准IP访问控制列表配置 CHAP验证路由器上配置DHCP网络地址转换NAT配置无线路由实现实验环境 1. 硬件&#xff1a;PC机&#xff1b; 2. 软件&#xff1a;W…

CCPD车牌检测识别数据集

CCPD 是一个在开源免费的中国城市车牌识别数据集。 1. 介绍 CCPD (Chinese City Parking Dataset, ECCV)是中国城市车牌数据集&#xff0c;共有两个CCPD2019和CCPD2020 数据集&#xff0c;总数据量约35W左右&#xff0c;可用于车牌检测和识别模型算法开发。 CCPD 发表的论文:…

该从哪些方面提升系统的吞吐量?

更多大厂面试内容可见 -> http://11come.cn 该从哪些方面提升系统的吞吐量&#xff1f; 我们平时自己做的项目一般没有用户量&#xff0c;都是练手项目&#xff0c;所以并不会在吞吐量上做出很多的优化&#xff0c;但是这样的话&#xff0c;又会导致项目和其他人相比并没有…

找不到d3dx9_42.dll无法继续执行代码的原因分析及解决方法

当您在使用电脑过程中遇到提示“缺少d3dx9_42.dll”时&#xff0c;这实际上是操作系统在运行某些应用程序或游戏时遇到的一个常见问题。D3DX9_42.dll是DirectX 9的一部分&#xff0c;DirectX是一组由微软开发的多媒体处理软件组件&#xff0c;广泛用于提升游戏与多媒体程序的性…

【Python项目】高校社团学生会管理系

技术简介&#xff1a;使用Django框架、MYSQL数据库、JS技术、XCode等实现。 系统简介&#xff1a;PYTHON高校社团管理系统的功能需求总体而言可以分为不同的角色&#xff0c;管理员主要包括&#xff1a;社团信息管理、社团活动管理、社团报名管理、留言板、社团会员管理及管理员…