stats.js使用性能監(jiān)控源碼解讀
1.性能監(jiān)控
github 地址:https://github.com/mrdoob/stats.js/blob/master/src/Stats.js
- FPS 在最近一秒渲染的幀數(shù)量。數(shù)值越高,性能越好.
- MS 渲染幀所需的毫秒數(shù)。數(shù)值越低,性能越好.
- MB 占用的內(nèi)存大小. (Chrome 瀏覽器快捷鍵后面添加--enable-precise-memory-info 命令)
2.fps 計(jì)算
var fps = 0; var prevTime = (performance || Date).now(), frames = 0; function aaa() { frames++; var time = (performance || Date).now(); //每秒計(jì)算一次渲染幀數(shù)量 if (time >= prevTime + 1000) { fps = (frames * 1000) / (time - prevTime); console.log(fps); prevTime = time; frames = 0; } window.requestAnimationFrame(aaa); } aaa();
3.ms 每個(gè)渲染幀運(yùn)行需要多少毫秒
let ms = 0; var beginTime = (performance || Date).now(); function bbb() { //當(dāng)前時(shí)間減去開始時(shí)間 ms = (performance || Date).now() - beginTime; console.log(ms); window.requestAnimationFrame(bbb); beginTime = (performance || Date).now(); } bbb();
4.memory 內(nèi)存占用
usedJSHeapSize
已經(jīng)使用的內(nèi)存
jsHeapSizeLimit
內(nèi)存大小限制
let mb = 0, mbPercent = 0; let prevTime = (performance || Date).now(); function ccc() { var time = (performance || Date).now(); //每秒獲取一次 if (time >= prevTime + 1000) { //獲取性能里的內(nèi)存相關(guān)參數(shù),前提是performance.memory存在 var memory = performance.memory; //1M =1048576=2^20 //使用了多少內(nèi)存 mb = memory.usedJSHeapSize / 1048576; //內(nèi)存占用百分比 mbPercent = memory.usedJSHeapSize / memory.jsHeapSizeLimit; console.log(mb, mbPercent); } window.requestAnimationFrame(ccc); } ccc();
5.畫 Canvas 的板面
創(chuàng)建 canvas
//name性能名稱, fg顏色, bg背景 Stats.Panel = function (name, fg, bg) { var min = Infinity, max = 0, round = Math.round; var PR = round(window.devicePixelRatio || 1); var WIDTH = 80 * PR, //canvas板面寬度 HEIGHT = 48 * PR, //canvas板面高度 TEXT_X = 3 * PR, //文本x坐標(biāo) TEXT_Y = 2 * PR, //文本y坐標(biāo) GRAPH_X = 3 * PR, //圖表x坐標(biāo) GRAPH_Y = 15 * PR, //圖表y坐標(biāo) GRAPH_WIDTH = 74 * PR, //圖表寬度 GRAPH_HEIGHT = 30 * PR; //圖表高度 //創(chuàng)建canvas var canvas = document.createElement('canvas'); canvas.width = WIDTH; canvas.height = HEIGHT; canvas.style.cssText = 'width:80px;height:48px'; var context = canvas.getContext('2d'); //設(shè)置字體樣式 context.font = 'bold ' + 9 * PR + 'px Helvetica,Arial,sans-serif'; context.textBaseline = 'top'; };
板面更新數(shù)值
update:function (value, maxValue) { //監(jiān)控過程中,最小最大值范圍 min = Math.min(min, value); max = Math.max(max, value); context.fillStyle = bg; context.globalAlpha = 1; //清空內(nèi)容重繪 context.fillRect(0, 0, WIDTH, GRAPH_Y); context.fillStyle = fg; //畫文本,當(dāng)前數(shù)值,name,最小最大值 context.fillText( round(value) + ' ' + name + ' (' + round(min) + '-' + round(max) + ')', TEXT_X, TEXT_Y ); //截取canvas之前的內(nèi)容范圍,往前移動,覆蓋內(nèi)容 context.drawImage( canvas, GRAPH_X + PR, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT, GRAPH_X, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT ); //清空最后的那部分 context.fillRect(GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, GRAPH_HEIGHT); context.fillStyle = bg; context.globalAlpha = 0.9; //畫出最新的數(shù)值矩形 context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, round((1 - value / maxValue) * GRAPH_HEIGHT) ); }
6.創(chuàng)建 Stats 板面
var mode = 0; var container = document.createElement('div'); container.style.cssText = 'position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000'; //點(diǎn)擊切換板面模式 container.addEventListener( 'click', function (event) { event.preventDefault(); showPanel(++mode % container.children.length); }, false ); //添加canvas板面 function addPanel(panel) { container.appendChild(panel.dom); return panel; } //顯示對應(yīng)的板面模式 function showPanel(id) { for (var i = 0; i < container.children.length; i++) { container.children[i].style.display = i === id ? 'block' : 'none'; } mode = id;
添加三種 canvas 板面
//添加索引為0的fps板面 var fpsPanel = addPanel(new Stats.Panel('FPS', '#0ff', '#002')); //添加索引為1的ms板面 var msPanel = addPanel(new Stats.Panel('MS', '#0f0', '#020')); //如果performance.memory存在,添加索引為2的內(nèi)存板面 if (self.performance && self.performance.memory) { var memPanel = addPanel(new Stats.Panel('MB', '#f08', '#201')); } //默認(rèn)顯示fps showPanel(0);
每個(gè)板面數(shù)值的更新
var beginTime = (performance || Date).now(), prevTime = beginTime, frames = 0; //開始時(shí)間 begin: function () { beginTime = (performance || Date).now(); }, //計(jì)算 end: function () { frames++; var time = (performance || Date).now(); //ms板面的數(shù)值 msPanel.update(time - beginTime, 200); if (time >= prevTime + 1000) { //fps板面數(shù)值 fpsPanel.update((frames * 1000) / (time - prevTime), 100); prevTime = time; frames = 0; //內(nèi)存板面數(shù)值更新 if (memPanel) { var memory = performance.memory; //1M =1048576=2^20 memPanel.update(memory.usedJSHeapSize / 1048576, memory.jsHeapSizeLimit / 1048576); } } return time; }, //更新 update: function () { beginTime = this.end(); },
7.使用 Stats
var stats = new Stats(); document.body.appendChild(stats.dom); function animate() { stats.update(); window.requestAnimationFrame(animate); } animate();
總結(jié)
Stats 真的很小巧實(shí)用,不用打開開發(fā)者中心,就可以用于監(jiān)控界面性能,比如可視化大屏或者一些復(fù)雜界面的性能,點(diǎn)開某個(gè)功能,猛地飆升內(nèi)存,關(guān)閉沒有降下來,那有可能內(nèi)存泄露,給你優(yōu)化渲染提供參考!
以上就是stats.js源碼解讀的詳細(xì)內(nèi)容,更多關(guān)于stats.js源碼解讀的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
分享一個(gè)插件實(shí)現(xiàn)水珠自動下落效果
本篇文章給大家分享一個(gè)插件制作水珠自動下落效果,效果非常逼真,感興趣的朋友可以添加下面代碼運(yùn)行看看效果哦2016-06-06微信小程序后端實(shí)現(xiàn)授權(quán)登錄
這篇文章主要介紹了微信小程序后端實(shí)現(xiàn)授權(quán)登錄,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02動態(tài)的創(chuàng)建一個(gè)元素createElement及刪除一個(gè)元素
本文用示例為大家介紹下動態(tài)創(chuàng)建一個(gè)元素createElement及刪除一個(gè)元素,感興趣的朋友可以參考下2014-01-01js學(xué)習(xí)總結(jié)_選項(xiàng)卡封裝(實(shí)例講解)
下面小編就為大家?guī)硪黄猨s學(xué)習(xí)總結(jié)_選項(xiàng)卡封裝(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07