2020-08-13 17:20:29 +02:00
|
|
|
import {
|
|
|
|
getCLS,
|
|
|
|
getFCP,
|
|
|
|
getFID,
|
|
|
|
getLCP,
|
|
|
|
getTTFB,
|
2020-10-16 10:27:50 +02:00
|
|
|
Metric,
|
2020-08-13 17:20:29 +02:00
|
|
|
ReportHandler,
|
2020-11-04 22:52:49 +01:00
|
|
|
} from 'next/dist/compiled/web-vitals'
|
2020-08-13 17:20:29 +02:00
|
|
|
|
2020-10-16 22:31:09 +02:00
|
|
|
const initialHref = location.href
|
2020-10-16 10:27:50 +02:00
|
|
|
let isRegistered = false
|
|
|
|
let userReportHandler: ReportHandler | undefined
|
|
|
|
|
2021-01-05 16:11:37 +01:00
|
|
|
function onReport(metric: Metric): void {
|
2020-10-16 10:27:50 +02:00
|
|
|
if (userReportHandler) {
|
|
|
|
userReportHandler(metric)
|
|
|
|
}
|
2020-10-16 22:31:09 +02:00
|
|
|
|
|
|
|
// This code is not shipped, executed, or present in the client-side
|
|
|
|
// JavaScript bundle unless explicitly enabled in your application.
|
|
|
|
//
|
|
|
|
// When this feature is enabled, we'll make it very clear by printing a
|
|
|
|
// message during the build (`next build`).
|
|
|
|
if (
|
|
|
|
process.env.NODE_ENV === 'production' &&
|
|
|
|
// This field is empty unless you explicitly configure it:
|
|
|
|
process.env.__NEXT_ANALYTICS_ID
|
|
|
|
) {
|
|
|
|
const body: Record<string, string> = {
|
|
|
|
dsn: process.env.__NEXT_ANALYTICS_ID,
|
|
|
|
id: metric.id,
|
|
|
|
page: window.__NEXT_DATA__.page,
|
|
|
|
href: initialHref,
|
|
|
|
event_name: metric.name,
|
|
|
|
value: metric.value.toString(),
|
|
|
|
speed:
|
|
|
|
'connection' in navigator &&
|
|
|
|
navigator['connection'] &&
|
|
|
|
'effectiveType' in navigator['connection']
|
|
|
|
? (navigator['connection']['effectiveType'] as string)
|
|
|
|
: '',
|
|
|
|
}
|
|
|
|
|
|
|
|
const blob = new Blob([new URLSearchParams(body).toString()], {
|
|
|
|
// This content type is necessary for `sendBeacon`:
|
|
|
|
type: 'application/x-www-form-urlencoded',
|
|
|
|
})
|
2020-11-23 21:08:04 +01:00
|
|
|
const vitalsUrl = 'https://vitals.vercel-insights.com/v1/vitals'
|
2020-10-16 22:31:09 +02:00
|
|
|
;(navigator.sendBeacon && navigator.sendBeacon(vitalsUrl, blob)) ||
|
|
|
|
fetch(vitalsUrl, {
|
|
|
|
body: blob,
|
|
|
|
method: 'POST',
|
|
|
|
credentials: 'omit',
|
|
|
|
keepalive: true,
|
|
|
|
})
|
|
|
|
}
|
2020-10-16 10:27:50 +02:00
|
|
|
}
|
|
|
|
|
2021-01-05 16:11:37 +01:00
|
|
|
export default (onPerfEntry?: ReportHandler): void => {
|
2020-10-16 10:27:50 +02:00
|
|
|
// Update function if it changes:
|
|
|
|
userReportHandler = onPerfEntry
|
|
|
|
|
|
|
|
// Only register listeners once:
|
|
|
|
if (isRegistered) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
isRegistered = true
|
|
|
|
|
|
|
|
getCLS(onReport)
|
|
|
|
getFID(onReport)
|
|
|
|
getFCP(onReport)
|
|
|
|
getLCP(onReport)
|
|
|
|
getTTFB(onReport)
|
2020-08-13 17:20:29 +02:00
|
|
|
}
|