Core Web Vitalsが完璧なチャットウィジェット
PageSpeedを低下させずにチャットウィジェットを読み込む
チャットウィジェットを正しく読み込む方法
何度も言っていることです。スクリプトには重要度の違いがあります。ページの読み込み開始から最初の500msでチャットウィジェットが読み込まれなかったからといって、イライラした人はインターネットの歴史上誰もいません。ページがまだ真っ白な時間帯のことです。
メインコンテンツの読み込みが始まる前にチャットウィジェットを読み込むのは理にかなっていません。まずは最も重要な要素(ロゴ、メイン画像、スタイルシート、フォント、ナビゲーションやコンバージョンを処理する非常に重要なスクリプト)を読み込む方がはるかに合理的です。
調査によると、セッション中に実際にチャットウィジェットを使用する訪問者はわずか3〜10パーセントです。チャットスクリプトを遅延させてもユーザーエクスペリエンスが損なわれることはなく、ページ速度の面ですべてのメリットを得られます。
残念ながら、大半のウェブサイトはこのように実装されていません。(チャットスクリプトのような)重要ではないスクリプトが、ページ読み込みの直後に最も高い優先度で読み込まれるのを日常的に目にします。
この記事では、チャットスクリプトを正しく読み込む方法と、それがLargest Contentful PaintやInteraction to Next Paintのような重要な指標にどう影響するかを説明します。
最終レビュー: Arjen Karel(2026年2月)
Table of Contents!
背景: チャットウィジェットの仕組み
チャットウィジェットは通常、ページに小さなスクリプトを読み込むことで機能します。そのスクリプトがいくつかのスタイルを読み込み、ページにiframeを挿入します。iframeはページ内の小さな独立したウェブページです。そして、そのiframeが顧客とのチャットに必要なすべての処理を行います。
チャットウィジェットはCore Web Vitalsにどう影響するか?
チャットウィジェットは、いくつかの方法でCore Web Vitalsに影響を与えます。
1. 初期のネットワークリソースを競合し、First Contentful PaintとLargest Contentful Paintに影響を与えます。
2. main threadをブロックし、またインタラクション後の更新が遅延することでInteraction to Next Paintに影響を与えます。
3. ページ上で正しくレンダリングされないと、レイアウトシフトを引き起こす可能性があります。
その影響はプロバイダー間で大きく異なります。最も重いチャットウィジェット(Zendesk、Tawk.to)は500〜750KBのJavaScriptを読み込みます。Zoho DeskやCrispなどの軽量な代替手段は155KB未満に収まります。平均して、チャットウィジェットは300〜600msのmain threadのブロック時間を追加します。これは、本来なら合格レベルのINPスコアを「改善が必要」の範囲に押し下げるのに十分な時間です。
チャットウィジェットが引き起こすLargest Contentful Paintの問題
チャットウィジェットがネットワークリソースを競合すると、Core Web Vitalsに影響を与えます。JavaScriptファイルは通常、画像よりも早くダウンロードのキューに入れられます。つまり最悪のシナリオ(チャットスクリプトがrender blockingな場合)では、ブラウザは他の処理を続行する前にチャットスクリプトのダウンロードと実行を待たなければなりません。render blockingなチャットウィジェットは、First Contentful Paintを1.0秒から2.3秒以上に倍増させる可能性があります。
チャットスクリプトを遅延させても、いくつかの点でペイント指標に影響を与えます。まず、遅延スクリプトの動作を説明します。ブラウザは遅延スクリプトを並行してダウンロードし、DOMContentLoadedイベントが発生するまでレンダリングを続行できます。その後、スクリプトを実行します。問題は、リピート訪問者の場合、LCP要素はおそらくDOMContentLoadedイベントの時点では読み込まれておらず、(キャッシュされた)チャットスクリプトが実行されてLCP指標の遅延を引き起こすことです。
チャットウィジェットが引き起こすInteraction to Next Paint (INP)の問題
チャットウィジェットは、2つの方法でInteraction to Next Paintに確実な影響を与えます。1つ目は、チャットウィジェットがスクリプトを実行したり更新を確認したりする際に、main threadを短時間ブロックすることです。これは仕組み上避けられません。ページに追加するすべての要素は、ページを少し遅くします。
INPの問題を引き起こす2つ目の理由は、粗悪なコードです(信じてください、ひどいコードのチャットウィジェットは存在します)。チャットウィジェットに関して言えば、「より人気がある」ことは「より良いコード」であることを意味しません。粗悪なコードが画面の更新に時間がかかると、必然的にINPの問題が発生します。一部のチャットプロバイダーは改善が必要です。残念ながら、この部分は私の管理外です。粗悪なコードのチャットウィジェットを選んでしまった場合、私がそのコードを改善する方法はありません。
チャットウィジェットが引き起こすレイアウトシフト(CLS)の問題
チャットウィジェットはレイアウトシフトを引き起こすことがあります。チャットウィジェットに関連するレイアウトシフトを調査する際、私はよく次の3つの原因を疑います。
- チャットの読み込み時に毎回発生するレイアウトシフト
- 遅延した「チャットを開く」動作で発生するレイアウトシフト
- チャット履歴が読み込まれた時に発生するレイアウトシフト(リピート訪問者)
チャットスクリプトによるCore Web Vitalsの問題を修正する方法
幸いなことに、チャットウィジェットがペイント指標(LCPとFCP)やInteraction to Next Paint (INP)の一部に与える影響を最小限に抑えるのは非常に簡単です。冒頭で述べたように、スクリプトには適切なタイミングと場所があります。チャットスクリプトの場合、それは「何が何でも今すぐ」ではありません。私はチャットスクリプトを、loadイベントの後で、ページがユーザー入力に応答していないときに読み込みます。また、ネットワークの競合を避けるためにプリロードスキャナをバイパスすることも好みます。
では、どうすればよいでしょうか?loadイベントを使用するのは、loadイベントが発火した時点でLCP要素がページにペイントされているからです(JavaScriptでlazy loadingをしていない限り)。ブラウザがユーザー入力に応答していないアイドル状態を待つために、requestIdleCallbackを使用します。そして、JavaScriptを使ってチャットスクリプトを注入することで、プリロードスキャナがscriptのsrcを即座に認識して早期ダウンロードをトリガーしないようにします(まさにこれを避けたいのです)。これは、YouTubeの埋め込みやGoogleマップで使用されるのと同じスクリプト遅延パターンです。
<script>
window.addEventListener('load', function(){
requestIdleCallback(function(){
var s = document.createElement('script');
s.src = 'https://your-chat-widget-url.com/chat.js';
document.body.appendChild(s);
})
})
</script>
SafariはrequestIdleCallbackをサポートしていないことに注意してください。fallbackを使用します。const idle = window.requestIdleCallback || ((cb) => setTimeout(cb, 1));とし、上記の例のrequestIdleCallbackをidleに置き換えてください。
このloadイベントとrequestIdleCallbackのパターンにより、チャットウィジェットによるLighthouseスコアへの影響は9〜16ポイントから0〜1ポイントに減少します。
代替案: インタラクションベースの読み込み
loadイベントの後にチャットウィジェットを自動的に読み込む代わりに、訪問者が実際にページとインタラクションするまで待つことができます。mousemove、scroll、またはtouchstartをリッスンし、最初のイベントでチャットスクリプトを読み込みます。これにより、スクロールやインタラクションを一度もしない訪問者に対するCore Web Vitalsへの影響は確実にゼロになります。
<script>
function loadChat() {
var s = document.createElement('script');
s.src = 'https://your-chat-widget-url.com/chat.js';
document.body.appendChild(s);
['mousemove','scroll','touchstart'].forEach(function(e){
document.removeEventListener(e, loadChat);
});
}
['mousemove','scroll','touchstart'].forEach(function(e){
document.addEventListener(e, loadChat, {once: true});
});
</script> チャットウィジェットが引き起こすCumulative Layout Shiftの問題を修正する
通常、チャットウィジェットは小さなレイアウトシフトを引き起こします。それが大きな問題になるとは限りません。しかし、チャットウィジェットのレンダリングが単にひどい場合もあります。幸いなことに、ウィジェットのレンダリングが完了するまでそのひどい状態を隠すことで、これも(ある程度)修正できます。
これを行うには、チャットウィジェットのドキュメントを読む必要があります(多くの異なるチャットプロバイダーがあり、それぞれ動作が少し異なります)。ドキュメントで、チャットレンダリングのさまざまな段階で呼び出されるコールバック関数を探してください。使用しているチャットウィジェットがわからないため、ここではメカニズムを説明するためにchat.ready()関数を使用します。
あとは少しのスマートなスタイリングで、CSSのopacityプロパティを使ってチャットの表示/非表示を切り替えることができます。まず、デフォルトでチャットウィジェットを非表示にするクラスを追加します(セレクタは使用中のチャットウィジェットに合わせて変更してください)。次に、chat.ready()のコールバックでbodyのclasslistに「showchat」を追加し、チャットを再表示する2行目のCSSを有効にします。
<style>
/*hide chat widget by default*/
.chatwidget{opacity:0}
/*show chat widget after .showchat body class*/
body.showchat .chatwidget {opacity:1}
</style>
<script>
chat.ready(function(){
document.documentElement.classList.add('showchat');
})
</script>
これだけです!チャットウィジェットの高速化を頑張ってください。実際の訪問者で変更を検証するには、Real User Monitoringを設定してください。デバッグにはlab dataのスコアが役立ちますが、Googleがランキングに使用するのは実際のユーザーからのfield dataです。