Impedisci a Coralogix RUM di rubare la tua rete iniziale
Coralogix RUM invia beacon durante il caricamento e ruba rete al tuo stesso LCP. Metti in buffer gli eventi e inviali invece al page hide.

Impedisci a Coralogix RUM di rubare la tua rete iniziale
Uno strumento RUM ha un solo compito: misurare l'esperienza che i tuoi utenti ottengono realmente. Coralogix fa l'opposto durante il caricamento. Inizia a inviare beacon non appena chiami init, quindi se quella chiamata si trova nel tuo bundle principale, l'SDK lancia il suo primo batch nella finestra di caricamento e idratazione e ruba rete proprio al LCP che dovrebbe misurare.
Lo strumento prima peggiora il numero, poi lo riporta. Questo è un controsenso. Quindi ho scritto un workaround che mette in buffer i dati e li invia all'API di Coralogix all'abbandono della pagina (proprio come fa Core/Dash per impostazione predefinita, quindi se stai cercando uno strumento RUM migliore considera di cambiare).
Coralogix pensa di essere più importante della tua pagina
Guarda con cosa sta competendo quel beacon. La tua hero image. I tuoi font. Lo script che idrata la pagina. Su fibra potresti non accorgertene mai. Ma i tuoi utenti non sono tutti su fibra. Su un telefono, su un treno, sul wifi di un hotel, la larghezza di banda è scarsa e quel beacon combatte con i tuoi stessi contenuti per ottenerla. I visitatori con le connessioni peggiori se ne accorgeranno. E per cosa??
Ed ecco la parte che dovrebbe infastidirti: non c'è alcun motivo per tutti quei dati iniziali. Nessuno. I dati riguardano semplicemente una visita che è ancora in corso. Nessuno li sta leggendo dal vivo (e se lo facessero sarebbe davvero inquietante). Possono restare in memoria ed essere inviati quando la visita finisce, a costo zero e senza perdere nulla. Inviarli durante il caricamento ha solo svantaggi. Può solo rallentare la pagina e non ti fa guadagnare nulla. È stupido. Quindi riprenditi il controllo: cattura ogni evento, non inviarne nessuno finché la visita non è terminata.

D'accordo, fine delle lamentele. È ora di risolvere. Ecco come far comportare correttamente Coralogix!
Metti tutto in buffer, non inviare nulla
Coralogix ti fornisce un hook beforeSend. Restituisci l'evento e viene inviato. Restituisci null e viene scartato. Quindi prima inserisci l'evento in un array, poi restituisci null. Ogni evento catturato, nulla sulla rete.
import { CoralogixRum } from '@coralogix/browser';
const PUBLIC_KEY = '<YOUR_PUBLIC_KEY>';
const APPLICATION = 'my-app';
// Capture every event, send none of them live.
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 now, flush later
return null; // suppress the SDK's own beacon
},
}); Ho verificato che questo catturi ciò che conta, perché nella documentazione beforeSend sembra un filtro solo per gli errori. Non lo è. Si attiva per ogni tipo di evento: lo snapshot iniziale, il resource timing, ogni web vital, le user interactions e gli errori. L'SDK continua a fare il suo vero lavoro, misurando l'intera pagina. Rimane semplicemente silenzioso sulla rete finché non gli dici di effettuare il flush.
Effettua il flush all'uscita
Ora invia il buffer quando la pagina è nascosta. È qui che la versione ingenua fallisce. Provi a usare navigator.sendBeacon, perché è il modo da manuale per inviare su unload. Qui non funziona. L'ingresso si autentica con un header Authorization: Bearer e sendBeacon non può impostare gli header della richiesta. Restituisce true e dà un errore 403 in silenzio. Usa invece fetch con keepalive. Sopravvive all'unload allo stesso modo e ti permette di impostare l'header.
Un'altra cosa che il beacon ti ha nascosto: l'ingresso non accetta eventi grezzi. L'SDK racchiude ciascuno in uno span e invia tramite post { logs: [...] }. Quindi ricostruisci quella forma prima di inviare.
const INGRESS = 'https://ingress.eu1.rum-ingress-coralogix.com/browser/v1beta/logs';
// swap eu1 for your region (us1, us2, eu2, ap1...) to match coralogixDomain
// The ingress wants the SDK's span shape, not raw events. Rebuild it.
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: a second call sends nothing
fetch(INGRESS, {
method: 'POST',
keepalive: true, // survives unload, and unlike sendBeacon it can set headers
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 svuota il buffer, quindi un secondo evento hidden non invia nulla. visibilitychange ad hidden è il segnale affidabile, anche su mobile dove unload non si attiva mai. pagehide è la riserva. Un avvertimento: keepalive condivide un budget di 64KB tra le richieste in volo, quindi una lunga sessione che mette in buffer migliaia di resource entries può farlo traboccare. Se raccogli molti dati, suddividi l'array logs in alcuni post più piccoli.
Quanto costa
Ora stai ricostruendo a mano il formato di Coralogix, fai attenzione! Il session_context è un po' più scarno rispetto a quello dell'SDK stesso. Coralogix inserisce il session id, lo user agent e il device dopo l'esecuzione di beforeSend, quindi i tuoi span costruiti a mano portano meno di quei dettagli rispetto a un normale beacon. Per la cattura dei Core Web Vitals non importa. Per analisi profonde della sessione potrebbe. E conferma un 200 nella tua scheda Network al primo deploy, perché una chiave sbagliata o una regola CORS più restrittiva falliscono nello stesso modo silenzioso del beacon.
Se mantenere un formato di rete di cui non sei proprietario ti sembra una cattiva idea, l'alternativa drastica è posticipare CoralogixRum.init() fino a dopo l'idratazione e lasciare che l'SDK invii normalmente da lì in poi. Perdi le metriche di caricamento pre-init, ma mantieni la tua sanità mentale. Fai la tua scelta.
CoreDash ha MCP integrato.
Collegalo a Claude o a un AI agent. Gli chiedi perché l'INP è schizzato martedì scorso e te lo dice lui.
Guarda come funziona
