Coralogix RUMが初期ネットワークを奪うのを防ぐ

Coralogix RUMはロード中にビーコンを送信し、自身のLCPからネットワークを奪います。代わりにイベントをバッファリングし、ページ非表示時にフラッシュしましょう。

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-06-06

Coralogix RUMが初期ネットワークを奪うのを防ぐ

RUMツールの役割はただ1つ、ユーザーが実際に得る体験を測定することです。しかし、Coralogixはロード中にその逆を行います。initを呼び出した瞬間にビーコンの送信を開始するため、その呼び出しがメインバンドル内にある場合、SDKはロードとハイドレーションのウィンドウに最初のバッチを送信し、まさに測定しようとしているLCPからネットワークを奪ってしまいます。 

このツールは最初に数値を悪化させ、その後でそれを報告します。これは本末転倒です。そのため、データをバッファリングし、ページから離れるときにCoralogix APIに送信する回避策を書きました(Core/Dashはデフォルトでこれを行っているので、より良いRUMツールを探しているなら乗り換えを検討してください)。

Coralogixは自身のページよりも自分が重要だと考えている

そのビーコンが何と競合しているかを見てください。ヒーロー画像。フォント。ページをハイドレーションするスクリプトです。光回線では気付かないかもしれません。しかし、ユーザー全員が光回線を利用しているわけではありません。スマートフォン、電車内、ホテルのWi-Fiなど、帯域幅が限られている環境では、そのビーコンがあなた自身のコンテンツと帯域幅を奪い合います。最も接続状態の悪い訪問者はそれに気付くでしょう。一体何のために??

そして、あなたを悩ませるべき部分がこれです。その初期データすべてを早期に送信する理由は何もありません。皆無です。データは現在進行中の訪問に関するものに過ぎません。誰もそれをライブで読んではいません(もしそうなら、本当に不気味です)。メモリ上に保持しておき、訪問が終了したときに送信すれば、コストもかからず、何も失われません。ロード中に送信することはデメリットしかありません。ページを遅くするだけで、何のメリットもありません。それは馬鹿げています。だから、主導権を取り戻しましょう。すべてのイベントをキャプチャし、訪問が終わるまで何も送信しないのです。

corelogix network and main thread

さて、愚痴はこれくらいにしましょう。修正の時間です。これがCoralogixを正しく動作させる方法です!

すべてをバッファリングし、何も送信しない

CoralogixはbeforeSendフックを提供しています。イベントを返すと送信され、nullを返すと破棄されます。したがって、まずイベントを配列にプッシュし、次にnullを返します。すべてのイベントがキャプチャされ、ネットワーク上には何も送信されません。

import { CoralogixRum } from '@coralogix/browser';

const PUBLIC_KEY = '<YOUR_PUBLIC_KEY>';
const APPLICATION = 'my-app';

// すべてのイベントをキャプチャし、ライブで送信しない。
const buffer = [];

CoralogixRum.init({
  public_key: PUBLIC_KEY,
  application: APPLICATION,
  version: '1.0.0',
  coralogixDomain: 'EU1',
  beforeSend: (event) => {
    buffer.push({ event, t: Date.now() }); // 今タイムスタンプを押し、後でフラッシュする
    return null;                           // SDK自身のビーコンを抑制する
  },
});

ドキュメントを読むとbeforeSendはエラー専用のフィルターのように見えますが、重要なものをキャッチできることを確認しました。そうではありません。初期化スナップショット、リソースのタイミング、すべてのWeb Vitals、ユーザーインタラクション、エラーなど、すべてのイベントタイプに対して発火します。SDKは、ページ全体を測定するという本来の仕事を継続します。フラッシュするように指示するまで、ネットワーク上で静かになるだけです。

終了時にフラッシュする

次に、ページが非表示になったときにバッファを送信します。ここで、単純な実装は失敗します。アンロード時に送信する教科書的な方法であるため、navigator.sendBeaconに手を伸ばすでしょう。しかし、ここでは機能しません。イングレスはAuthorization: Bearerヘッダーで認証を行いますが、sendBeaconはリクエストヘッダーを設定できません。trueを返し、サイレントに403エラーになります。代わりにkeepalive付きのfetchを使用してください。同じようにアンロード後も生き残り、ヘッダーを設定できます。

ビーコンがあなたから隠していたことがもう1つあります。それは、イングレスが生のイベントを受け取らないということです。SDKは各イベントをスパンでラップし、{ logs: [...] }としてPOSTします。したがって、送信する前にその形を再構築してください。

const INGRESS = 'https://ingress.eu1.rum-ingress-coralogix.com/browser/v1beta/logs';
// coralogixDomainに合わせてeu1をお住まいのリージョン(us1, us2, eu2, ap1...)に置き換えてください

// イングレスは生のイベントではなく、SDKのスパンの形を要求します。再構築します。
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); // ドレイン: 2回目の呼び出しでは何も送信されません

  fetch(INGRESS, {
    method: 'POST',
    keepalive: true, // アンロード後も生き残り、sendBeaconとは異なりヘッダーを設定できます
    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はバッファをドレイン(空に)するため、2回目の非表示イベントでは何も送信されません。unloadが発火しないモバイルにおいてすら、非表示へのvisibilitychangeは信頼できるシグナルです。pagehideはそのバックストップ(最後の砦)です。1つ注意点があります。keepaliveは実行中のリクエスト全体で64KBの予算を共有するため、何千ものリソースエントリをバッファリングする長いセッションでは、オーバーフローする可能性があります。大量に収集する場合は、logs配列をいくつかの小さなPOSTに分割(チャンク化)してください。

その代償

あなたは今、Coralogixのフォーマットを手動で再構築しています。注意してください! ここでのsession_contextは、SDK独自のものよりも少し薄くなります。CoralogixはセッションID、ユーザーエージェント、デバイス情報を後から( beforeSendの実行後に)入力するため、手動で構築したスパンには、通常のビーコンよりもこれらの詳細情報が含まれなくなります。Core Web Vitalsのキャプチャには関係ありません。詳細なセッション分析には影響する可能性があります。また、最初のデプロイ時には、ネットワークタブで200が返ってくることを確認してください。キーが間違っていたり、CORSルールが厳格化されていたりすると、ビーコンの時と同じようにサイレントに失敗するからです。

自分が所有していないワイヤーフォーマットを維持することが面倒に思える場合、率直な代替案は、ハイドレーション後までCoralogixRum.init()を遅延させ、そこからSDKに通常通り送信させることです。初期化前のロードメトリクスは失われますが、正気を保つことができます。どちらを取るか選んでください。

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

見張るのをやめた瞬間にパフォーマンスは劣化します。

監視、バジェット、運用プロセスまで組みます。一時的な修正と本当の解決の差はここです。

一度お話ししませんか
Coralogix RUMが初期ネットワークを奪うのを防ぐCore Web Vitals Coralogix RUMが初期ネットワークを奪うのを防ぐ