サイトスピードの相談を受けると、ページの作りを見直すという前提で話が進みやすい。何か実装方法が間違っているのだから、それを直せばスピードは上がるはず、と考えるのは自然な話だ。
しかし実際のタイムラインを見てみると、遅さの主な原因がページそのものではないケースは多い。HTMLやCSS、画像が十分に軽いにもかかわらず、後から差し込まれた広告や解析の サードパーティタグ が表示速度を押し下げている。サイト本体に手を入れる前に、これらのタグを見直すだけでスピードをかなり改善できるケースは決して珍しくない。
この記事では、実際のサイトを対象にした弊社のサイトスピードの弱点研究のデータをもとに、サードパーティタグがどれだけスピードに影響を与えるか、そしてそれにどう対処すべきかを紹介したい。
ブラウザは優しい世界ではない
なぜ、補助的なはずのサードパーティタグがページスピードに大きな影響を与えるのか。その答えは、ブラウザの中の仕組みにある。
JavaScriptに限らず、ブラウザの主要な処理はシングルスレッドで動く。マルチコアのCPUが当たり前になった今でも、同時に動かせる処理はひとつだけだ。1台しかないATMに、みんなで行列を作って順番に使う。そんなイメージである。
ここで私たちは、ユーザー向けのコンテンツが優先されるはず、と期待してしまう。だが現実は違う。コンテンツだろうとサードパーティタグだろうと、我先にとATMに並び、並んだ順にCPUを使う。決してユーザー中心の優しい世界ではないのだ。

理想を言えば、補助的なサードパーティタグは、ユーザーが見たいコンテンツに順番を譲るべきだ。ところが現実には、タグの処理がコンテンツの表示を妨げているケースは決して少なくない。
これが、ページ本体が軽くてもサードパーティタグによって表示スピードが低下する現象の正体だ。
実例で確認するサードパーティタグの影響
弊社では、表示速度ボトルネックの実例研究 というブログで、実際のWebページの表示速度のボトルネックを研究し、その成果を公開している。フロントエンドのどこをどう直すとどの指標が改善するかを、精度の高いシミュレーションで一つずつ検証し、結果を数値とともに公表する取り組みだ。
この研究には共通の手順がある。調査したいページ本体を観察する前に、まずサードパーティタグを取り除くのだ。理由は2つある。
ひとつはサードパーティタグがノイズとなり、サイト本体のパフォーマンスの分析が難しくなるためだ。もうひとつは、サードパーティタグ自体がどれだけスピードに影響しているかを計測するためである。タグを全部外すのは運用上できない話だが、外したときの数値は「タグを最適化すれば最大でここまで速くなる」という改善ポテンシャルを教えてくれる。
ではサードパーティタグが大きな影響を与えている具体例をいくつか見ていこう。
ABAHOUSE ONLINE STORE:ページ本体は軽いのに、タグでLCPが1.8秒延びる
ファッション通販の ABAHOUSE ONLINE STORE のトップページでは、12種類のサードパーティタグが検出され、合計約2.8MBの転送とメインスレッド640ms以上の占有が観測された。全215リソースのうち、サードパーティタグ由来は88件と約4割を占めていた。
これらをすべて外したときの数値が分かりやすい。
| 指標 | 観測時点(タグあり) | タグ全除去後 | 変化量 |
|---|---|---|---|
LCP | 1.8秒 | 0.1秒 | -1.7秒 |
FCP | 1.6秒 | 0.1秒 | -1.5秒 |
タグを外した状態の LCP(主要コンテンツが表示されるまでの時間)はわずか0.1秒。ページ本体はこれほど高速に表示できる作りなのに、タグが乗っているだけで LCP が1.8秒まで伸びていた。「ページが重い」のではなく「タグが重い」ことがはっきり分かる一例だ。なお、このタグを含む全ボトルネックを解消したシミュレーションでは、Lighthouseの 総合スコア は86から100へ到達している。
ページ本体の速さとタグの重さを分けて検証した詳しい手順は、弱点研究の記事 ABAHOUSE ONLINE STORE のボトルネック研究 にまとめている。
ホームセンターバロー:たった3個のタグでLCPが20秒
ホームセンターバロー公式オンラインショップ はもっと極端だ。検出されたサードパーティタグはわずか3個、全93リソースのうち1割にすぎない。しかもその3個はすべてGoogle Analytics/Google Tag Manager系のトラッキングコードで、機能が重複していた。
| 段階 | 総合スコア | LCP | FCP |
|---|---|---|---|
| 観測時点 | 35 | 20.2秒 | 4.5秒 |
| GTMまで除去 | 64 | 4.5秒 | 1.2秒 |
LCP 20.2秒という観測値が、タグを外すと4.5秒まで縮んだ。とりわけ最後に Google Tag Manager を外した段階で LCP が一気に落ちている。数の少なさと重さは比例しない。 タグマネージャーひとつがこれだけの遅延を生むことがある。総合スコア もタグ除去だけで35から64へと29ポイント改善した。全93リソースのうちタグはたった1割で、残り9割はサイト本体だ。それでも、この1割が表示速度を支配していた。
3個のタグを段階的に外したときの記録は、ホームセンターバロー公式オンラインショップのボトルネック研究 で確認できる。
プレジデント・オンライン:半分以上がタグ。外せばスコアは99に
広告で運営されるメディアサイトはタグの量がさらに桁違いになる。プレジデント・オンライン のトップページでは、全369リソースのうち約6割にあたる216件がサードパーティタグ由来で、その種類は54種、合計10.79MBにのぼった。
タグを3つのグループに分けて段階的に外していくと、指標は次のように改善した。
| 除去フェーズ | 総合スコア | LCP |
|---|---|---|
| 観測時点 | 56 | 15.9秒 |
| 高負荷広告・レコメンド除去 | 67 | 6.9秒 |
| 広告インフラ・Prebid除去 | 80 | 4.6秒 |
| GTM/GA・トラッキング除去 | 99 | 1.8秒 |
LCP は15.9秒から1.8秒へと約14秒短縮された。スコアの動きも見逃せない。総合スコア はタグを外すだけで56から99へと一気に上がり、サイト本体の微修正まで含めた全解消シミュレーションでは100に達した。100点満点で44ポイントの変化だ。
注目すべきは、これだけタグを外しても 見た目はほぼ変わらなかった こと(差分0.11%以下)。広告枠はサーバーサイドで制御されており、ユーザーが目にするコンテンツの大半はタグなしでも成立していた。スコアを44ポイント引き上げた要素の大半が、ユーザー体験には不要なものだったわけだ。
54種のタグを3グループに分けて外した詳細は、プレジデント・オンラインのボトルネック研究 を参照してほしい。
ASCII.jp:約7割がサードパーティタグ
IT情報サイトの ASCII.jp でも、全298リソースの約7割(203件)がタグ由来だった。これらを外すと LCP は11.6秒から0.4秒へ、総合スコア は71から100へと変化した。リソースの7割を占めるタグを外しただけで、スコアが満点に届いた。
Header Biddingを含む203件のタグの内訳は、ASCII.jp のボトルネック研究 に載せている。
念のため補足すると、これらはあくまでタグを全除去した上限値だ。実運用ではこの一部しか実現できない。それでも最適化で取り戻せる余地がこれほど大きいという事実は重い。
大規模改修の前にできることがある
ここまでの例に共通するのは、ページ本体はそこまで重くないという点だ。むしろ本体は十分に速く、後から積み重なったサードパーティタグが表示を押し下げている。
ただ、商用サイトではこれがむしろ普通の状態だと言ってよい。広告、アクセス解析、ABテスト、リターゲティング、チャットボット、UGC連携と、ビジネス上の必要から少しずつタグが増えていくのはしかたがない。
だからこそサイトスピード改善を狙ってリニューアルや大規模改修を実施しても、サードパーティタグを入れたら元の木阿弥、という事態にもなり得る。フロントエンドの作り直しは時間とコストのかかる大仕事だが、タグの整理はすぐに始められる。サイト本体を疑うのはその後でもできることだ。
では具体的にどう整理していくか。大きく2つの方向がある。
積極的に使われていない「ゾンビタグ」を消す
ひとつめは、もう使われていないタグを削除することだ。
長くサイトを運用していると、Google Tag Managerの中に「いつ、誰が、何のために入れたのか分からないタグ」「実はもうほとんど使われていないタグ」が溜まっていく。担当者が代わり、代理店が変わり、施策が終わり、計測ツールが乗り換わっても、外したときに思わぬ副作用が出るのを恐れて、誰も手を付けられないまま放置される。いわば ゾンビタグ だ。
長期運用のサイトでゾンビタグがまったく無いケースは見たことがない。まずはGTMのコンテナの棚卸しをして、計測や配信に使われていないタグを洗い出し、削除していく。
できれば「これだけは譲れない」とはっきり言えるタグだけを残し、他は思い切って消す決断をする。これで読み込むスクリプトが減り、メインスレッドの負荷は下がる。
読み込みのタイミングを後ろ倒しにする
ふたつめは、タグを読み込むタイミングを遅らせることだ。冒頭で見たとおり、メインスレッドというATMは1台きりで、あらゆる処理がそこを奪い合っている。本来サードパーティタグは、ユーザーが見たいコンテンツに順番を譲るのが理想だ。
ところが多くのサイトはページが開かれたのと同時にタグを読み込んでいる。そのようにタグのベンダーに指示されるからだが、コンテンツ表示にとっては非常に都合が悪い。ページの初期表示にCPUをフル回転させたいまさにその瞬間に、タグが行列に割り込んでくるからだ。

ユーザーが見たいのはコンテンツであって、計測や広告ではない。にもかかわらず補助的なはずのタグが初期表示に割り込み、コンテンツの描画を遅らせる。これでは本末転倒だ。表示の初期段階というゴールデンタイムは、できる限りユーザー向けのコンテンツに振り向けたい。タグの実行は後ろに回すのが望ましい。
GTMを使っているなら、これは各タグの トリガー(発火条件) を見直すことで実現できる。GTMのページビュー系トリガーには、発火が早い順に次の3種類がある。
- ページビュー:ブラウザがページの読み込みを開始した直後に発火(最も早い)
- DOM Ready:HTMLの解析が終わった時点で発火(
DOMContentLoaded相当) - ウィンドウの読み込み:画像なども含めてページが読み込み終わった時点で発火(
load相当、最も遅い)
ところが多くのタグは、最も早い「ページビュー」(All Pages)のまま設定されている。表示を優先したいタグは、このトリガーをできる限り遅い「DOM Ready」や「ウィンドウの読み込み」に変更する。これが、GTMにおける読み込みタイミング後ろ倒しの具体的な指定方法だ。
そもそもGoogle Tag Manager自体が重い
タグのタイミングを考えるうえで、ひとつ認識を改めてほしいことがある。Google Tag Manager(GTM)そのものが、かなり重い ということだ。
GTMは「タグを管理しているだけ」のツールに見えるので、それ自体は軽いと思われがちだ。だが実際にはデータ量が大きく、読み込むスクリプトも相応に重い。
GTMコンテナはひとつに
ひとつのページに複数のGTMコンテナを配置しているサイトも少なくない。しかしGTMコンテナはほとんどのコードが重複しており、ネットワークやCPUに無駄な負担を強いる。
管理上、致し方ない点があるのかもしれないが、GTMを利用する場合はひとつのページで読み込むコンテナをひとつに絞ることを推奨する。
GTMの読み込み自体を後ろ倒しにする
ユーザー向けのコンテンツ表示を優先する大胆な方法としては、GTM自体の読み込みタイミングを遅らせるやり方もある。
考えられるのは2段階だ。ひとつは DOMContentLoaded(DCL、HTMLの解析が終わったタイミング)でGTMを展開する方法。もうひとつ、ユーザー向けコンテンツの表示をさらに優先するなら、load(onload、画像なども含めてページの読み込みが完了したタイミング)まで遅らせる方法だ。
通常、GTMのスニペットはページの読み込みと同時にタグを展開する。
<!-- Google Tag Manager(標準のスニペット:即時実行) -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>
<!-- End Google Tag Manager -->これを、以下のようにDOMContentLoaded イベントまで展開を遅らせる形に書き換える。
<!-- Google Tag Manager(onload後に展開) -->
<script>
function loadGTM() {
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');
}
// ユーザー向けコンテンツの表示を優先し、読み込み完了後にGTMを展開する
if (document.readyState === 'complete') {
loadGTM();
} else {
window.addEventListener('DOMContentLoaded', loadGTM);
}
</script>
<!-- End Google Tag Manager -->こうしておけば、ページ表示の初期段階というゴールデンタイムをまるごとユーザー向けコンテンツに割り当てられる。
window.addEventListener('DOMContentLoaded', ...) の DOMContentLoaded を load に変えれば、サードパーティタグはほぼ完全にユーザーコンテンツの表示にCPUを譲ることができる。
「計測が乱れるのではないか?」という懸念について
タイミングを遅らせる話をすると、多くの人が「計測がズレてしまうのでは」と心配する。もっともな懸念だ。だが、ここで冒頭のATMの行列を思い出してほしい。
私たちは、サードパーティタグが決まった時刻にいっせいに計測や広告配信を始め、それぞれ正しく動いていると感じがちだ。だが実際には、タグたちは1台しかないATMを奪い合い、自分の作業をなかなか始められずにいる。順番を待つあいだにも、時間はどんどん過ぎていく。

つまり、いま現在のサードパーティタグも正確なタイミングで計測できているわけではない。ほかのスクリプトが立て込んでいれば、計測タグはその実行が空くまで待たされる。タグを後ろ倒しにすれば確かに遅延は大きくなる。だが「いまは遅延がゼロ」なのかというと、そんなことはない。もとから遅延はある。計測はすでに乱れているのだ。
だから計測のタイミングが多少ずれても深刻に捉えすぎる必要はない、というのが弊社の見解だ。サードパーティタグの計測値はもともと参考値であり、厳密な精度を期待するものではない。後ろ倒しによる多少の上乗せよりも、ユーザーが体験する表示スピードを優先するほうが、得るものは大きい。
まとめ
- サイトスピードが遅いとき、最初に疑うべきはサードパーティタグだ。ページ本体は十分に軽いのに、タグだけで
LCPが10秒以上延び、Lighthouseの総合スコアが40ポイント以上動く例も実在する。 - 商用サイトでタグが増えるのは避けにくい。だからこそ、リニューアルや大規模改修を始める前に、まずタグを見直したい。サイト本体を疑うのはそのあとでも遅くない。
- 整理の方向は2つ。ひとつは使われていない「ゾンビタグ」を削除すること。もうひとつは残すタグの読み込みを後ろ倒しにし、初期表示をユーザー向けコンテンツに譲ることだ(GTMならトリガーを「DOM Ready」や「ウィンドウの読み込み」へ)。
- GTM自体が重いことも忘れずに。読み込むコンテナはひとつに絞り、必要ならGTMの読み込み自体を
DOMContentLoadedやloadまで遅らせる。 - 「後ろ倒しで計測が乱れるのでは」という懸念はもっともだが、計測はもともと早い者勝ちで乱れている。過度に気にする必要はない。
ページを作り直す前に、まずタグを疑う。それだけで取り戻せるスピードは、きっと思っているより大きい。