mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-12 07:09:59 +00:00
fix(studio): prevent negative timeline latency telemetry (#2905)
This commit is contained in:
@@ -1,7 +1,28 @@
|
|||||||
// @vitest-environment happy-dom
|
// @vitest-environment happy-dom
|
||||||
|
|
||||||
import { describe, expect, it } from "vitest";
|
import { act, createElement } from "react";
|
||||||
import { summarizeTimelinePerformance } from "./useTimelinePerformanceTelemetry";
|
import { createRoot } from "react-dom/client";
|
||||||
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
const trackStudioTimelinePerformance = vi.hoisted(() => vi.fn());
|
||||||
|
|
||||||
|
vi.mock("../../telemetry/events", () => ({
|
||||||
|
trackStudioTimelinePerformance,
|
||||||
|
}));
|
||||||
|
|
||||||
|
import {
|
||||||
|
summarizeTimelinePerformance,
|
||||||
|
useTimelinePerformanceTelemetry,
|
||||||
|
} from "./useTimelinePerformanceTelemetry";
|
||||||
|
|
||||||
|
Reflect.set(globalThis, "IS_REACT_ACT_ENVIRONMENT", true);
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
trackStudioTimelinePerformance.mockReset();
|
||||||
|
vi.useRealTimers();
|
||||||
|
vi.restoreAllMocks();
|
||||||
|
vi.unstubAllGlobals();
|
||||||
|
});
|
||||||
|
|
||||||
describe("summarizeTimelinePerformance", () => {
|
describe("summarizeTimelinePerformance", () => {
|
||||||
it("reports raw mounted work and p95 scroll timings", () => {
|
it("reports raw mounted work and p95 scroll timings", () => {
|
||||||
@@ -52,3 +73,48 @@ describe("summarizeTimelinePerformance", () => {
|
|||||||
).toBeNull();
|
).toBeNull();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("useTimelinePerformanceTelemetry", () => {
|
||||||
|
it("measures callback delivery when the animation-frame timestamp predates the scroll", () => {
|
||||||
|
vi.useFakeTimers();
|
||||||
|
let frameCallback: FrameRequestCallback | undefined;
|
||||||
|
vi.stubGlobal("requestAnimationFrame", (callback: FrameRequestCallback) => {
|
||||||
|
frameCallback = callback;
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
vi.stubGlobal("cancelAnimationFrame", vi.fn());
|
||||||
|
|
||||||
|
let recordTimelineScroll: ((scroll: HTMLDivElement) => void) | undefined;
|
||||||
|
function Probe() {
|
||||||
|
recordTimelineScroll = useTimelinePerformanceTelemetry({
|
||||||
|
totalClipCount: 1,
|
||||||
|
totalRowCount: 1,
|
||||||
|
zoomMode: "manual",
|
||||||
|
}).recordTimelineScroll;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const root = createRoot(document.createElement("div"));
|
||||||
|
act(() => root.render(createElement(Probe)));
|
||||||
|
|
||||||
|
try {
|
||||||
|
vi.spyOn(performance, "now")
|
||||||
|
.mockReturnValueOnce(100)
|
||||||
|
.mockReturnValueOnce(108)
|
||||||
|
.mockReturnValueOnce(500);
|
||||||
|
|
||||||
|
recordTimelineScroll?.(document.createElement("div"));
|
||||||
|
frameCallback?.(99);
|
||||||
|
vi.advanceTimersByTime(400);
|
||||||
|
|
||||||
|
expect(trackStudioTimelinePerformance).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
scroll_frame_latency_p95_ms: 8,
|
||||||
|
scroll_frame_latency_max_ms: 8,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
act(() => root.unmount());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export function useTimelinePerformanceTelemetry(context: TimelinePerformanceCont
|
|||||||
state.pendingScrollStartedAt = now;
|
state.pendingScrollStartedAt = now;
|
||||||
state.frameRequest = requestAnimationFrame((frameAt) => {
|
state.frameRequest = requestAnimationFrame((frameAt) => {
|
||||||
state.frameRequest = 0;
|
state.frameRequest = 0;
|
||||||
state.frameLatencies.push(frameAt - state.pendingScrollStartedAt);
|
state.frameLatencies.push(performance.now() - state.pendingScrollStartedAt);
|
||||||
if (state.previousFrameAt !== null) {
|
if (state.previousFrameAt !== null) {
|
||||||
state.frameIntervals.push(frameAt - state.previousFrameAt);
|
state.frameIntervals.push(frameAt - state.previousFrameAt);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user