成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

requestAnimationFrame定時動畫屏幕刷新率節流示例淺析

瀏覽:174日期:2022-06-02 09:26:47
目錄
  • 前言
  • 早期定時動畫
  • 屏幕刷新率
  • requestAnimationFrame
  • cancelAnimationFrame
  • 通過 requestAnimationFrame 節流

前言

很長時間以來,計時器和定時執行都是 JavaScript 動畫最先進的工具。雖然 CSS 過渡和動畫方便了開發者實現某些動畫,但 JavaScript 動畫領域多年來進展甚微。requestAnimationFrame() 方法應運而生,這個方法會告訴瀏覽器要執行動畫了,于是瀏覽器可以通過最優方式確定重繪的時序。

早期定時動畫

以前,在 JavaScript 中創建動畫基本上就是使用 setInterval() 來控制動畫的執行:

(function () {
  function updateAnimations() {
    doAnimation1();
    doAnimation2();
    // ...
  }
  setInterval(updateAnimations, 100);
})();

這種定時動畫的問題在于,無法準確知曉循環之間的延時。

無論是 setInterval() 還是 setTimeout(),都是不能保證時間精度的。作為第二個參數的延時只能保證何時會把代碼添加到瀏覽器的任務隊列,并不能保證添加到隊列就會立即執行。如果隊列前面還有其他任務,那么就要等這些任務執行完再執行。

簡單來講,這里的毫秒延時不是指何時這些代碼會執行,而是指到時候會把回調添加到任務隊列。如果添加到隊列后,主線程還被其他任務占用,那么回調就不會立即執行。

知道何時繪制下一幀是創造平滑動畫的關鍵,所以 setInterval()setTimeout() 的不精確是個大問題。

瀏覽器自身計時器的精度讓這個問題雪上加霜。瀏覽器計時器的精度不足毫秒,最厲害的 Chrome 計時器精度為 4ms。更麻煩的是,瀏覽器又開始對切換到后臺或不活躍的標簽頁中的計時器執行限流,因此即使將時間間隔設為最優,也免不了只能得到近似的結果。

屏幕刷新率

一般計算機顯示器的屏幕刷新率都是 60HZ,基本上意味著每秒需要重繪 60 次。大多數瀏覽器會限制重繪頻率,使其不超過屏幕的刷新率,因為超過屏幕刷新率用戶也感知不到。

所以,實現平滑動畫最佳的重繪時間間隔為 1000ms/60,大約 17 ms。以這個速度重繪可以實現最平滑的動畫,因為這已經是瀏覽器的極限了。

requestAnimationFrame

requestAnimationFrame() 這個方法可以通知瀏覽器某些 JavaScript 代碼要執行動畫了,這樣瀏覽器就可以在運行某些代碼后進行適當的優化。

requestAnimationFrame() 這個方法接收一個參數,該參數是一個要在重繪屏幕前調用的函數。這個函數就是修改 DOM 樣式以反映下一次重繪有什么變化的地方。為了實現動畫循環,可以把多個 requestAnimationFrame() 調用串聯起來,就像以前使用 setTimeout() 一樣:

function updateProgress() {
  var div = document.getElementById("status");
  div.style.width = parseInt(div.style.width, 10) + 5 + "%";
  if (div.style.left != "100%") {
    requestAnimationFrame(updateProgress);
  }
}
requestAnimationFrame(updateProgress);

因為 requestAnimationFrame() 只會調用一次傳入的函數,所以每次更新用戶界面時需要再手動調用它一次。同時,也需要控制動畫何時停止。結果就會得到非常平滑的動畫。

requestAnimationFrame() 已經解決了瀏覽器不知道 JavaScript 動畫何時開始的問題,以及最佳間隔時間是多少的問題。但是,如果我們想知道自己的代碼實際的執行時間呢?同樣有解決方案。

傳給 requestAnimationFrame() 的函數實際上可以接收一個參數,該參數表示下次重繪的時間。這一點非常重要:requestAnimationFrame() 實際上把重繪任務安排在了未來一個已知的時間點上,而且通過這個參數告訴了開發者,那么基于這個參數,就可以更好地決定如何調優動畫了:

function foo(t) {
  console.log(t);
  requestAnimationFrame(foo);
}
requestAnimationFrame(foo);

cancelAnimationFrame

const requestID = window.requestAnimationFrame((t) => {
  console.log(t);
});
window.cancelAnimationFrame(requestID);

通過 requestAnimationFrame 節流

支持這個方法的瀏覽器實際上會暴露出作為鉤子的回調隊列。所謂鉤子,就是瀏覽器在執行下一次重繪之前的一個點。這個回調隊列是一個可修改的函數列表,包含應該在重繪之前調用的函數。每次調用 requestAnimationFrame() 都會在隊列上推入一個回調函數,隊列的長度沒有限制。

這個回調隊列的行為不一定跟動畫有關。通過 requestAnimationFrame() 遞歸地向隊列中加入回調函數,可以保證每次重繪最多只調用一次回調函數,這是一個非常好的節流工具。在頻繁執行影響頁面外觀的代碼時(比如滾動事件監聽器),可以利用這個回調隊列進行節流。

先看一個原生實現,其中的滾動事件監聽器每次觸發都會調用名為 expensiveOperation()(耗時操作) 的函數。當向下滾動網頁時,這個事件很快就會被觸發并執行成百上千次:

function expensiveOperation() {
  console.log("Invoked at", Date.now());
}
window.addEventListener("scroll", () => {
  expensiveOperation();
});

如果想把事件處理程序的調用限制在每次重繪之前,那么就可以把它封裝到 requestAnimationFrame() 調用中:

function expensiveOperation() {
  console.log("Invoked at", Date.now());
}
window.addEventListener("scroll", () => {
  window.requestAnimationFrame(expensiveOperation);
});

這樣會把所有回調的執行集中在重繪鉤子,但不會過濾掉每次重繪的多余調用。我們可以定義一個標志變量,在回調中設置其狀態,就能將多余的調用屏蔽:

let enqueued = false;
function expensiveOperation() {
  console.log("Invoked at", Date.now());
  enqueued = false;
}
window.addEventListener("scroll", () => {
  if (!enqueued) {
    enqueued = true;
    window.requestAnimationFrame(expensiveOperation);
  }
});

因為重繪是非常頻繁的操作,所以這算不上是真正的節流。更好的方法是配合使用一個計時器來限制操作執行的頻率。這樣,計時器可以限制實際的操作執行間隔,而 requestAnimationFrame() 控制在瀏覽器的哪個渲染周期中執行:

let enabled = true;
function expensiveOperation() {
  console.log("Invoked at", Date.now());
}
window.addEventListener("scroll", () => {
  if (enabled) {
    enqueued = false;
    window.requestAnimationFrame(expensiveOperation);
    window.setTimeout(() => (enabled = true), 50);
  }
});

上面的例子將回調限制為大約 50ms 執行一次。

以上就是requestAnimationFrame定時動畫屏幕刷新率節流示例淺析的詳細內容,更多關于requestAnimationFrame刷新節流的資料請關注其它相關文章!

標簽: JavaScript
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
99免费精品视频| av在线免费不卡| 亚洲愉拍自拍另类高清精品| 久久久久久久久久久一区 | 成人久久久精品乱码一区二区三区| 亚洲精品系列| 国产无人区一区二区三区| 国产成人在线视频网址| 色婷婷亚洲综合| 一区二区三区蜜桃网| 亚洲无线一线二线三线区别av| 欧美精品一区二区久久婷婷| 黑人巨大精品欧美黑白配亚洲| 亚洲一区二区精品在线观看| 亚洲精品视频免费看| 丰满少妇在线播放bd日韩电影| 精品视频色一区| 男男gaygay亚洲| 老司机午夜精品视频在线观看| 亚洲伦理在线免费看| 激情另类综合| 国产欧美一区二区精品性色| 99精品视频一区| 欧美丰满一区二区免费视频| 日日摸夜夜添夜夜添亚洲女人| 国产精品美女xx| 中文字幕中文字幕一区二区| 欧美一区视频| 欧美v日韩v国产v| 久久精品国产久精国产| 色婷婷国产精品久久包臀| 亚洲国产精品视频| 亚洲一区二区三区高清不卡| 亚洲一线二线三线久久久| 在线成人h网| 日韩一区中文字幕| 亚洲大胆女人| 亚洲视频图片小说| 在线成人av| 亚洲九九爱视频| 亚洲精品系列| 亚洲成在人线免费| 久久综合九色99| 日本欧洲一区二区| 欧美性色综合网| 国产制服丝袜一区| 欧美视频精品在线| 久久99国内精品| 欧美日韩精品一二三区| 国产精品66部| 欧美精品一区在线观看| 欧美a级片网站| 中文字幕va一区二区三区| 91麻豆国产精品久久| 中文字幕欧美国产| 伊人久久亚洲热| 亚洲午夜在线视频| 一本色道a无线码一区v| 亚洲国产一区二区三区| 色狠狠色噜噜噜综合网| 久久国产精品99久久人人澡| 91麻豆精品91久久久久久清纯 | 欧美一区二区播放| aaa亚洲精品一二三区| 国产亚洲欧美激情| 黄色av日韩| 一区二区三区日韩欧美| 免费试看一区| 美女免费视频一区| 日韩欧美亚洲一区二区| av一本久道久久综合久久鬼色| 国产日韩欧美高清| 99精品国产一区二区青青牛奶| 丝袜亚洲另类欧美综合| 在线电影院国产精品| 91免费国产在线| 尤物av一区二区| 欧美色大人视频| 不卡一区中文字幕| 国产精品美女久久福利网站| 国产欧美日韩| 日韩成人精品视频| 日韩欧美国产麻豆| 亚洲国产1区| 久久狠狠亚洲综合| 337p粉嫩大胆色噜噜噜噜亚洲 | 成人国产精品免费观看视频| 国产精品久久久久久亚洲伦| 久久久久欧美精品| 国产精品99久久久久久宅男| 久久综合给合久久狠狠狠97色69| 99pao成人国产永久免费视频| 免费高清成人在线| 久久久不卡网国产精品一区| 99国产精品视频免费观看一公开| 蜜臀av国产精品久久久久| 亚洲精品在线三区| 国产日产精品一区二区三区四区的观看方式 | 亚洲国产日日夜夜| 7777精品伊人久久久大香线蕉超级流畅 | 国产福利一区在线| 国产精品成人网| 欧美性色综合网| 狠狠色丁香久久综合频道 | 成人免费视频caoporn| 国产精品短视频| 色综合久久天天综合网| av中文字幕不卡| 亚洲成a人在线观看| 精品91自产拍在线观看一区| 先锋影音国产一区| 成人a免费在线看| 亚洲国产中文字幕在线视频综合 | 欧美一区二区播放| 99精品国产福利在线观看免费| 国产美女av一区二区三区| 国产精品色婷婷久久58| 色哟哟国产精品免费观看| 亚洲sss视频在线视频| 欧美第一区第二区| 亚洲一区一卡| www.欧美.com| 日韩国产精品91| 国产婷婷精品av在线| 在线观看成人免费视频| 欧美福利视频| 国产美女av一区二区三区| 亚洲午夜久久久久久久久电影网 | 91美女视频网站| 午夜av一区二区三区| 久久综合资源网| 91高清在线观看| 亚洲国产精品123| 成人精品免费看| 亚洲va欧美va人人爽午夜 | 亚洲国产欧美在线人成| 久久亚洲一区二区三区四区| 在线中文字幕一区二区| 亚洲婷婷在线| 国产一区中文字幕| 一区二区三区久久| 国产清纯白嫩初高生在线观看91 | 欧美+日本+国产+在线a∨观看| 久久99精品久久久久久动态图 | 七七婷婷婷婷精品国产| 国产欧美日韩不卡| 日韩一区二区在线看| 久久av一区| 欧美日韩精品一区| 成人永久免费视频| 麻豆91免费看| 亚洲妇熟xx妇色黄| 国产精品伦理一区二区| 精品免费视频.| 欧美美女一区二区| 色久优优欧美色久优优| 一区二区动漫| 亚洲视屏一区| 欧美在线视频二区| 9人人澡人人爽人人精品| 国产成人午夜精品5599| 国产精品18久久久| 成人在线视频首页| 国产黄色精品视频| 国产精品一品视频| 国产精品一二二区| 国产黄色成人av| 国产精品一区二区视频| 国产一区二区导航在线播放| 国产美女在线精品| 国产美女视频一区| 国产精品99久久久久| 国产a久久麻豆| 成人福利视频在线| 99久久精品国产一区| 不卡av在线免费观看| 成人网在线播放| www.色精品| 99久久精品国产观看| 91香蕉视频mp4| 欧美一区二区三区免费看| 欧美 日韩 国产在线 | 亚洲成av人影院在线观看网| 一区2区3区在线看| 色婷婷精品久久二区二区蜜臂av| 99视频一区| 一区二区三区四区五区精品| 亚洲国内欧美| 99久久精品免费| 成人福利在线看| 免费观看在线色综合| 亚洲成av人在线观看| 亚洲男同性恋视频| 国产婷婷色一区二区三区在线| 欧美激情中文不卡| 久久中文字幕电影| 欧美一级二级三级乱码| 欧美写真视频网站| 成人午夜av电影| 国产成人av福利|