關鍵要點
transform
和 opacity
。 will-change
屬性將要進行動畫處理的元素提升到它們自己的圖層,但這應該謹慎操作,因為它需要內存和管理。 requestAnimationFrame
替換 setTimeout/setInterval
,以減少卡頓的風險並確保動畫更流暢,因為此方法會在最適合瀏覽器的時機執行動畫代碼。 網頁動畫的作用已經從簡單的裝飾性效果發展到在用戶體驗中發揮具體作用——例如,在用戶與您的應用程序交互時提供視覺反饋,引導用戶關注以實現應用程序的目標,提供幫助用戶理解應用程序界面的視覺提示等等。
為了確保網頁動畫能夠勝任這些關鍵任務,重要的是運動必須在正確的時間以流暢的方式進行,以便用戶將其視為輔助,而不是妨礙他們在應用程序上嘗試執行的任何操作。
糟糕的動畫設計會導致一個令人討厭的效果——卡頓(jank),jankfree.org 對其解釋如下:
現代瀏覽器試圖與設備的刷新率同步刷新屏幕上的內容。對於當今大多數設備而言,屏幕每秒刷新 60 次,或 60Hz。如果屏幕上有一些運動(例如滾動、過渡或動畫),瀏覽器應該每秒創建 60 幀以匹配刷新率。卡頓是用戶在網站或應用程序跟不上刷新率時看到的任何卡頓、抖動或簡單的停頓。
如果動畫卡頓,用戶最終會越來越少地與您的應用程序交互,從而對其成功產生負面影響。顯然,沒有人想要那樣。
在本文中,我收集了一些性能技巧,以幫助您解決 JavaScript 動畫問題,並更輕鬆地達到 60fps(每秒幀數)的目標,從而在網絡上實現流暢的運動。
1. 避免對代價高昂的 CSS 屬性進行動畫處理
無論您計劃使用CSS 過渡/CSS 關鍵幀還是JavaScript 來對CSS 屬性進行動畫處理,了解哪些屬性會導致頁面幾何形狀發生變化(佈局)——這意味著必須重新計算頁面上其他元素的位置,或者會涉及繪製操作——這一點非常重要。佈局和繪製任務對於瀏覽器來說處理起來非常昂貴,尤其是在頁面上有多個元素的情況下。因此,如果您避免對觸發佈局或繪製操作的CSS 屬性進行動畫處理,並堅持使用諸如transform
和opacity
之類的屬性,則會看到動畫性能顯著提高,因為現代瀏覽器在優化這些屬性方面做得非常出色。
在 CSS Triggers 上,您可以找到一個最新的 CSS 屬性列表,其中包含有關它們在每個現代瀏覽器中觸發的操作的信息,包括第一次更改和後續更改。
更改僅觸發合成操作的 CSS 屬性是您可以採取的優化網頁動畫性能的簡單有效步驟。
2. 將要進行動畫處理的元素提升到它們自己的圖層(謹慎操作)
如果要進行動畫處理的元素位於它自己的合成器圖層上,一些現代瀏覽器會利用硬件加速將工作卸載到 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() { // 动画代码在此处 }, 2000); } // 要停止动画,请使用 clearInterval function stopAnimation() { clearInterval(timer); }
雖然這有效,但卡頓的風險很高,因為回調函數在幀中的某個時間點運行,可能在最後,這可能導致錯過一幀或多幀。如今,您可以使用一種專為流暢網頁動畫(DOM 動畫、畫布等)設計的原生 JavaScript 方法,稱為 requestAnimationFrame()
。
requestAnimationFrame()
在最適合瀏覽器的時機執行您的動畫代碼,通常在幀的開頭。
您的代碼可能如下所示:
var timer; function animateElement() { timer = setInterval(function() { // 动画代码在此处 }, 2000); } // 要停止动画,请使用 clearInterval function stopAnimation() { clearInterval(timer); }
SitePoint 上 Tim Evko 的《使用 requestAnimationFrame 提高性能》提供了一個關於使用 requestAnimationFrame()
進行編碼的精彩視頻介紹。
4. 在代碼中將事件與動畫解耦
在每秒 60 幀的情況下,瀏覽器在每一幀上只有 16.67ms 來完成它的工作。時間不多,因此保持代碼精簡可能會對動畫的流暢性產生影響。
將處理滾動、調整大小、鼠標事件等事件的代碼與使用 requestAnimationFrame()
處理屏幕更新的代碼解耦,是優化動畫代碼性能的好方法。
有關此優化技巧和相關示例代碼的深入討論,請查看 Paul Lewis 的《使用 requestAnimationFrame 創建更精簡、更強大、更快的動畫》。
5. 避免長時間運行的 JavaScript 代碼
瀏覽器使用主線程來運行 JavaScript,以及其他任務,例如樣式計算、佈局和繪製操作。長時間運行的 JavaScript 代碼可能會對這些任務產生負面影響,這可能導致幀被跳過並導致動畫卡頓。因此,簡化代碼肯定是一種確保動畫流暢運行的好方法。
對於不需要訪問 DOM 的複雜 JavaScript 操作,請考慮使用 Web Workers。工作線程執行其任務不會影響用戶界面。
6. 利用瀏覽器的開發者工具來控制性能問題
瀏覽器的開發者工具提供了一種方法來監控瀏覽器運行您的 JavaScript 代碼或第三方庫的難度。它們還提供有關幀速率等的實用信息。
您可以通過右鍵單擊網頁並在上下文菜單中選擇“檢查”來訪問 Chrome DevTools。例如,使用性能工具記錄您的網頁將使您深入了解該頁面上的性能瓶頸:
單擊“記錄”按鈕,然後在幾秒鐘後停止記錄:
此時,您應該擁有大量數據來幫助您分析頁面的性能:
本 Chrome DevTools 指南將幫助您充分利用 DevTools 來分析 Chrome 瀏覽器中的性能和許多其他類型的數據。如果 Chrome 不是您選擇的瀏覽器,這沒關係,因為如今大多數現代瀏覽器都配備了功能強大的 DevTools,您可以利用它們來優化代碼。
7. 對於復雜的繪圖操作,使用離屏畫布
此技巧專門與優化 HTML5 Canvas 代碼有關。
如果您的幀涉及復雜的繪圖操作,一個好主意是在其中執行所有繪圖操作一次或僅在發生更改時執行一次,然後在每一幀上僅繪製離屏畫布。
您可以在 MDN 的《優化 Canvas》文章中找到與該技巧相關的詳細信息和代碼示例以及更多內容。
結論
如果您不想在當今的網絡上辜負用戶的期望,那麼優化代碼性能是一項必要的任務,但這絕非易事。您的動畫性能不佳可能有多種原因,但如果您嘗試使用上面列出的技巧,您將朝著避免最常見的動畫性能陷阱邁進一大步,從而改善您的網站或應用程序的用戶體驗。
關於無卡頓 JavaScript 動畫的常見問題解答 (FAQ)
“卡頓”是指用戶在網站或應用程序跟不上刷新率時看到的任何卡頓、抖動或簡單的停頓。在 JavaScript 動畫中,當幀速率低於標準的每秒 60 幀時,可能會發生卡頓。這會導致動畫不那麼流暢和視覺上不那麼吸引人,這會對用戶體驗產生負面影響。
確保 JavaScript 動畫流暢涉及優化代碼以保持穩定的每秒 60 幀。這可以通過使用 requestAnimationFrame
方法來實現,該方法允許瀏覽器優化動畫。您還可以對簡單的動畫使用 CSS 過渡或動畫,因為它們通常比 JavaScript 更高效。此外,通過將 DOM 讀寫操作一起批處理來避免佈局抖動。
requestAnimationFrame
在 JavaScript 動畫中的作用是什麼? JavaScript 中的 requestAnimationFrame
方法是創建流暢動畫的關鍵工具。它告訴瀏覽器您希望執行動畫,並請求瀏覽器在下次重繪之前調用指定函數來更新動畫。此方法允許瀏覽器優化動畫,從而實現更流暢、更高效的動畫。
CSS 過渡和動畫可能比 JavaScript 更高效,因為它們由瀏覽器的合成器線程處理,與主 JavaScript 線程分開。這意味著即使主線程忙於其他任務,它們也可以順利運行。此外,某些屬性可以在 CSS 中進行動畫處理而不會導致重繪,這使得它們特別高效。
佈局抖動是指 JavaScript 反复讀取和寫入 DOM,導致瀏覽器多次重新計算佈局,從而導致動畫低效、卡頓。這可以通過將 DOM 讀寫操作一起批處理來避免。例如,您可以先進行所有讀取操作,然後再進行所有寫入操作,而不是交錯讀取和寫入操作。
will-change
屬性優化 JavaScript 動畫? CSS 中的 will-change
屬性允許您提前告知瀏覽器您可能要對元素進行哪些類型的更改,以便它可以在需要之前設置適當的優化。這可以顯著提高動畫的性能。但是,應該謹慎使用,因為過度使用會導致瀏覽器花費太多時間進行優化。
transform
和 opacity
屬性在 JavaScript 動畫中的意義是什麼? CSS 中的 transform
和 opacity
屬性對於動畫來說特別高效。這是因為對這些屬性的更改可以由瀏覽器的合成器線程處理,而無需佈局或繪製。這意味著即使主 JavaScript 線程繁忙,它們也可以順利運行。
JavaScript 中的 Web Workers 允許您在後台運行腳本,與主執行線程分開。這意味著它們可以處理計算密集型任務,而不會阻塞主線程並導致卡頓。但是,它們有一些限制,例如無法訪問 DOM 或某些 Web API。
“非主線程”動畫是指在與主 JavaScript 線程分開的單獨線程上運行動畫。這可以顯著提高動畫的性能,因為它允許它們即使在主線程繁忙時也能順利運行。這可以通過使用 CSS 動畫、Web Workers 或 Web Animations API 來實現。
Web Animations API 提供了一種使用 JavaScript 創建動畫的方法,其性能與 CSS 動畫一樣高效。它允許您直接從 JavaScript 控制和操作動畫,為您提供比 CSS 動畫更大的靈活性。但是,它仍然是一項實驗性技術,並非所有瀏覽器都完全支持。
以上是7個無垃圾JavaScript動畫的性能提示的詳細內容。更多資訊請關注PHP中文網其他相關文章!