Skip to content

Commit 50ca6cc

Browse files
authored
Merge pull request #313 from getmaxun/performance
feat: recorder performance improvements
2 parents 5058a3b + 2d79591 commit 50ca6cc

File tree

5 files changed

+685
-222
lines changed

5 files changed

+685
-222
lines changed

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
"joi": "^17.6.0",
4545
"jsonwebtoken": "^9.0.2",
4646
"jwt-decode": "^4.0.0",
47+
"lodash": "^4.17.21",
4748
"loglevel": "^1.8.0",
4849
"loglevel-plugin-remote": "^0.6.8",
4950
"maxun-core": "^0.0.7",
@@ -66,6 +67,7 @@
6667
"react-transition-group": "^4.4.2",
6768
"sequelize": "^6.37.3",
6869
"sequelize-typescript": "^2.1.6",
70+
"sharp": "^0.33.5",
6971
"socket.io": "^4.4.1",
7072
"socket.io-client": "^4.4.1",
7173
"styled-components": "^5.3.3",
@@ -97,6 +99,7 @@
9799
"@types/cookie-parser": "^1.4.7",
98100
"@types/express": "^4.17.13",
99101
"@types/js-cookie": "^3.0.6",
102+
"@types/lodash": "^4.17.14",
100103
"@types/loglevel": "^1.6.3",
101104
"@types/node": "22.7.9",
102105
"@types/node-cron": "^3.0.11",

perf/performance.ts

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Frontend Performance Monitoring
2+
export class FrontendPerformanceMonitor {
3+
private metrics: {
4+
fps: number[];
5+
memoryUsage: MemoryInfo[];
6+
renderTime: number[];
7+
eventLatency: number[];
8+
};
9+
private lastFrameTime: number;
10+
private frameCount: number;
11+
12+
constructor() {
13+
this.metrics = {
14+
fps: [],
15+
memoryUsage: [],
16+
renderTime: [],
17+
eventLatency: [],
18+
};
19+
this.lastFrameTime = performance.now();
20+
this.frameCount = 0;
21+
22+
// Start monitoring
23+
this.startMonitoring();
24+
}
25+
26+
private startMonitoring(): void {
27+
// Monitor FPS
28+
const measureFPS = () => {
29+
const currentTime = performance.now();
30+
const elapsed = currentTime - this.lastFrameTime;
31+
this.frameCount++;
32+
33+
if (elapsed >= 1000) { // Calculate FPS every second
34+
const fps = Math.round((this.frameCount * 1000) / elapsed);
35+
this.metrics.fps.push(fps);
36+
this.frameCount = 0;
37+
this.lastFrameTime = currentTime;
38+
}
39+
requestAnimationFrame(measureFPS);
40+
};
41+
requestAnimationFrame(measureFPS);
42+
43+
// Monitor Memory Usage
44+
if (window.performance && (performance as any).memory) {
45+
setInterval(() => {
46+
const memory = (performance as any).memory;
47+
this.metrics.memoryUsage.push({
48+
usedJSHeapSize: memory.usedJSHeapSize,
49+
totalJSHeapSize: memory.totalJSHeapSize,
50+
timestamp: Date.now()
51+
});
52+
}, 1000);
53+
}
54+
}
55+
56+
// Monitor Canvas Render Time
57+
public measureRenderTime(renderFunction: () => void): void {
58+
const startTime = performance.now();
59+
renderFunction();
60+
const endTime = performance.now();
61+
this.metrics.renderTime.push(endTime - startTime);
62+
}
63+
64+
// Monitor Event Latency
65+
public measureEventLatency(event: MouseEvent | KeyboardEvent): void {
66+
const latency = performance.now() - event.timeStamp;
67+
this.metrics.eventLatency.push(latency);
68+
}
69+
70+
// Get Performance Report
71+
public getPerformanceReport(): PerformanceReport {
72+
return {
73+
averageFPS: this.calculateAverage(this.metrics.fps),
74+
averageRenderTime: this.calculateAverage(this.metrics.renderTime),
75+
averageEventLatency: this.calculateAverage(this.metrics.eventLatency),
76+
memoryTrend: this.getMemoryTrend(),
77+
lastMemoryUsage: this.metrics.memoryUsage[this.metrics.memoryUsage.length - 1]
78+
};
79+
}
80+
81+
private calculateAverage(array: number[]): number {
82+
return array.length ? array.reduce((a, b) => a + b) / array.length : 0;
83+
}
84+
85+
private getMemoryTrend(): MemoryTrend {
86+
if (this.metrics.memoryUsage.length < 2) return 'stable';
87+
const latest = this.metrics.memoryUsage[this.metrics.memoryUsage.length - 1];
88+
const previous = this.metrics.memoryUsage[this.metrics.memoryUsage.length - 2];
89+
const change = latest.usedJSHeapSize - previous.usedJSHeapSize;
90+
if (change > 1000000) return 'increasing'; // 1MB threshold
91+
if (change < -1000000) return 'decreasing';
92+
return 'stable';
93+
}
94+
}
95+
96+
// Backend Performance Monitoring
97+
export class BackendPerformanceMonitor {
98+
private metrics: {
99+
screenshotTimes: number[];
100+
emitTimes: number[];
101+
memoryUsage: NodeJS.MemoryUsage[];
102+
};
103+
104+
constructor() {
105+
this.metrics = {
106+
screenshotTimes: [],
107+
emitTimes: [],
108+
memoryUsage: []
109+
};
110+
this.startMonitoring();
111+
}
112+
113+
private startMonitoring(): void {
114+
// Monitor Memory Usage
115+
setInterval(() => {
116+
this.metrics.memoryUsage.push(process.memoryUsage());
117+
}, 1000);
118+
}
119+
120+
public async measureScreenshotPerformance(
121+
makeScreenshot: () => Promise<void>
122+
): Promise<void> {
123+
const startTime = process.hrtime();
124+
await makeScreenshot();
125+
const [seconds, nanoseconds] = process.hrtime(startTime);
126+
this.metrics.screenshotTimes.push(seconds * 1000 + nanoseconds / 1000000);
127+
}
128+
129+
public measureEmitPerformance(emitFunction: () => void): void {
130+
const startTime = process.hrtime();
131+
emitFunction();
132+
const [seconds, nanoseconds] = process.hrtime(startTime);
133+
this.metrics.emitTimes.push(seconds * 1000 + nanoseconds / 1000000);
134+
}
135+
136+
public getPerformanceReport(): BackendPerformanceReport {
137+
return {
138+
averageScreenshotTime: this.calculateAverage(this.metrics.screenshotTimes),
139+
averageEmitTime: this.calculateAverage(this.metrics.emitTimes),
140+
currentMemoryUsage: this.metrics.memoryUsage[this.metrics.memoryUsage.length - 1],
141+
memoryTrend: this.getMemoryTrend()
142+
};
143+
}
144+
145+
private calculateAverage(array: number[]): number {
146+
return array.length ? array.reduce((a, b) => a + b) / array.length : 0;
147+
}
148+
149+
private getMemoryTrend(): MemoryTrend {
150+
if (this.metrics.memoryUsage.length < 2) return 'stable';
151+
const latest = this.metrics.memoryUsage[this.metrics.memoryUsage.length - 1];
152+
const previous = this.metrics.memoryUsage[this.metrics.memoryUsage.length - 2];
153+
const change = latest.heapUsed - previous.heapUsed;
154+
if (change > 1000000) return 'increasing';
155+
if (change < -1000000) return 'decreasing';
156+
return 'stable';
157+
}
158+
}
159+
160+
interface MemoryInfo {
161+
usedJSHeapSize: number;
162+
totalJSHeapSize: number;
163+
timestamp: number;
164+
}
165+
166+
type MemoryTrend = 'increasing' | 'decreasing' | 'stable';
167+
168+
interface PerformanceReport {
169+
averageFPS: number;
170+
averageRenderTime: number;
171+
averageEventLatency: number;
172+
memoryTrend: MemoryTrend;
173+
lastMemoryUsage: MemoryInfo;
174+
}
175+
176+
interface BackendPerformanceReport {
177+
averageScreenshotTime: number;
178+
averageEmitTime: number;
179+
currentMemoryUsage: NodeJS.MemoryUsage;
180+
memoryTrend: MemoryTrend;
181+
}

0 commit comments

Comments
 (0)