使用JS和DOM设置多个DIV元素的动画会导致低帧率

Animating multiple DIV-Elements with JS and the DOM results in a low Framerate

本文关键字:动画 帧率 元素 DIV JS DOM 设置 使用      更新时间:2023-09-26

前言

我刚开始用javascript编程,目前正在做我的这个业余网站项目。该网站应该显示充满产品图像的页面,这些图像可以向左或向右"平移"。每个"页面"包含大约24张中等大小的图片,一页几乎完全填满了整个屏幕。当用户选择查看下一个页面时,他需要单击左侧的"拖动"(例如(,让一个新页面(通过AJAX脚本动态加载(滑入视图。

问题

这需要我的javascript将其中两个提到的页面同步"滑动"一个屏幕的宽度。这导致了非常低的帧速率。Firefox和Opera有点滞后,Chrome尤其糟糕:一帧动画大约需要100毫秒,因此使动画看起来非常"滞后"。

我不使用jQuery,也不想使用它或任何其他库来"为我做工作"。至少在我确信我要做的事情不是用几行自己编写的代码就能完成的之前。

到目前为止,我已经发现操作DOM的特定方式会导致性能下降。程序如下:

function slide() {
  this.t = new Date().getTime() - this.msBase;
  if( this.t > this.msDura ) {
    this.callB.call(this.ref,this.nFrames);
    return false;
  }
  //calculating the displacement of both elements
  this.pxProg = this.tRatio * this.t;
  this.eA.style.left = ( this.pxBaseA + this.pxProg ) + 'px';
  this.eB.style.left = (this.pxBaseB + this.pxProg) + 'px';
  if ( bRequestAnimationStatus )
    requestAnimationFrame( slide.bind(this) );
  else
    window.setTimeout( slide.bind(this), 16 );
  this.nFrames++;
}
//starting an animation
slide.call({
  eA:      theMiddlePage,
  eB:      neighboorPage, 
  callB:   theCallback,
  msBase:  new Date().getTime(),
  msDura:  400,
  tRatio:  ((0-pxScreenWidth)/400),
  nFrames: 0,
  ref:     myObject,
  pxBaseA: theMiddlePage.offsetLeft,
  pxBaseB: neighboorPage.offsetLeft
});

问题

我注意到,当我让AJAX脚本在每个页面中加载更少的图像时,动画会变得更快。这些单独的图像似乎产生了比我预期的更多的开销。

有别的办法吗?

Java脚本解决方案

好吧,有两种可能的方法可以让你加快速度。

首先,当您修改元素的样式时,您会强制浏览器重新发送页面。这被称为重新喷漆。某些更改还会强制重新计算页面的几何图形。这被称为回流。回流总是在它之后立即触发重新绘制。我认为,元素越多,性能越差的原因是,每个元素的每次更新都会触发至少一次重新绘制。在修改单个元素上的多个样式的情况下,通常建议通过添加或删除类一次完成所有样式,或者隐藏元素,进行操作,然后显示它,这意味着只有两次重新绘制(可能还会重新绘制(。

在这种特殊的情况下,您可能已经做得很好了,因为每次迭代只操作一次每个项目。

其次,requestAnimationFrame((适合在画布元素上制作动画,但在DOM元素上的性能似乎有些不可靠。在Chrome的探查器中打开你的页面,看看它到底挂在哪里。试着使用setTimeout((看看是否会出现这种情况。同样,探查器会告诉您挂断的位置。requestAnimationFrame((应该更好,但请验证这一点。我以前也有过事与愿违的经历。

的实解

如果可以避免的话,不要在JavaScript中这样做。使用CSS转换和翻译来制作动画,并将JavaScript函数注册为每个动画元素的onTransitionEnd事件处理程序。让浏览器原生地完成这项工作几乎总是比任何人都能编写的任何JS代码都快。

唯一的问题是CSS3动画只有更新的浏览器才支持。为了你自己的启迪,这样做吧。对于实际应用程序,请委托给库。如果可能的话,一个好的库将以本机方式完成,并返回到旧浏览器的JS中的最佳方式。

很好的链接阅读关于这些东西:http://www.html5rocks.com/en/tutorials/speed/html5/