perf(web): add dashboard hydration observability

This commit is contained in:
vince 2026-06-20 14:58:25 +02:00
parent b6de67f081
commit 328f6e00bf
5 changed files with 339 additions and 22 deletions

View file

@ -157,6 +157,8 @@ export interface DashboardViewportHydrationQueueOptions<TItem> {
getModelId: (item: TItem) => string;
hydrate: (item: TItem) => Promise<void> | void;
items: TItem[];
onAllItemsSettled?: () => void;
onVisibleItemsSettled?: () => void;
signal: AbortSignal;
waitForIdle: () => Promise<void>;
}
@ -179,8 +181,13 @@ export async function runViewportAwareDashboardHydrationQueue<TItem>(
items: visible,
signal: options.signal,
});
if (options.signal.aborted) return;
options.onVisibleItemsSettled?.();
if (!deferred.length || options.signal.aborted) return;
if (!deferred.length) {
options.onAllItemsSettled?.();
return;
}
await options.waitForIdle();
if (options.signal.aborted) return;
@ -191,6 +198,7 @@ export async function runViewportAwareDashboardHydrationQueue<TItem>(
items: deferred,
signal: options.signal,
});
options.onAllItemsSettled?.();
}
export function splitDashboardHydrationItemsByVisibility<TItem>(options: {
@ -408,6 +416,51 @@ export function createDashboardRefreshDelay(
};
}
export interface DashboardPerformanceMarkOptions {
mark?: (name: string) => void;
}
export const dashboardPerformanceMarks = {
allTilesSettled: "dashboard:all-tiles-settled",
firstTileReady: "dashboard:first-tile-ready",
shellLoad: "dashboard:shell-load",
visibleTilesReady: "dashboard:visible-tiles-ready",
} as const;
export function createDashboardPerformanceMarks(
options: DashboardPerformanceMarkOptions = {},
) {
const mark = options.mark ||
globalThis.performance?.mark?.bind(globalThis.performance);
let firstTileReadyMarked = false;
function safeMark(name: string) {
try {
mark?.(name);
} catch {
// Performance marks are diagnostics only.
}
}
return {
markAllTilesSettled(): void {
safeMark(dashboardPerformanceMarks.allTilesSettled);
},
markFirstTileReady(): void {
if (firstTileReadyMarked) return;
firstTileReadyMarked = true;
safeMark(dashboardPerformanceMarks.firstTileReady);
},
markShellLoad(): void {
firstTileReadyMarked = false;
safeMark(dashboardPerformanceMarks.shellLoad);
},
markVisibleTilesReady(): void {
safeMark(dashboardPerformanceMarks.visibleTilesReady);
},
};
}
const dashboardTileBackoffDelaysMs = [15_000, 30_000, 60_000, 120_000];
export function createDashboardTileBackoff() {