日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
JS模擬監(jiān)控頁(yè)面FPS幀率

動(dòng)畫(huà)其實(shí)是由一幀一幀的圖像構(gòu)成的。有 Web 動(dòng)畫(huà)那么就會(huì)存在該動(dòng)畫(huà)在播放運(yùn)行時(shí)的幀率。而幀率在不同設(shè)備不同情況下又是不一樣的。

十載的臨澤網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營(yíng)銷推廣的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整臨澤建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“臨澤網(wǎng)站設(shè)計(jì)”,“臨澤網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

有的時(shí)候,一些復(fù)雜SVGA或者CSS動(dòng)畫(huà),我們需要實(shí)時(shí)監(jiān)控它們的幀率,或者說(shuō)是需要知道它們?cè)诓煌O(shè)備的運(yùn)行狀況,從而更好的優(yōu)化它們。

流暢的標(biāo)準(zhǔn)
首先,理清一些概念。FPS 表示的是每秒鐘畫(huà)面更新次數(shù)。我們平時(shí)所看到的連續(xù)畫(huà)面都是由一幅幅靜止畫(huà)面組成的,每幅畫(huà)面稱為一幀,F(xiàn)PS 是描述“幀”變化速度的物理量。

理論上說(shuō),F(xiàn)PS 越高,動(dòng)畫(huà)會(huì)越流暢,目前大多數(shù)設(shè)備的屏幕刷新率為 60 次/秒,所以通常來(lái)講 FPS 為 60 frame/s 時(shí)動(dòng)畫(huà)效果最好,也就是每幀的消耗時(shí)間為 (1000/60) 16.67ms。

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

不過(guò),這個(gè)只是顯示器提供的高刷新率特性,對(duì)于我們 Web 動(dòng)畫(huà)而言,是否支持還要看瀏覽器,而大多數(shù)瀏覽器刷新率為 60 次/秒。

直觀感受,不同幀率的體驗(yàn):

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

那么我們?cè)撊绾瓮ㄟ^(guò)JS來(lái)模擬獲取我們頁(yè)面動(dòng)畫(huà)當(dāng)前的 FPS 值呢?

requestAnimationFrame
requestAnimationFrame 大家應(yīng)該都不陌生,方法告訴瀏覽器您希望執(zhí)行動(dòng)畫(huà)并請(qǐng)求瀏覽器調(diào)用指定的函數(shù)在下一次重繪之前更新動(dòng)畫(huà)。

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

 當(dāng)你準(zhǔn)備好更新屏幕畫(huà)面時(shí)你就應(yīng)用此方法。這會(huì)要求你的動(dòng)畫(huà)函數(shù)在瀏覽器下次重繪前執(zhí)行?;卣{(diào)的次數(shù)常是每秒 60 次,大多數(shù)瀏覽器通常匹配 W3C 所建議的刷新率。

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

核心代碼如下,能近似計(jì)算每秒頁(yè)面幀率,以及我們額外記錄一個(gè) allFrameCount,用于記錄 rAF 的執(zhí)行次數(shù),用于計(jì)算每次動(dòng)畫(huà)的幀率 :

 
 
 
  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,在動(dòng)畫(huà)的開(kāi)頭及結(jié)尾記錄此值的差值算出 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內(nèi) FPS:`, fps); 
  29.         frame = 0; 
  30.         lastTime = now; 
  31.     }; 
  32.    
  33.     rAF(loop); 
  34.   
  35. loop(); 

如果我們需要統(tǒng)計(jì)某個(gè)特定動(dòng)畫(huà)過(guò)程的幀率,只需要在動(dòng)畫(huà)開(kāi)始和結(jié)尾兩處分別記錄 allFrameCount 這個(gè)數(shù)值大小,再除以中間消耗的時(shí)間,也可以得出特定動(dòng)畫(huà)過(guò)程的 FPS 值。

值得注意的是,這個(gè)方法計(jì)算的結(jié)果和真實(shí)的幀率肯定是存在誤差的,因?yàn)樗菍⒚績(jī)纱沃骶€程執(zhí)行 javascript 的時(shí)間間隔當(dāng)成一幀,而非上面說(shuō)的主線程加合成線程所消耗的時(shí)間為一幀。但是對(duì)于現(xiàn)階段而言,算是一種可取的方法。

適當(dāng)美化一下

 
 
 
  1. import BUS from 'event-bus'; 
  2.  
  3. // 計(jì)算性能指標(biāo) 
  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 解析耗時(shí)', timing.domainLookupEnd - timing.domainLookupStart); 
  13.         createConsole('TCP連接耗時(shí)', timing.connectEnd - timing.connectStart); 
  14.         createConsole('網(wǎng)絡(luò)請(qǐng)求耗時(shí)', timing.responseStart - timing.requestStart); 
  15.         createConsole('數(shù)據(jù)傳輸耗時(shí)', timing.responseEnd - timing.requestStart); 
  16.         createConsole('頁(yè)面首次渲染時(shí)間', timing.responseEnd - timing.navigationStart); 
  17.         createConsole('首次可交互時(shí)間', timing.domInteractive - timing.navigationStart); 
  18.         createConsole('DOM解析耗時(shí)', timing.domInteractive - timing.responseEnd); 
  19.         createConsole('DOM構(gòu)建耗時(shí)', timing.domComplete - timing.domInteractive); 
  20.         createConsole('HTML 加載完成,DOM Ready', timing.domContentLoadedEventEnd - timing.navigationStart); 
  21.         createConsole('頁(yè)面完全加載耗時(shí)', timing.loadEventStart - timing.navigationStart); 
  22.     }); 
  23. })(); 
  24.  
  25.  
  26. // FPS檢測(cè) 
  27. (() => { 
  28.     const limit = 3;                        // 出現(xiàn)低FPS的連續(xù)次數(shù)上限 
  29.     const below = 20;                       // 可容忍的最低FPS 
  30.     const updateInterval = 2 * 1000;        // 檢測(cè)幀率的間隔時(shí)間 
  31.     let updateTimer = 0;                    // 已經(jīng)過(guò)去的時(shí)間 
  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('網(wǎng)頁(yè)卡頓', `連續(xù)${count}次FPS低于${below},當(dāng)前FPS為${fps}`); 
  60.                 BUS.trigger('fps-low');    // 關(guān)閉一些JS動(dòng)畫(huà) 
  61.             } 
  62.         } else { 
  63.             count = 0; 
  64.         } 
  65.         window.requestAnimationFrame(loop); 
  66.     }; 
  67.  
  68.     loop(); 
  69. })(); 

參考
Web 動(dòng)畫(huà)幀率(FPS)計(jì)算:https://www.cnblogs.com/coco1s/p/8029582.html


網(wǎng)頁(yè)標(biāo)題:JS模擬監(jiān)控頁(yè)面FPS幀率
轉(zhuǎn)載源于:http://m.5511xx.com/article/djpjcig.html