From 8a3f36bd79affbe09e83f6612b950a9474c3f687 Mon Sep 17 00:00:00 2001 From: Tyler Dixon Date: Tue, 7 Jul 2026 14:17:02 -0700 Subject: [PATCH 1/2] fix: use globalThis.performance in SuspenseWithPerf to avoid SSR crash --- src/performance.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/performance.tsx b/src/performance.tsx index 92ab587b..d71b7f15 100644 --- a/src/performance.tsx +++ b/src/performance.tsx @@ -9,17 +9,18 @@ export interface SuspensePerfProps { export function SuspenseWithPerf({ children, traceId, fallback }: SuspensePerfProps): JSX.Element { // TODO: Should this import firebase/performance? - const entries = performance?.getEntriesByName?.(traceId, 'measure') || []; + const perf = typeof globalThis !== 'undefined' ? globalThis.performance : undefined; + const entries = perf?.getEntriesByName?.(traceId, 'measure') || []; const startMarkName = `_${traceId}Start[${entries.length}]`; const endMarkName = `_${traceId}End[${entries.length}]`; const Fallback = () => { React.useLayoutEffect(() => { - performance?.mark?.(startMarkName); + perf?.mark?.(startMarkName); return () => { - performance?.mark?.(endMarkName); - performance?.measure?.(traceId, startMarkName, endMarkName); + perf?.mark?.(endMarkName); + perf?.measure?.(traceId, startMarkName, endMarkName); }; }, []); From 7ab64d49498af0336022ad465305f10e0f34742e Mon Sep 17 00:00:00 2001 From: Tyler Dixon Date: Tue, 7 Jul 2026 14:39:41 -0700 Subject: [PATCH 2/2] fix: use useEffect instead of useLayoutEffect in SuspenseWithPerf useLayoutEffect triggers a React warning on the server. Since performance marks don't require synchronous DOM layout reads, useEffect is sufficient and avoids the SSR warning. --- src/performance.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/performance.tsx b/src/performance.tsx index d71b7f15..78a0455c 100644 --- a/src/performance.tsx +++ b/src/performance.tsx @@ -15,7 +15,7 @@ export function SuspenseWithPerf({ children, traceId, fallback }: SuspensePerfPr const endMarkName = `_${traceId}End[${entries.length}]`; const Fallback = () => { - React.useLayoutEffect(() => { + React.useEffect(() => { perf?.mark?.(startMarkName); return () => {