Skip to content

Commit

Permalink
Merge pull request #236 from galacean/feat/support-request-stats
Browse files Browse the repository at this point in the history
feat: support network request
  • Loading branch information
JujieX authored Nov 23, 2023
2 parents 904af80 + d72675a commit 45ee386
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 3 deletions.
14 changes: 12 additions & 2 deletions packages/stats/src/Core.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import DrawCallHook from "./hooks/DrawCallHook";
import { RequestHook } from "./hooks/RequestHook";
import ShaderHook from "./hooks/ShaderHook";
import TextureHook from "./hooks/TextureHook";

Expand All @@ -16,6 +17,7 @@ export class Core {
private drawCallHook: DrawCallHook;
private textureHook: TextureHook;
private shaderHook: ShaderHook;
private requestHook: RequestHook;
private samplingFrames: number = 60;
private samplingIndex: number = 0;
private updateCounter: number = 0;
Expand All @@ -30,6 +32,7 @@ export class Core {
this.drawCallHook = new DrawCallHook(gl);
this.textureHook = new TextureHook(gl);
this.shaderHook = new ShaderHook(gl);
this.requestHook = new RequestHook();
}

/**
Expand Down Expand Up @@ -68,15 +71,21 @@ export class Core {

let data: PerformanceData = {
fps: Math.round((this.updateCounter * 1000) / (now - this.updateTime)),
memory: performance.memory && (performance.memory.usedJSHeapSize / 1048576) >> 0,
memory:
performance.memory &&
(performance.memory.usedJSHeapSize / 1048576) >> 0,
drawCall: this.drawCallHook.drawCall,
triangles: this.drawCallHook.triangles,
lines: this.drawCallHook.lines,
points: this.drawCallHook.points,
textures: this.textureHook.textures,
size: this.requestHook.size,
shaders: this.shaderHook.shaders,
webglContext:
window.hasOwnProperty("WebGL2RenderingContext") && this.gl instanceof WebGL2RenderingContext ? "2.0" : "1.0"
window.hasOwnProperty("WebGL2RenderingContext") &&
this.gl instanceof WebGL2RenderingContext
? "2.0"
: "1.0",
};

this.reset();
Expand All @@ -97,5 +106,6 @@ interface PerformanceData {
points: number;
textures: number;
shaders: number;
size: string;
webglContext: string;
}
13 changes: 12 additions & 1 deletion packages/stats/src/Monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ let tpl = `
<dd>0</dd>
<dt>Shaders</dt>
<dd>0</dd>
<dt>Network Size <span class="unit">(MB)</span></dt>
<dd>0</dd>
<dt>WebGL</dt>
<dd></dd>
</dl>
Expand Down Expand Up @@ -62,7 +64,16 @@ export default class Monitor {
constructor(gl: WebGLRenderingContext | WebGL2RenderingContext) {
this.core = new Core(gl);
this.items = [];
this.items = ["fps", "memory", "drawCall", "triangles", "textures", "shaders", "webglContext"];
this.items = [
"fps",
"memory",
"drawCall",
"triangles",
"textures",
"shaders",
"size",
"webglContext",
];
this.createContainer();
this.update = this.update.bind(this);
}
Expand Down
90 changes: 90 additions & 0 deletions packages/stats/src/hooks/RequestHook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
let requestSize = 0;

let originalSend = XMLHttpRequest.prototype.send;

const cacheMap = new Map<string, number>();
function addRequestSize(url: string, size: number) {
if (cacheMap.get(url) == undefined) {
cacheMap.set(url, size);
console.log(`request(${size}): ${url}`);
requestSize += size;
}
}

XMLHttpRequest.prototype.send = function (body) {
this.addEventListener(
"load",
function () {
let size = 0;
if (this.responseType === "" || this.responseType === "text") {
size = new Blob([JSON.stringify(this.responseText)]).size;
} else if (this.response instanceof Blob) {
size = this.response.size;
} else if (this.response instanceof ArrayBuffer) {
size = this.response.byteLength;
} else if (this.responseType === "json") {
size = new Blob([JSON.stringify(this.response)]).size;
}

addRequestSize((this as XMLHttpRequest).responseURL, size);
},
false
);

originalSend.call(this, body);

var originalImageSrc = Object.getOwnPropertyDescriptor(
Image.prototype,
"src"
).set;

this.originalImageSrc = originalImageSrc;

Object.defineProperty(Image.prototype, "src", {
set: function (value) {
fetch(value).then((response) => {
if (response.ok) {
response.blob().then((blob) => {
addRequestSize((this as XMLHttpRequest).responseURL, blob.size);
});
}
});
originalImageSrc.call(this, value);
},
});
};

export class RequestHook {
private _originalSend;
private _hooked = false;

get size() {
return formatNumber(requestSize / 1024 / 1024);
}

constructor() {
this._hooked = true;
}

public reset(): void {
requestSize = 0;
}

public release(): void {
if (this._hooked) {
XMLHttpRequest.prototype.send = this._originalSend;
Object.defineProperty(Image.prototype, "src", {
set: function (value) {
this.src.call(this, value);
},
});
}
this._hooked = false;
}
}

function formatNumber(num: number): string {
return Number(num).toFixed(
Math.max(6 - num.toString().split(".")[0].length, 0)
);
}

0 comments on commit 45ee386

Please sign in to comment.