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)文章
JS實(shí)現(xiàn)簡單的星期格式轉(zhuǎn)換功能示例
這篇文章主要介紹了JS實(shí)現(xiàn)簡單的星期格式轉(zhuǎn)換功能,涉及JavaScript基于Date()對象的日期時(shí)間操作技巧,需要的朋友可以參考下2018-07-07
Javascript 同時(shí)提交多個(gè)Web表單的方法
1 問題來自一位網(wǎng)友的提問: web頁面里有多個(gè)表單,每個(gè)表單對應(yīng)著某一類數(shù)據(jù)操作。2009-02-02
JS表格組件BootstrapTable行內(nèi)編輯解決方案x-editable
這篇文章主要介紹了JS組件系列BootstrapTable行內(nèi)編輯解決方案:x-editable,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
.NET微信公眾號開發(fā)之創(chuàng)建自定義菜單
這篇文章主要介紹了.NET微信公眾號開發(fā)之創(chuàng)建自定義菜單的相關(guān)資料,需要的朋友可以參考下2015-07-07
js實(shí)現(xiàn)無限級樹形導(dǎo)航列表效果代碼
這篇文章主要介紹了js實(shí)現(xiàn)無限級樹形導(dǎo)航列表效果代碼,通過一個(gè)封裝的JS類實(shí)現(xiàn)無限樹形導(dǎo)航的效果,非常簡單實(shí)用,需要的朋友可以參考下2015-09-09

