perf: avoid perf overlay overhead when hidden

This commit is contained in:
scamiv
2026-02-22 17:37:28 +01:00
parent 3dbac7d387
commit 86cc25110b
3 changed files with 54 additions and 21 deletions
+14 -7
View File
@@ -429,7 +429,10 @@ export class GameRenderer {
}
renderGame() {
FrameProfiler.clear();
const shouldProfileFrame = FrameProfiler.isEnabled();
if (shouldProfileFrame) {
FrameProfiler.clear();
}
const start = performance.now();
// Set background
this.context.fillStyle = this.game
@@ -463,9 +466,13 @@ export class GameRenderer {
isTransformActive,
);
const layerStart = FrameProfiler.start();
layer.renderLayer?.(this.context);
FrameProfiler.end(getProfileLabel(layer), layerStart);
if (shouldProfileFrame) {
const layerStart = FrameProfiler.start();
layer.renderLayer?.(this.context);
FrameProfiler.end(getProfileLabel(layer), layerStart);
} else {
layer.renderLayer?.(this.context);
}
}
handleTransformState(false, isTransformActive); // Ensure context is clean after rendering
this.transformHandler.resetChanged();
@@ -473,15 +480,15 @@ export class GameRenderer {
requestAnimationFrame(() => this.renderGame());
const duration = performance.now() - start;
const layerDurations = FrameProfiler.consume();
if (FrameProfiler.isEnabled()) {
if (shouldProfileFrame) {
const layerDurations = FrameProfiler.consume();
this.renderFramesSinceLastTick++;
for (const [name, ms] of Object.entries(layerDurations)) {
this.renderLayerDurationsSinceLastTick[name] =
(this.renderLayerDurationsSinceLastTick[name] ?? 0) + ms;
}
this.performanceOverlay.updateFrameMetrics(duration, layerDurations);
}
this.performanceOverlay.updateFrameMetrics(duration, layerDurations);
if (duration > 50) {
console.warn(
@@ -265,22 +265,40 @@ export class PerformanceOverlay extends LitElement implements Layer {
}
init() {
this.setVisible(this.userSettings.performanceOverlay());
this.eventBus.on(TogglePerformanceOverlayEvent, () => {
this.userSettings.togglePerformanceOverlay();
this.setVisible(this.userSettings.performanceOverlay());
const nextVisible = !this.isVisible;
this.setVisible(nextVisible);
this.userSettings.set("settings.performanceOverlay", nextVisible);
});
this.eventBus.on(TickMetricsEvent, (event: TickMetricsEvent) => {
this.updateTickMetrics(event.tickExecutionDuration, event.tickDelay);
});
globalThis.addEventListener("user-settings-changed", (event: Event) => {
const customEvent = event as CustomEvent<{
key?: string;
value?: unknown;
}>;
if (customEvent.detail?.key !== "settings.performanceOverlay") return;
const nextVisible = customEvent.detail.value === true;
if (this.isVisible === nextVisible) return;
this.setVisible(nextVisible);
});
}
setVisible(visible: boolean) {
this.isVisible = visible;
FrameProfiler.setEnabled(visible);
this.requestUpdate();
}
private handleClose() {
this.userSettings.togglePerformanceOverlay();
const nextVisible = false;
this.setVisible(nextVisible);
this.userSettings.set("settings.performanceOverlay", nextVisible);
}
private handleMouseDown = (e: MouseEvent) => {
@@ -375,14 +393,6 @@ export class PerformanceOverlay extends LitElement implements Layer {
frameDuration: number,
layerDurations?: Record<string, number>,
) {
const wasVisible = this.isVisible;
this.isVisible = this.userSettings.performanceOverlay();
// Update FrameProfiler enabled state when visibility changes
if (wasVisible !== this.isVisible) {
FrameProfiler.setEnabled(this.isVisible);
}
if (!this.isVisible) return;
const now = performance.now();
@@ -478,7 +488,7 @@ export class PerformanceOverlay extends LitElement implements Layer {
frameCount: number,
layerDurations: Record<string, number>,
) {
if (!this.isVisible || !this.userSettings.performanceOverlay()) return;
if (!this.isVisible) return;
const alpha = 0.2; // smoothing factor for EMA
@@ -514,7 +524,7 @@ export class PerformanceOverlay extends LitElement implements Layer {
}
updateTickLayerMetrics(tickLayerDurations: Record<string, number>) {
if (!this.isVisible || !this.userSettings.performanceOverlay()) return;
if (!this.isVisible) return;
const alpha = 0.2; // smoothing factor for EMA
@@ -555,7 +565,7 @@ export class PerformanceOverlay extends LitElement implements Layer {
}
updateTickMetrics(tickExecutionDuration?: number, tickDelay?: number) {
if (!this.isVisible || !this.userSettings.performanceOverlay()) return;
if (!this.isVisible) return;
// Update tick execution duration stats
if (tickExecutionDuration !== undefined) {
+16
View File
@@ -4,6 +4,20 @@ import { PlayerPattern } from "../Schemas";
const PATTERN_KEY = "territoryPattern";
export class UserSettings {
private emitChange(key: string, value: boolean | number): void {
try {
const maybeDispatch = (globalThis as any)?.dispatchEvent;
if (typeof maybeDispatch !== "function") return;
(globalThis as any).dispatchEvent(
new CustomEvent("user-settings-changed", {
detail: { key, value },
}),
);
} catch {
// Ignore - settings should still be applied even if event dispatch fails.
}
}
get(key: string, defaultValue: boolean): boolean {
const value = localStorage.getItem(key);
if (!value) return defaultValue;
@@ -17,6 +31,7 @@ export class UserSettings {
set(key: string, value: boolean) {
localStorage.setItem(key, value ? "true" : "false");
this.emitChange(key, value);
}
getFloat(key: string, defaultValue: number): number {
@@ -31,6 +46,7 @@ export class UserSettings {
setFloat(key: string, value: number) {
localStorage.setItem(key, value.toString());
this.emitChange(key, value);
}
emojis() {