Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion frontend/src/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,18 @@ const theme = extendTheme({
},
});

/**
* Wraps the application UI with a ChakraProvider using the project theme and initializes web vitals on mount.
*
* Calls `initWebVitals` once when mounted to start web vitals collection.
*
* @param children - The React node(s) to render within the themed provider
* @returns The React element tree where `children` are wrapped by a `ChakraProvider` configured with the module theme
*/
export function Providers({ children }: { children: React.ReactNode }) {
useEffect(() => {
initWebVitals();
}, []);

return <ChakraProvider theme={theme}>{children}</ChakraProvider>;
}
}
13 changes: 13 additions & 0 deletions frontend/src/app/web-vitals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ function scheduleFlush() {
}, FLUSH_INTERVAL_MS)
}

/**
* Sends all queued web-vital and navigation-timing events to the server and clears the in-memory queue.
*
* If the queue is empty this is a no-op. Attempts to deliver using `navigator.sendBeacon` when available;
* otherwise falls back to a POST request with `keepalive`. On network failure, logs a warning in non-production
* environments and restores the events to the front of the queue so they are not lost.
*/
async function flushQueue() {
if (queue.length === 0) {
return
Expand Down Expand Up @@ -223,6 +230,12 @@ function installLifecycleFlush() {
window.addEventListener('beforeunload', flush)
}

/**
* Initializes collection and reporting of web-vitals and navigation timing data.
*
* This function is idempotent: calling it multiple times has no additional effect.
* It is a no-op outside of a browser environment.
*/
export function initWebVitals() {
if (typeof window === 'undefined') {
return
Expand Down
Loading