「ページを開いたら一瞬だけ白くなって、その後全部表示される…」
こんな経験、ありませんか?ちょっとしたリストを表示するだけなのに、なぜか重い。原因を調べてみたら、たった4行のテキストを表示するために2MB近いデータを転送していた——そんな驚きの事例が話題になっています。
今回はこの実例をもとに、「フロントエンドのパフォーマンス問題をどうやって特定するか」を一緒に見ていきましょう! 🔍
なにが起きていたのか

問題のページはシンプルな構成でした。顧客向けエリアに設置された、日付と見出しが並ぶちょっとしたリスト。エディターが手動で更新するだけの、いわゆる静的に近いコンテンツです。
ところがそのページを開くたびに、一瞬ブランク(白紙)になってからコンテンツが出現するという怪しい挙動が。体感的には「遅い」とは言えないかもしれないけど、何かがおかしい。
こういうときに最初にやるべきことは、ブラウザの開発者ツール(DevTools)でネットワークタブを開くことです 🛠️
DevToolsで原因を掘り下げる
ネットワークタブを開いてページをリロードしてみると、転送量が異常に多いことがすぐわかります。4行しかないリストなのに、合計で約2MBのデータが流れていたんです。
よくある犯人としては、こんなものが挙げられます。
- 📦 巨大なJavaScriptバンドル:使っていない機能まで全部まとめてロードしている
- 🖼️ 最適化されていない画像:WebP変換やリサイズをしていない
- 🔁 不要なAPIレスポンス:表示に必要ないフィールドまでJSON丸ごと返している
- 🧩 重いUIフレームワークの読み込み:ちょっとしたリストにフル機能のSPAを使っている
実際に確認する際は、こんなコードでAPIレスポンスのサイズを簡単にチェックできます。
# PythonでAPIレスポンスのサイズを確認するシンプルな例
import requests
url = 'https://example.com/api/items'
response = requests.get(url)
# バイト数をMBに変換して表示
size_bytes = len(response.content)
size_mb = size_bytes / (1024 * 1024)
print(f'レスポンスサイズ: {size_bytes} バイト ({size_mb:.2f} MB)')
print(f'HTTPステータス: {response.status_code}')
# JSONの中身を確認
data = response.json()
print(f'返ってきた件数: {len(data)} 件')
print(f'フィールド一覧: {list(data[0].keys()) if data else "空"}')
これを実行すると、「4件のリストを返しているだけのはずのAPI」が大量のフィールドを含むJSONを返していることが一目瞭然になります。
実際の犯人:APIが「全部入り」だった
この事例の場合、APIのレスポンスを詳しく見てみると衝撃の事実が判明しました。
表示に使っているフィールドは title と date の2つだけ。ところがAPIが返しているJSONには、本文全文・画像の埋め込みデータ・編集履歴・メタデータ・タグ・カテゴリ・関連コンテンツ…と、数十個ものフィールドが詰め込まれていました。
# 問題のある「全部入り」レスポンスのイメージ
bad_response = [
{
'id': 1,
'title': '2024年1月のお知らせ', # ← 使う
'date': '2024-01-15', # ← 使う
'body': '...3万文字の本文...', # 使わない
'thumbnail': '...base64エンコードの画像データ...', # 使わない
'author': {...}, # 使わない
'edit_history': [...], # 使わない
'related': [...], # 使わない
# ...以下、延々とフィールドが続く
},
# × 4件分
]
たった4件のリストなのに、1件あたり500KB近いデータが含まれていたというわけです。これが4件で約2MB——謎が解けましたね。
解決策①:APIのレスポンスをスリム化する
最もシンプルな解決策は、APIが返すフィールドを必要最低限に絞ることです。
# Pythonで「必要なフィールドだけ」を返すAPIを作るイメージ(Flask使用)
from flask import Flask, jsonify
app = Flask(__name__)
# ダミーデータ(本来はDBから取得)
all_items = [
{'id': 1, 'title': '1月のお知らせ', 'date': '2024-01-15', 'body': '...長い本文...', 'thumbnail': '...'},
{'id': 2, 'title': '2月のお知らせ', 'date': '2024-02-10', 'body': '...長い本文...', 'thumbnail': '...'},
]
# ❌ 悪い例:全フィールドをそのまま返す
@app.route('/api/items/bad')
def get_items_bad():
return jsonify(all_items) # 不要データも全部流れる
# ✅ 良い例:必要なフィールドだけに絞る
@app.route('/api/items/good')
def get_items_good():
slim = [{'id': item['id'], 'title': item['title'], 'date': item['date']} for item in all_items]
return jsonify(slim) # 必要なものだけ!
これだけで転送量が劇的に減ります。「全部返しておけば後で使えるかも」という発想が、こういった無駄につながりがちです。
解決策②:JavaScriptバンドルを見直す
もう一つよくある原因が、巨大なJavaScriptバンドルです。ReactやVueなどのSPAフレームワークを使っていると、ちょっとしたリスト表示のためだけに数百KBのJSファイルが読み込まれることがあります。
DevToolsの「ソース」タブや、Webpack Bundle Analyzerなどのツールを使うと、どのライブラリが何KBを占めているかが可視化できます。
# npmでBundle Analyzerを使う場合(ターミナルで実行)
# npm install --save-dev webpack-bundle-analyzer
# package.jsonのscriptsに追記
# "analyze": "webpack --profile --json > stats.json && webpack-bundle-analyzer stats.json"
# 実行
# npm run analyze
よくある改善ポイントとしては以下のようなものがあります。
- 🗂️ コードスプリッティング:ページごとに必要なJSだけを読み込む
- 🌲 Tree Shaking:使っていない関数・モジュールをビルド時に除外する
- 📉 ライブラリの見直し:moment.jsをday.jsに換えるだけで数十KB削減できることも
- 🚀 遅延ロード(Lazy Load):最初の表示に不要なものは後から読み込む
解決策③:キャッシュを活用する
静的に近いコンテンツなら、キャッシュを使うのも効果的です。毎回APIを叩くのではなく、一定時間はキャッシュしたデータを使い回すだけで、体感速度が大幅に改善します。
import requests
import time
# シンプルなインメモリキャッシュの実装例
cache = {}
CACHE_TTL = 60 # 60秒間キャッシュを保持
def get_items_with_cache(url):
now = time.time()
# キャッシュが有効ならそれを返す
if url in cache:
cached_data, cached_at = cache[url]
if now - cached_at < CACHE_TTL:
print('キャッシュを使用しました ✅')
return cached_data
# キャッシュがないor期限切れならAPIを叩く
print('APIからデータを取得しています...')
response = requests.get(url)
data = response.json()
# キャッシュに保存
cache[url] = (data, now)
return data
# 使い方
items = get_items_with_cache('https://example.com/api/items')
print(f'{len(items)} 件取得しました')
本番環境ではRedisやMemcachedを使うのが一般的ですが、原理はこれと同じです。「毎回サーバーに取りに行かなくていいもの」はキャッシュする——これだけでパフォーマンスが大きく変わります。
改善前後の比較
今回の事例を整理すると、こんな感じになります。
# 改善前後のイメージ比較
改善前:
転送量: 約2MB
内訳: 全フィールドJSON × 4件 + 重いJSバンドル
初期表示: 一瞬白くなる(ブランク発生)
改善後:
転送量: 約80KB(-96%!)
内訳: 必要フィールドのみJSON × 4件 + スリム化したJS
初期表示: スムーズに表示
96%削減——数字で見るとインパクトがありますね。やったことは「不要なフィールドを返さないようにした」「使っていないライブラリを整理した」というシンプルなことだけです。
パフォーマンス改善のデバッグフロー まとめ
今回の事例を踏まえた、フロントエンドのパフォーマンス問題を調査するときの基本フローをまとめます。
- 🔍 DevToolsのネットワークタブを開いて転送量・件数を確認
- 📊 Lighthouseタブでパフォーマンススコアを計測(Google提供のツールが内蔵されています)
- 🧐 APIレスポンスの中身を確認して、不要なフィールドがないかチェック
- 📦 JSバンドルのサイズを確認して、不要なライブラリを排除
- 🖼️ 画像の最適化(WebP変換・適切なリサイズ)を確認
- 🗄️ キャッシュ戦略を導入して無駄なリクエストを減らす
難しいツールは必要ありません。まずはブラウザのDevToolsを開くことが、パフォーマンス改善の第一歩です。
まとめ
「たった4行のリストなのに2MB転送していた」という一見ありえない話も、APIが全フィールドを返している・重いJSバンドルが読み込まれているといった、よくある原因が積み重なった結果でした。
フロントエンドのパフォーマンス問題は、「なんか重いな」という感覚を無視しないことが改善への入り口です。DevToolsを開いて数値を見るだけで、原因の大半はすぐに特定できます。
「遅い気がするけど、まあいいか」で放置せず、一度DevToolsで確認してみてください。きっと驚く数字が出てくるかもしれません 😄





