搜尋
首頁web前端js教程深入探究讓JavaScript動畫流暢的一些方法_javascript技巧

基於Javascript的動畫暗中同CSS過渡效果一樣,甚至更加快,這怎麼可能呢?而Adobe和Google持續發布的富媒體行動網站的效能可媲美本地應用,這又怎麼可能呢?

本文逐一遍覽了基於Javascript的DOM動畫庫,如Velocity.js和GSAP,看其是如何比jQuery和CSS動畫效果更具性能的.
jQuery

讓我們先從基礎的開始: JavaScript 和 jQuery 被錯誤的混為一談了. JavaScript 動畫是很快的. jQuery 把它放慢了下來。為什麼?因為 — 儘管jQuery非常強大 — 但成為一個性能強勁的動畫引擎從來都不是jQuery的設計目標:

  •     jQuery 不能避免 佈局顛簸 ,這得歸因於它的程式碼庫提供了動畫之外的多種用途.
  •     jQuery 的記憶體消耗經常會觸發垃圾回收,那樣會 時不時的讓動畫定格下來.
  •     jQuery 使用 setInterval 而非 requestAnimationFrame (RAF) 來 保護新科技不受其自身的影響.

應該注意到佈局顛簸就是在動畫開始部分的不順暢,垃圾回收就是造成動畫期間不順暢的元兇, 而沒有使用RAF則會導致低幀率.

實作範例

避免造成佈局顛簸的DOM查詢和更新組合:
 

var currentTop,
  currentLeft;
 
/* With layout thrashing. */
currentTop = element.style.top; /* QUERY */
element.style.top = currentTop + 1; /* UPDATE */
 
currentLeft = element.style.left; /* QUERY */
element.style.left = currentLeft + 1; /* UPDATE */
 
/* Without layout thrashing. */
currentTop = element.style.top; /* QUERY */
currentLeft = element.style.left; /* QUERY */
 
element.style.top = currentTop + 1; /* UPDATE */
element.style.left = currentLeft + 1; /* UPDATE */

發生在更新之後的查詢會強制瀏覽器對頁面的計算式資料進行重新計算(同時會把新的更新效果考慮在內). 這樣就會對動畫產生顯著的開銷,而這只是16毫秒微小間隔的運行超時.

類似的,實作 RAF 並不必須是對你的現有程式碼庫的顯著返工. 讓我們拿RAF的基礎實作同setInterval比較一下:
 

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);

RAF 产生了推动动画性能的最大可能性,你可以对你的代码进行单一的变更.

CSS 转换

CSS转换通过把动画逻辑甩给浏览器本身去处理而超越了jQuery,这在以下几方面是有效果的:(1)优化DOM交互和内存消耗以避免卡顿(颠簸),(2)利用引擎的RAF原则,(3)强制硬件加速(利用GPU的能力来提高动画性能)。

然而,现实是,这些优化也可以在JavaScript中直接执行。GSAP已经这样做了多年。Velocity.js,一个新的动画引擎,不仅利用了同样的技术,而且还向前多走了几步——我们不久会探讨这些。

面对事实,JavaScript动画可以与CSS转换竞争只是我们康复计划的第一步。第二步是实现“JavaScript动画实际上可以比CSS转换更快”。


现在我们开始谈谈CSS变换的弱点:

  •     transition强制硬件加速会加大GPU消耗,高负荷情形下将导致运行不流畅。这种情况在移动设备上尤为明显。(特殊情况下,比如当数据在浏览器主线程和排版线程之间传递产生的瓶颈也会导致不流畅)。某些CSS属性,比如transform和opacity,则不受这些瓶颈影响。Adobe在这里精心总结了这些问题。
  •     transition在IE10以下没有用,造成的自IE8和IE9以来的桌面站点可用性问题至今仍然广泛存在。
  •     由于transition并不是由JavaScript原生控制(而仅仅是由JavaScript触发),浏览器无法获知如何与控制这些transition的JavaScript代码同步地优化他们。

相反的,基于JavaScript的动画库则可以自行确定合适开启硬件。它们原生支持各版本IE浏览器,并且它们尤其适合批量动画优化。

我的建议是仅当你单独为移动端开发且仅实现简单动画时使用原生CSS变换。这种环境下,transition是一种原生有效的解决方案,可以使你在样式表中实现所有动画逻辑,而不用添加额外的JavaScript库,从而避免你的页面变得臃肿。然而,当你在设计复杂的UI,或者是开发存在不同状态的UI的App时,你就应该使用动画库以使动画保持流畅,同时使工作流程易于管理。Transit是一个在管理CSS变换方面做得尤其优秀的库。

JavaScript 动画

好了,那JavaScript可就在性能方面占据上风了. 但Javascript究竟具体快了多少呢? 好吧 — 最初 — 对于构建一个实在的 3D动画示例 是足够快的,通常在构建中你只会看到有使用WebGL. 而构建一个 多媒体小动画 也够了,通常你看到只会使用Flash或者After Effects构建. 而构建一个 虚拟世界 也够了,通常你只会看到使用canvas构建.

为了对领先的动画库,当然还要包含Transit(它使用CSS渐变效果),进行直接的对比, 回头去看看Velocity在VelocityJS.org上的文档.

问题仍然是: JavaScript是怎样具体的达成其高水平性能的? 下面是对基于Javascript动画能够被执行这一目标的优化的一个简短清单:

  •     同步 DOM → 在整个动画链中间入栈以最小化布局抖动.
  •     为整个链式调用缓存属性值,以最小化DOM查询发生 (这些就是高性能DOM动画的坑).
  •     在同样的调用中缓存整个同级别元素的单元转换率 (比如 px 到 %, em, 等等.).
  •     当更新可能会在视觉上不可见时跳过样式更新.


回顾一下我们先前学过的关于布局颠簸的知识,Velocity.js利用这些最佳实践来缓存动画结束值以复用为随后动画的开始值,从而避免了重新查询DOM以获取元素的开始值:
 

$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% 开始。

浏览器本身最终能够执行许多这些相同的优化,但这样做会明显减少开发者能够制作的动画代码的方式。因此,出于同样原因,由于jQuery不使用RAF(如上所述),浏览器就不会强制优化它,甚至给出一个很小的机会去打破规格或偏离预期的行为。

最后,我们对这两个JavaScript动画库(Velocity.js 和 GSAP)互相比较一下。


GSAP 是首个动画库,用在演示JavaScript DOM 令人印象深刻的动画表现。它确实是这样,但有些缺点:

  •     在中到高负荷动画中,GSAP 的 DOM 交互开销导致动画在开始时和过程中失帧。
  •     相反于Velocity.js 是在超宽松的 MIT 许可下发布的,  GSAP 是闭源的, 并且在很多类商用时候需要许可年费。
  •     因为 GSAP 是一个完整的动画套件,是 Velocity 大小的三倍。然而,GSAP 有如此丰富功能,有助于其成为动画的瑞士军刀。

我推荐做法是在你需要精确控制定时(比如 重绘,暂停/恢复)和运动(比如贝塞尔曲线路径)的时候用 GSAP 。这些特性在游戏开发和某些特殊应用中是至关重要的,但是通常不需要用在网页应用的 UI中。

Velocity.js

引用 GSAP 丰富的特性并不代表Velocity自身在特性上是轻量级的. 相反,在压缩后仅有的7kb中,Velocity不仅仅复制了jQuery $.animate()的所有功能, 它还把颜色动画,转换,循环,easing效果,类动画还有滚动都打包了进去.

总之,Velocity是jQuery,jQuery UI,以及CSS渐变效果的最佳组合.

此外,从便利的角度看,Velocity在hood(盖子,大概意思是公共的接口)之下使用jQuery的 $.queue() 方法, 如此就可以实现同 jQuery 的 $.animate(), $.fade(), 和 $.delay() 函数的无缝互操作. 而且,由于Velocity的语法同 $.animate() 的语法是相同的, 你不需要改变页面的任何代码.

让我们快速地来看一看 Velocity.js. 在基础的层面,Velocity的行为同$.animate()一样:

 
$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);

在其最高级的层面,可以创建带有3D动画的复杂滚动场景 — 几乎只要用到两行简单的代码:
 

$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);

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
1 個月前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器