>  기사  >  웹 프론트엔드  >  CSS vs JS 애니메이션: 누가 더 빠릅니까?

CSS vs JS 애니메이션: 누가 더 빠릅니까?

大家讲道理
大家讲道理원래의
2016-11-10 11:53:141132검색

이 기사는 Julian Shapiro가 작성한 CSS vs. JS 애니메이션: 어느 것이 더 빠를까요?를 번역한 것입니다. Julian Shapiro는 Velocity.js의 창시자이기도 합니다. 이것은 매우 효율적이고 간단하며 사용하기 쉬운 JS 애니메이션 라이브러리입니다. 웹애니메이션 분야에서 높은 성취도를 가지고 있다.

Javascript 애니메이션이 항상 CSS 전환만큼 빠르거나 더 빠르다는 것이 어떻게 가능합니까? 비밀은 무엇입니까? Adobe와 Google은 어떻게 미디어가 풍부한 모바일 사이트를 기본 앱만큼 빠르게 만들까요? CSS vs JS 애니메이션: 누가 더 빠릅니까?

이 기사에서는 Javascript 기반 DOM 애니메이션 라이브러리(예: Velocity.js 및 GSAP)가 jQuery 및 CSS 기반 애니메이션 라이브러리보다 더 효율적인 이유를 단계별로 설명합니다.

jQuery

기본부터 시작하겠습니다. Javascript와 jQuery는 혼동될 수 없습니다. Javascript 애니메이션은 빠른 반면 jQuery 애니메이션은 느립니다. 왜? jQuery는 매우 강력하지만 디자인 목표는 효율적인 애니메이션 엔진이 되는 것이 아니기 때문입니다.

jQuery는 레이아웃 스래싱을 ​​피할 수 없습니다(어떤 사람들은 이를 "레이아웃 스래싱"으로 번역하기를 좋아합니다. 코드가 애니메이션에만 사용되는 것이 아니라 다른 많은 시나리오에서도 사용되기 때문에 (중복 릴레이아웃/리플로우)가 발생합니다.
  • jQuery는 많은 메모리를 소비하고 종종 가비지 수집을 트리거합니다. 가비지 수집이 실행되면 애니메이션이 멈추기 쉽습니다.
  • jQuery는 reqeustAnimationFrame(RAF) 대신 setInterval을 사용합니다. 왜냐하면 창이 포커스를 잃으면 RAF가 실행을 중지하여 jQuery 버그가 발생하기 때문입니다. (현재 jQuery는 이미 RAF를 사용하고 있습니다.)
  • 레이아웃 스래싱으로 인해 애니메이션이 처음에 정지되고, 가비지 수집이 트리거되면 실행 프로세스 중에 애니메이션이 정지됩니다. RAF를 사용하지 마십시오. 이렇게 하면 애니메이션 프레임 속도가 낮아집니다.
구현 예

레이아웃 스래싱을 ​​방지하려면 DOM에 일괄적으로 액세스하고 업데이트해야 합니다.

업데이트 작업 후 액세스 작업을 수행하면 브라우저가 페이지 요소의 스타일을 다시 계산하게 됩니다(올바른 값을 얻으려면 업데이트된 스타일을 적용해야 하기 때문입니다). 이는 일반적인 동작에서는 큰 성능 손실을 일으키지 않지만, 단 16ms 간격으로 애니메이션에 배치할 경우 상당한 성능 오버헤드가 발생합니다. 작업 순서를 조금만 변경해도 애니메이션 성능이 크게 향상될 수 있습니다.

var currentTop,
    currentLeft;
/* 有 layout thrashing. */
currentTop = element.style.top; /* 访问 */
element.style.top = currentTop + 1; /* 更新 */
currentLeft = element.style.left; /* 访问 */
element.style.left = currentLeft + 1; /* 更新 */
/* 没有 layout thrashing. */
currentTop = element.style.top; /* 访问 */
currentLeft = element.style.left; /* 访问 */
element.style.top = currentTop + 1; /* 更新 */
element.style.left = currentLeft + 1; /* 更新 */
마찬가지로 RAF를 사용하면 코드를 많이 리팩터링할 수 없습니다. RAF 사용과 setInterval 사용의 차이점을 비교해 보겠습니다.

RAF를 사용하려면 코드를 약간 수정하기만 하면 애니메이션 성능이 크게 향상될 수 있습니다.

var startingTop = 0;
/* setInterval: Runs every 16ms to achieve 60fps (1000ms/60 ~= 16ms). */
setInterval(function() {
    /* Since this ticks 60 times a second, we divide the top property's increment of 1 unit per 1 second by 60. */
    element.style.top = (startingTop += 1/60);
}, 16);
/* requestAnimationFrame: Attempts to run at 60fps based on whether the browser is in an optimal state. */
function tick () {
    element.style.top = (startingTop += 1/60);
}
window.requestAnimationFrame(tick);

CSS 전환

CSS 전환의 애니메이션 로직은 브라우저에서 실행되므로 jQuery 애니메이션보다 성능이 좋을 수 있습니다. 장점은 다음과 같습니다.

DOM 작업 최적화 및 메모리 소비 방지로 지연 감소
  • RAF와 유사한 메커니즘 사용
  • 하드웨어 가속 강제 사용(GPU를 통한 애니메이션 성능 향상)
그러나 실제로 Javascript에서도 이러한 최적화를 사용할 수 있습니다. GSAP는 오랫동안 이러한 최적화를 수행해 왔습니다. Velocity.js는 이러한 최적화를 수행할 뿐만 아니라 그 이상을 수행하는 새로운 애니메이션 엔진입니다. 이에 대해서는 나중에 이야기하겠습니다.

현실을 직시하세요. Javascript 애니메이션을 CSS 애니메이션의 성능과 비교할 수 있게 만드는 것은 우리의 훌륭한 계획의 첫 번째 단계에 불과합니다. 두 번째 단계는 가장 중요한 단계로, Javascript 애니메이션을 CSS 애니메이션보다 빠르게 만듭니다!

CSS 애니메이션 라이브러리의 결함을 살펴보겠습니다.

전환으로 인해 GPU 사용이 강제됩니다. 하드웨어 가속. 결과적으로 브라우저는 항상 높은 부하에서 실행되며 이로 인해 애니메이션이 중단됩니다. 모바일 브라우저에서는 더욱 심각합니다. (특히, 브라우저의 메인 스레드와 합성 스레드 사이에 데이터가 자주 전송되는 경우 특히 성능이 소모되므로 지연이 발생하기 쉽습니다. 일부 CSS 속성은 영향을 받지 않습니다. Adobe 블로그에서는 이에 대해 설명합니다.
  • IE 10 이하의 브라우저는 전환을 지원하지 않습니다. 현재 IE8과 IE9는 여전히 인기가 높습니다.
  • Javascript로 전환을 완전히 제어할 수 없습니다(전환은 Javascript로만 트리거할 수 있음). 브라우저는 Javascript가 애니메이션을 제어하고 애니메이션 성능을 최적화하도록 하는 방법을 모르기 때문입니다. 동시.
  • 반면에 Javascript는 하드웨어 가속을 활성화할 시기를 결정할 수 있고 모든 버전의 IE를 지원할 수 있으며 배치 애니메이션을 완전히 최적화할 수 있습니다.
자바스크립트 애니메이션
我的建议是:当你只在移动平台上开发,并且动画只是简单的状态切换,那么适合用纯 CSS transition。在这种情况下,transition 
是高性能的原生支持方案。它可以让你将动画逻辑放在样式文件里面,而不会让你的页面充斥 Javascript 
库。然而如果你在设计很复杂的富客户端界面或者在开发一个有着复杂UI状态的 
app。那么我推荐你使用一个动画库,这样你的动画可以保持高效,并且你的工作流也更可控。有一个特别的库做的特别棒,它可以用 Javascript 
控制 CSS transition。这就是 Transit。

  所以 Javascript 可以比 CSS transition 性能更好。但是它到底有多块呢?它快到足够可以构建一个3D 动画的demo,通常需要用到 WebGL 才能完成。并且它快到足够搭建一个多媒体小动画,通常需要 Flash 或者 After Effects 才能完成。并且它还快到可以构建一个虚拟世界,通常需要 canvas 才能完成。

  为了更直接的来比较主流动画库的性能,包括 Transit(使用了 CSS transition),让我们打开Velocity的官方文档。

  之前那个问题还在:Javascript 是如何达到高性能的呢?下面是一个列表,列举了基于 Javascript 的动画库能做的事情:

  • 同步DOM -> 在整个动画链中微调堆栈以达到最小的layout thrashing。

  • 缓存链式操作中的属性值,这样可以最小化DOM的查询操作(这就是高性能 DOM 动画的阿喀琉斯之踵)

  • 在同一个跨同层元素的调用中缓存单位转化比率(例如px转换成%、em等等单位)

  • 忽略那些变动小到根本看不出来的DOM更新

  让我们重新温习下之前学到的关于layout thrashing的知识点。Velocity.js 运用了这些最佳实践,缓存了动画结束时的属性值,在紧接的下一次动画开始时使用。这样可以避免重新查询动画的起始属性值。

$element
    /* Slide the element down into view. */
    .velocity({ opacity: 1, top: "50%" })
    /* After a delay of 1000ms, slide the element out of view. */
    .velocity({ opacity: 0, top: "-50%" }, { delay: 1000 });

  在上面的样例中,第二次调用 Velocity 时已经知道了 opacity 的起始值为 1,top 的值为 50%。

  浏览器也可以使用与此类似的优化,但是要做这些事情太过激进,使用场景也会受到限制,开发者就有可能会写出有bug的动画代码。jQuery就是因为这个原因没有使用RAF(如上所说),浏览器永远不会强行实施可能打破规范或者可能偏离期望行为的优化。

  最后,让我们来比较下两个Javascript框架(velocity.js 和 GSAP)。

  • GASP 是一个快速且功能丰富的动画平台。Velocity则更为轻量级,它大大地改善了UI动画性能和工作流程。

  • GSAP 需要付费才能用于商业产品。Velocity 是完全免费的,它使用了自由度极高的 MIT 协议。

  • 性能方面,两者几乎相当,很难区分胜负。

我个人推荐在你需要如下功能时使用 GSAP:精确控制时间(例如 remapping,暂停/继续/跳过),或者需要动作(例如:贝赛尔曲线路径),又或者复杂的动画组合/队列。这些特性对游戏开发或者复杂的应用很重要,但是对普通的 web app 的 UI 不太需要。

 Velocity.js

  之前提到了 GSAP 有着丰富的功能,但这不代表 Velocity 的功能简单。相反的,Velocity 在 zip 压缩之后只有 7kb,它不仅仅实现了 jQuery animate 方法的所有功能,还包含了 颜色、transforms、loop、easings、class 动画和滚动动画等功能。

  简单的说就是 Velocity 包含了 jQuery、 jQuery UI 和 CSS transition 的功能。

  更进一步从易用性的角度来讲,Velocity 使用了 jQuery 的$.queue() 方法,因此可以无缝过渡到 jQuery 的$.animate()、$.fade()和$.delay()方法。并且 Velocity 的语法和$.animate()一摸一样,所以我们根本不需要修改页面的现有代码。

  让我们快速过一下 Velocity.js 的例子:

$element
    .delay(1000)
    /* Use Velocity to animate the element's top property over a duration of 2000ms. */
    .velocity({ top: "50%" }, 2000)
    /* Use a standard jQuery method to fade the element out once Velocity is done animating top. */
    .fadeOut(1000);

  如下是一个高级用法:滚动网页到当前元素并且旋转元素。这样的动画只需要简单的几行代码:

$element
    /* Scroll the browser to the top of this element over a duration of 1000ms. */
    .velocity("scroll", 1000)
    /* Then rotate the element around its Y axis by 360 degrees. */
    .velocity({ rotateY: "360deg" }, 1000);

 总结

  Velocity 的目标是成为 DOM 动画领域性能最好易用性最高的库。这篇文章主要关注了性能方面。易用性方面可以前往 VelocityJS.org 了解。

  在结束之前,请记住一个高性能的 UI 绝不仅仅是选择一个正确的动画库。页面上的其他代码也需要优化。可以看看Google那些非常棒的演讲:

Jank Free

Rendering Without Lumps

Faster Websites


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.