ラボまとめコラムニュース
ブログ/記事一覧/【体験談】直帰率94%を治そうとしてサイトを心肺停止させた話
直帰率94%を治そうとしてサイトを心肺停止させた話 - カバー

【体験談】直帰率94%を治そうとしてサイトを心肺停止させた話

GA4で直帰率94%を確認し、13個の回遊改善を自作CMSに実装。デプロイ直後に全記事ページが壊れた体験から、UX分析・改善設計・障害対応・環境整備の教訓を共有します。

コラム
kkm-horikawa

kkm

Backend Engineer / AWS / Django

2026.03.288 min8 views
この記事のポイント

GA4で直帰率94%を確認し、13個の回遊改善を自作CMSに実装。デプロイ直後に全記事ページが壊れた体験から、UX分析・改善設計・障害対応・環境整備の教訓を共有します。

手術は成功したが、患者は一時心肺停止した

「手術は成功しました。ただ、患者は一時心肺停止しました」。医者にこう言われたら、成功とは何だったのかと問い詰めたくなります。

このサイトで、まさにそれをやりました。

記事ページの回遊率を上げるためにUI改善を13個入れました。施策の方向性は正しかったし、今もちゃんと動いています。ただ、デプロイした直後に全記事ページが表示不能になりました。JavaScriptのシンタックスエラーでインタラクティブな要素がすべて死に、hotfixを4連発で打って蘇生しています。

なぜこうなったのか。時間を巻き戻します。

94%が1記事で帰っていく

GA4を開いて最初に目に入ったのがこの数字でした。

指標モバイルデスクトップ業界平均(ブログ)
1記事離脱率94.0%90.1%70〜90%
ページ/セッション1.091.191.2〜1.5
平均エンゲージメント21秒30秒
スクロール90%到達率26%34%

サイトを立ち上げて数週間の時点でのデータです。離脱率やエンゲージメント時間そのものは、開設間もないブログとしては標準的な範囲でした。記事を読んでくれている人はちゃんと読んでくれている。問題はそこではありません。

ページ/セッションが1.09。ほぼ全員が1記事だけ読んで帰っています。

流入元別に見ると傾向がはっきりします。SNS経由の流入が最も多いのですが、そのうち95.9%が1記事で離脱。検索経由だと12.8%、ダイレクトだと16.0%が2記事以上読んでいました。

面白いのは、2記事以上読んだ人の平均が4.4記事だったことです。一度回遊に入ると深く読んでくれる。ただ、その「一度」がほとんど発生していない。

最後まで読まないと他の記事に気づけない

なぜ回遊が起きないのか。改善前の記事ページを見直して、すぐにわかりました。

他の記事への導線がフッター付近にしかない。記事を最後までスクロールしないと、サイトに他にどんな記事があるのか一切わからない構造になっていました。

スクロール90%到達率がモバイルで26%ということは、74%の人は記事の途中で読むのをやめて帰っています。その人たちの画面には、他の記事の存在が一度も映っていません。

エンゲージメント時間の分布を見ると、モバイルの31%が5秒以内に離脱しています。タイトルか冒頭だけ見て去っていく層です。この人たちにフッターの関連記事が届くわけがない。

読者は「他の記事を読まない」のではなく「他の記事があることに気づけない」状態でした。回遊率が低い原因は記事の質ではなく、ページの構造にあった。

「邪魔にならない」を最優先にした13の施策

原因が構造にあるとわかったので、記事ページ内に回遊導線を追加することにしました。

設計で最も重視したのは「邪魔にならないこと」です。ポップアップやモーダルで「この記事も読んで!」と叫ぶサイト、あれは読んでいる側からすると本当にうるさい。「ここにこういう記事もありますよ」と、さりげなく提案するくらいがちょうどいい。

施策配置狙い
プログレスバー + 残り読了時間ヘッダー下あとどれくらいかわかると読み続けやすい
TL;DR 要点表示記事冒頭要点を先に見せて読む判断を助ける
目次スムーススクロール目次読みたいセクションへの移動を快適にする
記事途中の関連記事カード2つ目のH2の前途中で他の記事を認識してもらう
関連記事の自動生成記事下部カテゴリ最新 + 人気記事を自動で表示
ニュースティッカーヘッダー直下最新記事の存在を常に示す。閉じ可能
サイドバー人気記事デスクトップ右側目次の下に人気記事5件
カテゴリタブバーヘッダー直下カテゴリ移動を常に可能に。Smart Hide対応
モバイルボトムナビ画面下部固定検索・ページ内検索・目次の3機能
ページ内検索(表記揺れ対応)ボトムナビから起動ひらがな/カタカナ/全角半角を吸収する検索
API公開キャッシュサーバー設定動的取得するAPIレスポンスをキャッシュ
APIフィールド拡充バックエンドカード描画に必要な情報をAPIで返す

回遊導線だけでなく、滞在時間の改善(プログレスバー、TL;DR)とモバイル操作性(ボトムナビ、ページ内検索)にも手を入れています。回遊導線をいくら増やしても、そもそも記事を読んでもらえなければ意味がないからです。

技術的にはCMSの公開APIで記事データを取得し、バニラJavaScriptで描画する構成です。フレームワークは使っていません。テンプレートに直接書いています。

一方で、見送った施策もあります。

見送った施策理由
フローティング「次に読む」ボタン差し込みカード・関連記事・ティッカーと重複してしつこい
ウェルカムバー(初回訪問者向け)3秒で消えるバーに効果があるとは思えない
パンくず強化既存パンくず + カテゴリタブで十分
無限スクロール実装したが同じ記事が繰り返し表示されるバグが出て削除

無限スクロールは実装までしたのですが、同じ記事が何度もロードされる問題が出て削除しました。入れるべきでないものを見送る判断も、設計の一部です。全部入れればいいというものではない。

自分で検討して自分で壊せるのが自作CMSの醍醐味

WordPressであれば「関連記事プラグインを入れる」「人気記事ウィジェットを追加する」で済む話かもしれません。

ただ、「2つ目のH2の前に同カテゴリの記事カードを1枚だけ差し込む」とか「ニュースティッカーをsessionStorageで閉じた状態を記憶する」とか、そういう細かい制御はプラグインでは難しいことが多い。できたとしても、プラグイン同士の競合やアップデート時の動作保証に気を配る必要があります。

このサイトはPython製のCMSで構築しています。テンプレートもAPI設計も自分でコントロールできるので、GA4のデータを見て「ここにこれを出したい」と思ったら、その通りに実装できます。

裏を返せば、「自分が書いたコードで自分のサイトを壊せる」ということでもあります。WordPressなら本体が壊れることはまずありませんが、自作CMSではテンプレートの書き方ひとつで全ページが動かなくなります。

そしてデプロイボタンを押した

13の施策を1つのPRにまとめてmainブランチにマージし、本番にデプロイしました。ここから連鎖的に問題が起きます。

CSSが反映されない

デプロイ後、新しいUIのスタイルが一切適用されていませんでした。

このサイトでは、テンプレート内のCSS/JSを静的ファイルにビルドする仕組みを使っています。ビルドが走るタイミングはCMS管理画面からページを保存したときなのですが、今回はテンプレートへの直接変更なので、そのトリガーが発生しない。新しいTailwindクラスを書いたのにCSSが生成されていない状態でした。

デプロイ後に自動でビルドを走らせるよう設定しましたが、処理が遅すぎて即revert。代わりに全ページを再公開するコマンドを作って対応しています。

全記事ページのJavaScriptが壊れた

これが一番まずかった。

13の施策で大量のJavaScriptをテンプレートに追加したのですが、複数のscriptブロックに分けて書いていました。ビルド時にこれらが1つのscriptブロックに統合されるのですが、その過程で閉じタグが消失。JavaScriptのシンタックスエラーが発生し、全記事ページのインタラクティブな要素が動かなくなりました。

この修正にhotfixを4本投入しています。閉じタグの復元、scriptブロックの統合、コメントの除去と、問題を1つずつ潰していきました。

無限スクロールが同じ記事を繰り返す

記事末端で次の記事を自動ロードする機能も入れていたのですが、APIのオフセット指定が正しくなく、同じ記事が何度も表示される。修正を試みるよりも、他の回遊導線で十分と判断し、機能ごと削除しました。

問題原因対応
CSSが反映されないテンプレート変更ではCSS再ビルドが走らない全ページ再公開コマンドを作成
JS全壊ビルド時のscript統合で閉じタグが消失hotfix 4本で復旧
無限スクロールが同じ記事を繰り返すAPIオフセットの実装不備機能ごと削除
再公開コマンドが403エラーCodeBuildロールにS3/CloudFront権限がないIAMポリシー追加

1つのPRから、8つの後続PRが生まれました。うち4つがhotfix、2つがリリースPR、2つが周辺対応です。

dev環境は「ある」。使っていないだけだ

このサイトにはdev環境が存在します。Terraformで本番と同じ構成を定義してあり、いつでも立ち上げられる状態です。ただ、使っていません。

理由は運用コストです。AWSの各種リソースを常時稼働させると、個人サイトの規模には見合わない費用が発生します。サイト開設直後で記事数も少なく、テストもCIも通している。今回の問題はテストでは検出できない種類のもの(asset publisherのビルド時の挙動)だったので、dev環境があっても気づけたかどうかは微妙なところです。

この判断自体は、個人サイトの初期フェーズとしては妥当だったと今でも思います。

ただし、これが企業のサイトだったら話は別です。

全記事ページが表示不能になるということは、その間のトラフィック・広告収益・ユーザーの信頼がすべて失われるということです。「dev環境の運用コストが高いから本番で確認する」は通りません。staging環境でのデプロイ検証、CSS/JSビルドのCI統合、カナリアリリースなど、本番投入前に問題を検出する仕組みは必須です。

個人サイトで済むミスと、企業サイトで許されないミスの境界は、「壊れたときに誰が困るか」で決まります。自分だけなら即hotfixで済みますが、顧客がいるなら環境を整えてから手術してください。

今回の経験を経て、このサイトでもdev環境の運用を検討し始めています。記事数が増えれば影響範囲も広がるし、次にテンプレートに大きな変更を入れるときに同じことはしたくない。

手術は成功しました。患者は一時心肺停止しましたが、今は元気に動いています。次はもう少し慎重にメスを入れようと思います。