提高JavaScript动画的性能

在本文中,我收集了一些开发技巧,以帮助您解决JavaScript动画的性能问题,并使您更容易实现在web上实现流畅移动的60fps(每秒帧数)目标。

1、避免使用昂贵的CSS属性

你是否打算使用CSS动画CSS属性转换/ CSS关键帧或JavaScript,重要的是要知道哪些属性带来的改变页面的几何(布局)——这意味着页面上的其他元素的位置将会重新计算,或将涉及绘画操作。布局和绘制任务对于浏览器来说都是非常昂贵的,特别是当你的页面上有几个元素时。因此,如果您避免对触发布局或绘制操作的CSS属性进行动画化,并坚持使用诸如转换和不透明度之类的属性,那么您将看到动画性能的显著提高,因为现代浏览器在优化这些属性方面做得非常出色。

在CSS触发器上,您将找到CSS属性的最新列表,其中包含了它们在每个现代浏览器中触发的工作的信息,包括第一次更改和随后的更改。

更改仅触发复合操作的CSS属性是优化web动画性能的一个简单而有效的步骤。

2、提升你想要的元素到他们自己的层(谨慎)

如果您想要动画的元素在它自己的compositor层上,一些现代浏览器通过将工作卸载到GPU来利用硬件加速。如果使用得当,这个动作可以对动画的表现产生积极的影响。

要将元素放在自己的层上,您需要对其进行升级。一种方法是使用CSS will-change属性。这个属性允许开发人员警告浏览器他们想要在一个元素上做出的一些更改,这样浏览器就可以提前进行必要的优化。

然而,并不是建议你在他们自己的层面上推广太多的元素,或者你是夸大其词。事实上,浏览器创建的每个层都需要内存和管理,这可能会很昂贵。

在Nick Salloum的CSS will-change属性介绍中,您可以了解如何使用will-change的细节、它的优点和缺点。

3、用requestAnimationFrame替换setTimeOut/setInterval

JavaScript动画通常使用setInterval()或setTimeout()方法。

代码像是这样的:

var timer;function animateElement() {
  timer = setInterval( function() {
    // animation code goes here
  } , 2000 );}// To stop the animation, use clearIntervalfunction stopAnimation() {
  clearInterval(timer);}

虽然这是可行的,但是jank的风险很高,因为回调函数在帧中的某个点(可能在最后)运行,这可能导致丢失一个或多个帧。现在,您可以使用一个为流畅的web动画(DOM animation, canvas等)定制的本地JavaScript方法,称为requestAnimationFrame()。

requestAnimationFrame()在最适合浏览器的时间执行动画代码,通常在框架的开始。

你的代码可以是这样的:

function makeChange( time ) {
  // Animation logic here

  // Call requestAnimationFrame recursively inside the callback function
  requestAnimationFrame( makeChange ):}// Call requestAnimationFrame again outside the callback functionrequestAnimationFrame( makeChange );

4、将事件与代码中的动画分离

以每秒60帧的速度,浏览器在每一帧上都有16.67ms来完成它的工作。这并不是很多时间,所以保持代码的精确性会对动画的流畅性产生影响。

将处理诸如滚动、调整大小、鼠标事件等事件的代码与使用requestAnimationFrame()处理屏幕更新的代码分离开来,是优化动画代码以提高性能的好方法。

5、避免长时间运行的JavaScript代码

浏览器使用主线程运行JavaScript,以及其他任务,如样式计算、布局和绘制操作。长时间运行的JavaScript代码可能会对这些任务产生负面影响,这可能导致帧被跳过,并导致janky动画。因此,简化代码肯定是确保动画平稳运行的好方法。

对于不需要访问DOM的复杂JavaScript操作,可以考虑使用Web worker。工作线程执行任务时不会影响用户界面。

6、利用浏览器的DevTools来控制性能问题

您的浏览器的开发工具提供了一种方法来监控您的浏览器在运行JavaScript代码或第三方库的过程中有多困难。它们还提供有关帧速率和更多的有用信息。

您可以通过右键单击web页面并在上下文菜单中选择Inspect来访问Chrome DevTools。

例如,使用性能工具记录web页面将使您了解该页面上的性能瓶颈:

点击录制按钮,几秒钟后停止录制:

此时,您应该有大量的数据来帮助您分析页面的性能:

Chrome DevTools指南将帮助您充分利用DevTools来分析性能,并在您的Chrome浏览器中提供大量其他类型的数据。如果Chrome不是你选择的浏览器,那也没什么大不了的,因为现在大多数浏览器都有超强大的DevTools,你可以利用它们来优化你的代码。

7、使用屏幕外的画布进行复杂的绘图操作

这个技巧与优化HTML5 Canvas的代码有关。

如果您的框架涉及复杂的绘图操作,那么一个好主意是创建一个屏幕外的画布,您在其中执行所有的绘图操作一次或仅当发生更改时,然后在每个框架上绘制屏幕外的画布。

结论

为性能优化代码是一项必要的任务,但它绝不总是简单或直接的。你的动画效果不佳可能有几个原因,但如果你尝试一下上面列出的技巧,你将会在很大程度上避免最常见的动画性能陷阱,从而改善你的网站或应用的用户体验。

原文发布于微信公众号 - 程序你好(codinghello)

原文发表时间:2018-06-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏极乐技术社区

『教程』微信小程序--图片相关问题合辑

最近有注意到,很多同学在社区求助图片上传、加载、效果处理等相关的问题,这期专程做这样一个汇总供大家学习参考。 图片上传相关文章 微信小程序多张图片上传功能 微信...

1.1K10
来自专栏移动开发

小trick之tools

以前写布局时为了观看布局效果,会写些静态的测试数据,以便在androidstudio中观察布局的效果.等到写完布局的时候在进行擦除.当布局很多的时候,这确实也是...

1102
来自专栏知晓程序

开发 | 餐饮小程序必备!教你轻松做出像「饿了么」一样的点餐界面

许多购物、外卖小程序,都会做「分栏」设计,即在左侧展示商品分类、右侧展示分类下的具体商品。

1284
来自专栏xingoo, 一个梦想做发明家的程序员

JQuery向导插件Step——第一个阉割版插件

如果使用过JQuery Steps的朋友一定会发现这个插件有一个缺点,就是页面在第一次进入的时候,会进行一次很明显的DOM重绘——页面会闪一下。 尤其是前端...

3847
来自专栏河湾欢儿的专栏

03-保存

存储所需内容 ctrl+c ctrl+n ctrl+v 或者直接拖动文件至新文件

902
来自专栏前端知识分享

第81天:jQuery 插件使用方法

在追求页面互动效果的时代,大家都想把页面效果做的美轮美奂,这一切都离不开前端技术脚本Javascript,而最近常被人用到的Javascript库文件则是jQu...

1102
来自专栏V站

javascript实现background 定时循环随机背景图

这里用的固定地址,用的新浪图床,喜欢的话可以自己扩充图片,我这里简短的展示了10个图片!

1663
来自专栏小程序之家

如何在小程序中实现音频播放

在如何使用小程序媒体组件这篇文章中,我们介绍了小程序媒体组件的使用,但是对音频组件部分讲的不够详细,本文将对音频部分做些补充。

3.7K1
来自专栏编程微刊

小程序点击轮播图跳转到tab导航界面

一切准备好之后,在wxml文件里面,我们要使用 bindtap在图片上绑定一个事件,在js里面写事件函数的具体操作。

2992
来自专栏日常学python

用python来给图片加水印

有时候我想在图片上添加自己的水印来防止别人盗图,所以今天给大家分享如何用python给我们的图片添加上水印。我们先来看看效果。

1413

扫码关注云+社区

领取腾讯云代金券