Voorkom dat Coralogix RUM je vroege netwerk steelt
Coralogix RUM stuurt beacons tijdens het laden en steelt netwerk van je eigen LCP. Buffer de events en verstuur ze in plaats daarvan bij page hide.

Voorkom dat Coralogix RUM je vroege netwerk steelt
Een RUM tool heeft één taak: meten welke ervaring je gebruikers daadwerkelijk krijgen. Coralogix doet tijdens het laden het tegenovergestelde. Het begint met het versturen van beacons op het moment dat je init aanroept. Dus als die call in je main bundle zit, vuurt de SDK zijn eerste batch af in de load- en hydration-fase en steelt het bandbreedte van precies de LCP die het wordt verondersteld te meten.
De tool schaadt eerst het cijfer en rapporteert het vervolgens. Dat is de omgekeerde wereld. Daarom schrijf ik een workaround die de data buffert en pas bij het verlaten van de pagina naar de Coralogix API stuurt (precies zoals CoreDash standaard doet, dus als je een betere RUM tool zoekt, overweeg dan om over te stappen).
Coralogix denkt dat het belangrijker is dan jouw pagina
Kijk waar die beacon mee concurreert. Je hero image. Je fonts. Het script dat de pagina hydrateert. Op een glasvezelverbinding merk je hier misschien nooit iets van. Maar je gebruikers zitten niet allemaal op glasvezel. Op een telefoon, in een trein, op hotel wifi is bandbreedte schaars, en die beacon vecht daarvoor met je eigen content. De bezoekers met de slechtste verbindingen zullen dit merken. En waarvoor??
En hier is het deel dat je zou moeten storen: er is geen enkele reden voor al die vroege data. Geen enkele. De data gaat over een bezoek dat nog steeds gaande is. Niemand zit dit live te lezen (en als ze dat wel doen, zou dat echt eng zijn). Het kan in het geheugen blijven staan en pas worden verstuurd als het bezoek eindigt, zonder dat het iets kost of data verloren gaat. Het versturen tijdens het laden kent alleen maar nadelen. Het kan de pagina slechts vertragen en het levert je niets op. Dat is dom. Neem dus de controle terug: vang elk event af, maar stuur ze pas als het bezoek voorbij is.

Oké, genoeg geklaagd. Tijd om het op te lossen. Dit is hoe je Coralogix zich correct laat gedragen!
Buffer alles, verstuur niets
Coralogix geeft je een beforeSend hook. Retourneer het event en het wordt verstuurd. Retourneer null en het wordt gedropt. Push het event dus eerst in een array en retourneer vervolgens null. Elk event wordt vastgelegd, niets gaat over de lijn.
import { CoralogixRum } from '@coralogix/browser';
const PUBLIC_KEY = '<YOUR_PUBLIC_KEY>';
const APPLICATION = 'my-app';
// Vang elk event af, stuur ze niet live door.
const buffer = [];
CoralogixRum.init({
public_key: PUBLIC_KEY,
application: APPLICATION,
version: '1.0.0',
coralogixDomain: 'EU1',
beforeSend: (event) => {
buffer.push({ event, t: Date.now() }); // stamp nu, flush later
return null; // onderdruk de eigen beacon van de SDK
},
});
Ik heb gecontroleerd of dit de belangrijke zaken afvangt, want beforeSend leest in de documentatie als een filter dat alleen voor errors bedoeld is. Dat is het niet. Het vuurt voor elk event type: de init snapshot, resource timing, elke Core Web Vitals metric, user interactions, en errors. De SDK blijft gewoon zijn echte werk doen: het meten van de volledige pagina. Het blijft alleen stil op het netwerk totdat jij zegt dat het moet flushen.
Flush het bij het verlaten van de pagina
Verstuur nu de buffer wanneer de pagina wordt verborgen. Dit is waar de naïeve versie faalt. Je grijpt naar navigator.sendBeacon, omdat dat de klassieke manier is om te verzenden bij een unload. Dat werkt hier niet. De ingress authenticeert met een Authorization: Bearer header, en sendBeacon kan geen request headers instellen. Het retourneert true en geeft stilzwijgend een 403. Gebruik in plaats daarvan fetch met keepalive. Het overleeft de unload op dezelfde manier en het laat je de header wél instellen.
Nog iets wat de beacon voor je verborg: de ingress accepteert geen ruwe events. De SDK wikkelt elk event in een span en post { logs: [...] }. Bouw die structuur dus opnieuw op voordat je deze verstuurt.
const INGRESS = 'https://ingress.eu1.rum-ingress-coralogix.com/browser/v1beta/logs';
// vervang eu1 door jouw regio (us1, us2, eu2, ap1...) zodat het overeenkomt met coralogixDomain
// De ingress verwacht de span-structuur van de SDK, geen ruwe events. Bouw deze opnieuw op.
function toCxSpan({ event, t }) {
const hasStack = !!(event.error_context
&& event.error_context.original_stacktrace
&& event.error_context.original_stacktrace.length);
return {
version_metadata: event.version_metadata,
applicationName: APPLICATION,
subsystemName: 'cx_rum',
severity: (event.event_context && event.event_context.severity) || 3,
isErrorWithStacktrace: hasStack,
timestamp: t,
text: { cx_rum: Object.assign({}, event, { timestamp: t }) },
};
}
function flush() {
if (!buffer.length) return;
const logs = buffer.splice(0).map(toCxSpan); // drain: een tweede aanroep verstuurt niets
fetch(INGRESS, {
method: 'POST',
keepalive: true, // overleeft unload, en in tegenstelling tot sendBeacon kan het wel headers instellen
headers: {
'Authorization': 'Bearer ' + PUBLIC_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ logs, skip_enrichment_with_ip: false }),
}).catch(function () {});
}
document.addEventListener('visibilitychange', function () {
if (document.visibilityState === 'hidden') flush();
});
window.addEventListener('pagehide', flush);
splice leegt de buffer, dus een tweede hidden event verstuurt niets. visibilitychange naar hidden is het betrouwbare signaal, zelfs op mobiel waar unload nooit vuurt. pagehide is de back-up. Eén kanttekening: keepalive deelt een budget van 64KB over actieve in-flight requests, dus een lange sessie die duizenden resource entries buffert kan dit laten overstromen. Als je zwaar verzamelt, deel de logs array dan op in een paar kleinere posts.
Wat het kost
Je bouwt nu het formaat van Coralogix handmatig opnieuw op, wees voorzichtig! De session_context is iets beknopter dan die van de SDK zelf. Coralogix vult de session id, user agent en het device in nadat beforeSend draait, dus je handgemaakte spans bevatten minder van die details dan een normale beacon zou hebben. Voor het vastleggen van Core Web Vitals maakt dit niet uit. Voor diepgaande session analytics misschien wel. Controleer bij de eerste deploy ook of je een 200 krijgt in je Network tab, want een verkeerde key of een aangescherpte CORS rule faalt op dezelfde stille manier als de beacon deed.
Als het onderhouden van een wire format dat niet van jou is klinkt als een slecht idee, dan is het botte alternatief om CoralogixRum.init() uit te stellen tot na de hydratatie en de SDK vanaf daar normaal te laten verzenden. Je verliest de pre-init laadstatistieken, maar je behoudt je gezond verstand. Kies je compromis.
CoreDash heeft MCP ingebouwd.
Hang 'm aan Claude of een andere AI agent. Vraag waarom je INP vorige dinsdag piekte.
Zo werkt het
