Files
paseo/packages/app/e2e/support/helpers/replica-cache-perf.ts
T
Mohamed BoudraandGitHub b9d7d4b18e Reduce storage writes during agent streaming (#3232)
* perf(app): skip transient replica cache writes

The replica cache subscribed to the entire session store, so live stream-head updates forced repeated JSON serialization and browser storage writes even though the head is not persisted. Select the cache's persisted inputs once and schedule writes only when that projection changes.

* test(app): move perf cleanup into fixture

Keep the replica-cache performance scenario as a direct setup, stream, measure, and assert flow while the spec-local Playwright fixture owns deterministic mock-agent cleanup.
2026-08-11 19:42:51 +02:00

81 lines
2.3 KiB
TypeScript

import type { Page } from "@playwright/test";
const REPLICA_CACHE_STORAGE_KEY = "@paseo:replica-cache";
export interface ReplicaCachePerfReport {
elapsedMs: number;
redundantWrites: number;
serializedChars: number;
storageDurationMs: number;
writes: number;
}
interface ReplicaCachePerfState {
lastValue: string | null;
resetAt: number;
redundantWrites: number;
serializedChars: number;
storageDurationMs: number;
writes: number;
}
declare global {
interface Window {
__replicaCachePerf?: ReplicaCachePerfState;
}
}
export async function observeReplicaCacheWrites(page: Page): Promise<void> {
await page.addInitScript((storageKey) => {
const originalSetItem = Storage.prototype.setItem;
window.__replicaCachePerf = {
lastValue: localStorage.getItem(storageKey),
resetAt: performance.now(),
redundantWrites: 0,
serializedChars: 0,
storageDurationMs: 0,
writes: 0,
};
Storage.prototype.setItem = function measuredSetItem(key: string, value: string): void {
const startedAt = performance.now();
originalSetItem.call(this, key, value);
if (key !== storageKey) return;
const state = window.__replicaCachePerf;
if (!state) return;
if (state.lastValue === value) state.redundantWrites += 1;
state.lastValue = value;
state.writes += 1;
state.serializedChars += value.length;
state.storageDurationMs += performance.now() - startedAt;
};
}, REPLICA_CACHE_STORAGE_KEY);
}
export async function beginReplicaCacheMeasurement(page: Page): Promise<void> {
await page.evaluate(() => {
const lastValue = window.__replicaCachePerf?.lastValue ?? null;
window.__replicaCachePerf = {
lastValue,
resetAt: performance.now(),
redundantWrites: 0,
serializedChars: 0,
storageDurationMs: 0,
writes: 0,
};
});
}
export async function readReplicaCacheMeasurement(page: Page): Promise<ReplicaCachePerfReport> {
return page.evaluate(() => {
const state = window.__replicaCachePerf;
if (!state) throw new Error("Replica cache performance observer is not installed");
return {
elapsedMs: performance.now() - state.resetAt,
redundantWrites: state.redundantWrites,
serializedChars: state.serializedChars,
storageDurationMs: state.storageDurationMs,
writes: state.writes,
};
});
}