rsnext/packages/next/client/streaming/vitals.ts
Jiachi Liu 5365f41785
Group streaming experimental apis (#33878)
Move undocumented `next/rsc` and `next/vitals` to `next/streaming`. In the future `next/streaming` can contain streaming SSR related (including react server components) APIs together.
2022-02-02 13:42:14 +00:00

50 lines
1.3 KiB
TypeScript

import { useEffect, useRef } from 'react'
import { NextWebVitalsMetric } from '../../pages/_app'
type ReportWebVitalsCallback = (webVitals: NextWebVitalsMetric) => any
export const webVitalsCallbacks = new Set<ReportWebVitalsCallback>()
let flushed = false
const metrics: NextWebVitalsMetric[] = []
export function getBufferedVitalsMetrics() {
return metrics
}
export function flushBufferedVitalsMetrics() {
flushed = true
metrics.length = 0
}
export function trackWebVitalMetric(metric: NextWebVitalsMetric) {
metrics.push(metric)
webVitalsCallbacks.forEach((callback) => callback(metric))
}
export function useWebVitalsReport(callback: ReportWebVitalsCallback) {
const metricIndexRef = useRef(0)
if (process.env.NODE_ENV === 'development') {
if (flushed) {
console.error(
'The `useWebVitalsReport` hook was called too late -- did you use it inside of a <Suspense> boundary?'
)
}
}
useEffect(() => {
// Flush calculated metrics
const reportMetric = (metric: NextWebVitalsMetric) => {
callback(metric)
metricIndexRef.current = metrics.length
}
for (let i = metricIndexRef.current; i < metrics.length; i++) {
reportMetric(metrics[i])
}
webVitalsCallbacks.add(reportMetric)
return () => {
webVitalsCallbacks.delete(reportMetric)
}
}, [callback])
}