Impeça o Coralogix RUM de roubar sua rede inicial
O Coralogix RUM envia beacons durante o carregamento e rouba banda do seu próprio LCP. Em vez disso, coloque os eventos em buffer e envie-os ao ocultar a página.

Impeça o Coralogix RUM de roubar sua rede inicial
Uma ferramenta de RUM tem apenas um trabalho: medir a experiência real que seus usuários têm. O Coralogix faz o oposto durante o carregamento. Ele começa a enviar beacons no instante em que você chama o init. Se essa chamada estiver no seu bundle principal, o SDK dispara seu primeiro lote na janela de carregamento e hidratação, roubando banda da rede do próprio LCP que ele deveria estar medindo.
A ferramenta primeiro estraga a métrica, depois a reporta. Isso é um contrassenso. Por isso, criei uma solução alternativa que coloca os dados em buffer e os envia para a API do Coralogix ao sair da página (exatamente como o Core/Dash faz por padrão — se você estiver procurando uma ferramenta de RUM melhor, considere mudar).
O Coralogix acha que é mais importante do que sua página
Olhe com o que esse beacon compete. Sua imagem principal. Suas fontes. O script que hidrata a página. Na fibra, você talvez nunca perceba. Mas seus usuários não estão todos na fibra. No celular, no trem, no Wi-Fi do hotel, a banda é escassa, e esse beacon briga com seu próprio conteúdo por ela. Os visitantes nas piores conexões vão notar. E para quê??
E aqui está a parte que deveria incomodar você: não há motivo algum para todos esses dados iniciais. Nenhum. Os dados são apenas sobre uma visita que ainda está acontecendo. Ninguém está lendo isso ao vivo (e, se estiverem, seria muito bizarro). Eles podem ficar na memória e ser enviados quando a visita terminar — sem custo e sem perda. Enviar durante o carregamento só traz desvantagens. Só deixa a página lenta e não traz benefício algum. Isso é burrice. Então retome o controle: capture todos os eventos, não envie nenhum até que a visita termine.

Chega de desabafos. Hora de corrigir. É assim que você faz o Coralogix se comportar da forma certa!
Coloque tudo em buffer, não envie nada
O Coralogix oferece um gancho beforeSend. Retorne o evento e ele será enviado. Retorne null e ele será descartado. Então, primeiro adicione o evento a um array e, em seguida, retorne null. Cada evento é capturado, e nada vai para a rede.
import { CoralogixRum } from '@coralogix/browser';
const PUBLIC_KEY = '<YOUR_PUBLIC_KEY>';
const APPLICATION = 'my-app';
// Capture todos os eventos, não envie nenhum ao vivo.
const buffer = [];
CoralogixRum.init({
public_key: PUBLIC_KEY,
application: APPLICATION,
version: '1.0.0',
coralogixDomain: 'EU1',
beforeSend: (event) => {
buffer.push({ event, t: Date.now() }); // registra a hora agora, faz o flush depois
return null; // suprime o beacon do próprio SDK
},
}); Eu verifiquei se isso captura o que importa, pois o beforeSend parece um filtro apenas para erros na documentação. Não é. Ele é disparado para todo tipo de evento: o snapshot do init, resource timing, cada Core Web Vital, interações do usuário e erros. O SDK continua fazendo seu trabalho real, medindo a página inteira. Ele apenas fica em silêncio na rede até você mandar fazer o flush.
Faça o flush na saída
Agora, envie o buffer quando a página for ocultada. É aqui que a versão ingênua falha. Você tenta usar o navigator.sendBeacon, porque é a forma clássica de enviar dados no unload. Não funciona aqui. O ingress autentica com um cabeçalho Authorization: Bearer, e o sendBeacon não permite definir cabeçalhos de requisição. Ele retorna true e falha silenciosamente com 403. Use fetch com keepalive em vez disso. Ele sobrevive ao unload da mesma forma e permite definir o cabeçalho.
Outro detalhe que o beacon escondeu de você: o ingress não aceita eventos puros. O SDK envelopa cada um em um span e envia um POST com { logs: [...] }. Então, recrie essa estrutura antes de enviar.
const INGRESS = 'https://ingress.eu1.rum-ingress-coralogix.com/browser/v1beta/logs';
// troque eu1 pela sua região (us1, us2, eu2, ap1...) para corresponder ao coralogixDomain
// O ingress espera o formato de span do SDK, não eventos puros. Reestruture.
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); // esvazia o buffer: uma segunda chamada não envia nada
fetch(INGRESS, {
method: 'POST',
keepalive: true, // sobrevive ao unload e, ao contrário do sendBeacon, permite definir cabeçalhos
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); O splice esvazia o buffer, então um segundo evento de ocultação não envia nada. O visibilitychange para oculto é o sinal confiável, mesmo no celular, onde o unload nunca dispara. O pagehide funciona como garantia. Uma ressalva: o keepalive compartilha um limite de 64 KB entre requisições em andamento. Uma sessão longa que acumula milhares de registros de recursos no buffer pode estourá-lo. Se você coleta muitos dados, divida o array de logs em alguns envios menores.
O custo disso
Você agora está recriando o formato do Coralogix manualmente. Cuidado! O session_context fica um pouco mais enxuto do que o padrão do SDK. O Coralogix preenche o ID da sessão, o user agent e o dispositivo depois que o beforeSend executa. Por isso, seus spans manuais carregam menos detalhes do que um beacon comum. Para capturar os Core Web Vitals, isso não faz diferença. Para análises profundas de sessão, talvez faça. E confirme o status 200 na aba Network no primeiro deploy; uma chave errada ou uma regra de CORS restrita falharão silenciosamente, assim como o beacon original.
Se manter um formato de comunicação que você não controla parece uma dor de cabeça, a alternativa direta é adiar o CoralogixRum.init() para depois da hidratação e deixar o SDK fazer o envio normal dali em diante. Você perde as métricas de carregamento anteriores à inicialização, mas mantém sua sanidade. Faça sua escolha.
Descobre o que é mesmo lento.
Mapeio o critical rendering path com dados RUM. Recebes uma lista de fixes por prioridade, não um relatório do Lighthouse.
Quero a auditoria
