使用JS和DOM设置多个DIV元素的动画会导致低帧率
Animating multiple DIV-Elements with JS and the DOM results in a low Framerate
前言
我刚开始用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/
- 画布:逐像素绘制图像并请求动画帧计时
- D3/Raphael js 以慢帧率绘制 1000+ 动画圆圈
- 将对象函数传递给请求动画帧时丢失对象引用
- 防止请求动画帧一直运行
- CSS 动画中的非动画帧序列
- 如何在kinetic.js中跟踪动画帧数
- BlackBerry PlayBook网络作品:低帧率
- 为什么chromecast在动画帧之间需要这么长时间
- 从间隔到请求动画帧
- Javascript move 元素与鼠标移动事件 60 FPS 请求动画帧
- 如何控制动画速度(请求动画帧)
- 请求动画帧范围更改为窗口
- 反应.js - 在请求动画帧上呈现
- 如何通过请求动画帧从其新实例中移动形状
- 从对象引用请求动画帧时出错
- HTML5 画布撕裂与请求动画帧
- 请求返回结果的动画帧
- 低帧率的JS和CSS动画
- 动态调整paperjs动画的帧率
- 使用JS和DOM设置多个DIV元素的动画会导致低帧率