5365f41785
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.
50 lines
1.3 KiB
TypeScript
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])
|
|
}
|