效能優化之通俗易懂學習requestAnimationFrame和使用場景舉例

語言: CN / TW / HK
ead>

theme: cyanosis

一項新技術新的技術方案的提出,一定是為了解決某個問題的,或者是對某種方案的優化,比如window.requestAnimationFrame這個api...

requestAnimationFrame官方介紹

requestAnimationFrame用處概述

window.requestAnimationFrame() 告訴瀏覽器——你希望執行一個動畫,並且要求瀏覽器在下次重繪之前呼叫指定的回撥函式更新動畫。該方法需要傳入一個回撥函式作為引數,該回調函式會在瀏覽器下一次重繪之前執行...

官方文件對應截圖

000.png

官方文件:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame

大致看了以後,我們可以知道:

requestAnimationFrame這個api主要是用來做動畫的。

requestAnimationFrame這個api主要是用來做動畫的。

requestAnimationFrame這個api主要是用來做動畫的。

其實顧名思義,我們翻譯這個英文單詞,也能大致明白。request(請求)Animation(動畫)Frame(幀)

關於前端動畫的兩個問題:

1.前端動畫方案有哪些?

2.為何偏偏要使用這個新的api來做動畫(或者說這個api較之前做動畫的方式優點有哪些)?

1.前端動畫方案有哪些?

主要分類為css動畫js動畫,如下細分:

  • css動畫
    • transition過渡動畫
    • animation直接動畫(搭配@keyframes
  • js動畫
    • setIntervalsetTimeout定時器(比如不停地更改dom元素的位置,使其運動起來)
    • canvas動畫,搭配js中的定時器去運動起來(canvas只是一個畫筆,然後我們通過定時器會使用這個畫筆去畫畫-動畫)
    • requestAnimationFrame動畫(js動畫中的較好方案)

另有svg動畫標籤,不過工作中這種方式是比較少的,這裡不贅述

2.為何偏偏要使用這個新的api來做動畫(或者說這個api較之前做動畫的方式優點有哪些)?

在工作中,做動畫最優的方案無疑是css動畫,但是某些特定場景下,css動畫無法實現我們所需要的需求,此時,我們就要考慮使用js去做動畫了

canvas動畫本質也是定時器動畫

使用定時器動畫幹活,實際上是可以的,但是存在一個最大的問題,就是動畫會抖動動畫會抖動動畫會抖動,體驗效果不是非常好。

而,使用requestAnimationFrame去做動畫,就不會抖動就不會抖動就不會抖動

這裡筆者寫一個demo動畫(分別是上述兩種方式實現dom元素向右平移)給大家看一下,就知道具體的區別。我們先看一下效果圖:(紅色dom是定時器實現、綠色domrequestAnimationFrame實現)

111.gif

因為筆者的gif錄製軟體的問題,看著都有點卡,實際上,大家把下方程式碼複製一份跑起來看的話,會發現定時器動畫在微微顫抖,而requestAnimationFrame動畫卻穩如老狗

```html

requestAnimationFrame_yyds

```

GitHub倉庫地址:https://github.com/shuirongshuifu/elementSrcCodeStudy

另外,有一個做滾動的外掛庫,叫做vue-seamless-scroll其內部實現原理也是基於requestAnimationFrame實現的。感興趣的道友可以去看看

類比學習reduce迴圈解決了forEach迴圈可能需要一個初始變數的問題

我們類比一下學習,比如既然有了forEach迴圈,為啥還又新推出一個reduce迴圈呢?

原因:某些場景下,reduce迴圈解決了forEach迴圈還需要再定義一個變數的問題。

似曾相識的感覺...

比如我們有一個需求,給一個數組求和。

forEach寫法

js let arr = [1, 3, 5, 7, 9] function forEachFn(params) { let total = 0 params.forEach((num) => { total = total + num }) return total } let res1 = forEachFn(arr) console.log(res1);

reduce寫法

js let arr = [1, 3, 5, 7, 9] function reduceFn(params) { return params.reduce((temp, num) => { temp = temp + num return temp }, 0) } let res2 = reduceFn(arr) console.log(res2);

通過上述兩段程式碼,我們可以看到,reduce函式比forEach少寫了一個total變數,千萬不要小看這少寫的東西,某些情況下,會節省很多的工作量呢!

一項新技術新的技術方案的提出,一定是為了解決某個問題的,或者是對某種方案的優化,比如xxx