成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

JS模擬監控頁面FPS幀率

開發
有的時候,一些復雜SVGA或者CSS動畫,我們需要實時監控它們的幀率,或者說是需要知道它們在不同設備的運行狀況,從而更好的優化它們。

動畫其實是由一幀一幀的圖像構成的。有 Web 動畫那么就會存在該動畫在播放運行時的幀率。而幀率在不同設備不同情況下又是不一樣的。

[[345185]]

有的時候,一些復雜SVGA或者CSS動畫,我們需要實時監控它們的幀率,或者說是需要知道它們在不同設備的運行狀況,從而更好的優化它們。

流暢的標準
首先,理清一些概念。FPS 表示的是每秒鐘畫面更新次數。我們平時所看到的連續畫面都是由一幅幅靜止畫面組成的,每幅畫面稱為一幀,FPS 是描述“幀”變化速度的物理量。

理論上說,FPS 越高,動畫會越流暢,目前大多數設備的屏幕刷新率為 60 次/秒,所以通常來講 FPS 為 60 frame/s 時動畫效果最好,也就是每幀的消耗時間為 (1000/60) 16.67ms。

當然,經常玩 FPS 游戲的朋友肯定知道,吃雞/CSGO 等 FPS 游戲推薦使用 144HZ 刷新率的顯示器,144Hz 顯示器特指每秒的刷新率達到 144Hz 的顯示器。相較于普通顯示器每秒60的刷新速度,畫面顯示更加流暢。因此144Hz顯示器比較適用于視角時常保持高速運動的第一人稱射擊游戲。

不過,這個只是顯示器提供的高刷新率特性,對于我們 Web 動畫而言,是否支持還要看瀏覽器,而大多數瀏覽器刷新率為 60 次/秒。

直觀感受,不同幀率的體驗:

  • 幀率能夠達到 50 ~ 60 FPS 的動畫將會相當流暢,讓人倍感舒適;
  • 幀率在 30 ~ 50 FPS 之間的動畫,因各人敏感程度不同,舒適度因人而異;
  • 幀率在 30 FPS 以下的動畫,讓人感覺到明顯的卡頓和不適感;
  • 幀率波動很大的動畫,亦會使人感覺到卡頓。

那么我們該如何通過JS來模擬獲取我們頁面動畫當前的 FPS 值呢?

requestAnimationFrame
requestAnimationFrame 大家應該都不陌生,方法告訴瀏覽器您希望執行動畫并請求瀏覽器調用指定的函數在下一次重繪之前更新動畫。

  1. // 語法 
  2. window.requestAnimationFrame(callback); 

 當你準備好更新屏幕畫面時你就應用此方法。這會要求你的動畫函數在瀏覽器下次重繪前執行。回調的次數常是每秒 60 次,大多數瀏覽器通常匹配 W3C 所建議的刷新率。

使用 requestAnimationFrame 計算 FPS 原理 原理是,正常而言 requestAnimationFrame 這個方法在一秒內會執行 60 次,也就是不掉幀的情況下。假設動畫在時間 A 開始執行,在時間 B 結束,耗時 x ms。而中間 requestAnimationFrame 一共執行了 n 次,則此段動畫的幀率大致為:n / (B - A)。

核心代碼如下,能近似計算每秒頁面幀率,以及我們額外記錄一個 allFrameCount,用于記錄 rAF 的執行次數,用于計算每次動畫的幀率 :

  1. var rAF = function () { 
  2.     return ( 
  3.         window.requestAnimationFrame || 
  4.         window.webkitRequestAnimationFrame || 
  5.         function (callback) { 
  6.             window.setTimeout(callback, 1000 / 60); 
  7.         } 
  8.     ); 
  9. }(); 
  10.    
  11. var frame = 0; 
  12. var allFrameCount = 0; 
  13. var lastTime = Date.now(); 
  14. var lastFameTime = Date.now(); 
  15.    
  16. var loop = function () { 
  17.     var now = Date.now(); 
  18.     var fs = (now - lastFameTime); 
  19.     var fps = Math.round(1000 / fs); 
  20.    
  21.     lastFameTime = now; 
  22.     // 不置 0,在動畫的開頭及結尾記錄此值的差值算出 FPS 
  23.     allFrameCount++; 
  24.     frame++; 
  25.    
  26.     if (now > 1000 + lastTime) { 
  27.         var fps = Math.round((frame * 1000) / (now - lastTime)); 
  28.         console.log(`${new Date()} 1S內 FPS:`, fps); 
  29.         frame = 0; 
  30.         lastTime = now; 
  31.     }; 
  32.    
  33.     rAF(loop); 
  34.   
  35. loop(); 

如果我們需要統計某個特定動畫過程的幀率,只需要在動畫開始和結尾兩處分別記錄 allFrameCount 這個數值大小,再除以中間消耗的時間,也可以得出特定動畫過程的 FPS 值。

值得注意的是,這個方法計算的結果和真實的幀率肯定是存在誤差的,因為它是將每兩次主線程執行 javascript 的時間間隔當成一幀,而非上面說的主線程加合成線程所消耗的時間為一幀。但是對于現階段而言,算是一種可取的方法。

適當美化一下

  1. import BUS from 'event-bus'
  2.  
  3. // 計算性能指標 
  4. (() => { 
  5.     const createConsole = (desc, val) => console.log( 
  6.         `%c${desc}`, 
  7.         'color:#fff;background:red;padding:2px 6px;border-radius:3px;'
  8.         val); 
  9.  
  10.     window.addEventListener('load', () => { 
  11.         const timing = performance.timing; 
  12.         createConsole('DNS 解析耗時', timing.domainLookupEnd - timing.domainLookupStart); 
  13.         createConsole('TCP連接耗時', timing.connectEnd - timing.connectStart); 
  14.         createConsole('網絡請求耗時', timing.responseStart - timing.requestStart); 
  15.         createConsole('數據傳輸耗時', timing.responseEnd - timing.requestStart); 
  16.         createConsole('頁面首次渲染時間', timing.responseEnd - timing.navigationStart); 
  17.         createConsole('首次可交互時間', timing.domInteractive - timing.navigationStart); 
  18.         createConsole('DOM解析耗時', timing.domInteractive - timing.responseEnd); 
  19.         createConsole('DOM構建耗時', timing.domComplete - timing.domInteractive); 
  20.         createConsole('HTML 加載完成,DOM Ready', timing.domContentLoadedEventEnd - timing.navigationStart); 
  21.         createConsole('頁面完全加載耗時', timing.loadEventStart - timing.navigationStart); 
  22.     }); 
  23. })(); 
  24.  
  25.  
  26. // FPS檢測 
  27. (() => { 
  28.     const limit = 3;                        // 出現低FPS的連續次數上限 
  29.     const below = 20;                       // 可容忍的最低FPS 
  30.     const updateInterval = 2 * 1000;        // 檢測幀率的間隔時間 
  31.     let updateTimer = 0;                    // 已經過去的時間 
  32.     let count = 0; 
  33.  
  34.     let lastTime = performance.now(); 
  35.     let frame = 0; 
  36.     let lastFameTime = performance.now(); 
  37.     const loop = () => { 
  38.         frame += 1; 
  39.         const now = performance.now(); 
  40.         const fs = (now - lastFameTime); 
  41.         lastFameTime = now; 
  42.         updateTimer += fs || 0; 
  43.         if (updateTimer < updateInterval) { 
  44.             window.requestAnimationFrame(loop); 
  45.             return
  46.         } 
  47.         updateTimer = 0; 
  48.  
  49.         let fps = 0; 
  50.         fps = Math.round(1000 / fs); 
  51.         if (now > 1000 + lastTime) { 
  52.             fps = Math.round((frame * 1000) / (now - lastTime)); 
  53.             frame = 0; 
  54.             lastTime = now; 
  55.         } 
  56.         if (fps < below) { 
  57.             count += 1; 
  58.             if (count >= limit) { 
  59.                 console.log('網頁卡頓', `連續${count}次FPS低于${below},當前FPS為${fps}`); 
  60.                 BUS.trigger('fps-low');    // 關閉一些JS動畫 
  61.             } 
  62.         } else { 
  63.             count = 0; 
  64.         } 
  65.         window.requestAnimationFrame(loop); 
  66.     }; 
  67.  
  68.     loop(); 
  69. })(); 

參考
Web 動畫幀率(FPS)計算:https://www.cnblogs.com/coco1s/p/8029582.html

 

責任編輯:姜華 來源: JavaScript忍者秘籍
相關推薦

2015-05-13 09:36:18

js模擬手機下拉刷新

2022-09-23 20:06:52

微軟Windows 11

2022-02-17 23:13:24

筆記本顯卡AMD

2023-03-23 08:37:23

Linux

2011-09-08 15:06:33

HTML 5

2023-07-24 09:03:38

汽車之家頁面性能監控

2023-10-06 11:39:39

2021-04-23 09:33:55

Windows10操作系統微軟

2010-10-09 11:01:31

JS

2012-05-22 01:56:01

Google CodeJava代碼工具

2020-04-21 14:00:25

HTMLCSSJS

2015-03-26 13:14:53

javascriptjs callback實現調用

2016-12-02 18:03:32

2021-06-18 10:12:09

JS代碼前端

2021-12-18 07:42:15

Ebpf 監控 Node.js

2009-03-27 09:51:00

IP監控視頻

2021-02-23 12:25:26

鴻蒙HarmonyOS應用開發

2024-03-01 08:38:35

Hybrid頁面JS

2021-11-05 21:36:59

JavaScript語言開發

2017-04-20 12:30:57

聲明式爬蟲網絡
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产在线视频一区 | 欧美区日韩区 | 综合国产 | 天天综合网永久 | 日韩av一二三区 | 免费午夜电影 | 高清人人天天夜夜曰狠狠狠狠 | 观看av| 在线成人免费视频 | 欧美福利网站 | 成人av片在线观看 | 欧美寡妇偷汉性猛交 | 亚洲国产成人精品久久久国产成人一区 | 国产一区二区精华 | 亚洲欧美一区二区三区视频 | 久久久久亚洲精品国产 | 欧美激情精品久久久久久 | 欧美精品一区二区三区一线天视频 | 99精品久久久久久 | 网黄在线| 日韩中文视频 | 中文字幕在线剧情 | 成人不卡| 祝你幸福电影在线观看 | 成人免费视频一区 | 亚洲国产伊人 | 午夜小视频在线播放 | 亚洲精品一 | 婷婷久久精品一区二区 | 天天爽夜夜爽精品视频婷婷 | 国产一区二区自拍 | 日韩在线精品视频 | 日本中文字幕日韩精品免费 | 超碰97人人人人人蜜桃 | 久久精品国产久精国产 | 亚洲精品乱码久久久久久蜜桃 | 在线欧美视频 | 国产小视频精品 | 91精品久久久久久久久久 | 黄网站涩免费蜜桃网站 | 91伊人网|