0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-02-24 22:46:02 -05:00
astro/packages/integrations/web-vitals/src/client-script.ts
2024-05-18 16:33:14 +02:00

36 lines
1.1 KiB
TypeScript

import { type Metric, onCLS, onFCP, onINP, onLCP, onTTFB } from 'web-vitals';
import { WEB_VITALS_ENDPOINT_PATH } from './constants.js';
import type { ClientMetric } from './schemas.js';
const pathname = location.pathname.replace(/(?<=.)\/$/, '');
const route =
document
.querySelector<HTMLMetaElement>('meta[name="x-astro-vitals-route"]')
?.getAttribute('content') || pathname;
const queue = new Set<Metric>();
const addToQueue = (metric: Metric) => queue.add(metric);
function flushQueue() {
if (!queue.size) return;
const rawBody: ClientMetric[] = [...queue].map(({ name, id, value, rating }) => ({
pathname,
route,
name,
id,
value,
rating,
}));
const body = JSON.stringify(rawBody);
if (navigator.sendBeacon) navigator.sendBeacon(WEB_VITALS_ENDPOINT_PATH, body);
else fetch(WEB_VITALS_ENDPOINT_PATH, { body, method: 'POST', keepalive: true });
queue.clear();
}
for (const listener of [onCLS, onLCP, onINP, onFCP, onTTFB]) {
listener(addToQueue);
}
addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') flushQueue();
});
addEventListener('pagehide', flushQueue);