Webアプリが遅いと言われたときに、原因を探して直すのがパフォーマンスチューニングです。見る場所がコード・データベース・サーバーと広く、それぞれに別の知識が要るので、かなり難易度の高い作業でした。
今は事情が変わりました。AIがコードベースを読んでボトルネックの場所を探してくれますし、SSHでサーバーにつなげられれば、サーバーの状態も調べてくれます。この記事では、AIがない頃に何が大変だったのかを振り返り、今どう楽になったのかをまとめます。
AIがない頃のパフォーマンスチューニング
AIがない頃は、調べる場所ごとに、自分の知識で一つずつ当たっていく必要がありました。
コードを読んでボトルネックを探す
まずはアプリのコードです。遅い画面やAPIの処理を追いかけて、どこで時間を使っているのかをコードリーディングで探します。ループの中でデータベースにアクセスしていないか、同じ処理を何度も呼んでいないか、といった箇所を目で見つけていく作業です。
読むだけで分からなければ、動かして調べます。画面が遅いなら、ブラウザの開発者ツール(Chrome の DevTools など)の「ネットワーク」タブで、どのリクエストに何秒かかっているのかを計測します。リクエストごとの「タイミング」を開くと、サーバーの応答待ちが長いのか、ダウンロードに時間がかかっているのかも分かります。JavaScript が怪しければ、「ソース」タブでブレークポイントを置いてデバッグします。
サーバー側の処理は、アプリをローカルで起動して調べます。IDE のデバッグ機能で処理を止めて変数の値を確かめたり、ログや経過時間を出すデバッグコードを差し込んだりして、どこが遅いのかを絞り込んでいきます。
// 経過時間を測るデバッグコードの例(JavaScript)
console.time('一覧の取得');
const items = await fetchItems();
console.timeEnd('一覧の取得'); // コンソールに「一覧の取得」の経過時間が出る
データベースを調べる
遅いのがSQLなら、データベースに EXPLAIN などの分析コマンドを打って、実行計画を確認します。MySQLでもPostgreSQLでも、クエリの先頭に EXPLAIN を付けると、インデックスが使われているか、何行を読むつもりなのかが分かります。
-- MySQL / PostgreSQL どちらも同じ書き方で実行計画が見られる
EXPLAIN SELECT id, total FROM orders
WHERE shop_id = 10 AND created_at >= '2026-09-01';
あわせてテーブル定義書やER図を開いて、テーブル同士の関係やインデックスの付き方を確かめながら調べていました。実行計画の読み方は、50万行で実測した複合インデックスの記事に詳しく書いています。
サーバーを調べる
原因がアプリやデータベースではなく、サーバー側にあることもあります。アプリがメモリをどれだけ使っているのか、ディスクの読み書き(ディスクIO)が詰まっていないか。これを調べるには、Linuxのコマンドやインフラの知識が必要でした。よく使うのは次のようなコマンドです。
# メモリの空き(-h で単位付き)
free -h
# CPU・メモリ・スワップ・IO の推移を1秒ごとに
vmstat 1
# ディスクごとのIO(sysstat パッケージのコマンド)
iostat -x 1
# プロセスごとのメモリ(-r)とディスクIO(-d)
pidstat -r 1
pidstat -d 1
# メモリを多く使っているプロセスの上位
ps aux --sort=-%mem | head
コマンドを知っているだけでは足りず、出力のどの列を見ればよいのかも分かっている必要があります。たとえば vmstat なら、IO待ちの割合を示す wa や、スワップの出入りを示す si・so の列です。
直し方も知っている必要があった
調べて原因が分かっても、直し方を知らなければ直せません。パフォーマンス改善には定番の手法がいくつもあり、原因に合わせて選ぶ必要がありました。
| 手法 | 効くとき |
|---|---|
| N+1問題を解消する | 一覧の件数分だけSQLが発行されている。JOINやINでまとめて取る |
| インデックスを追加・見直す | WHEREやORDER BYで全件を読んでいる。複合インデックスは列の順番で効き方が変わる |
| 必要なカラムだけ取る | SELECT * で使わない大きな列まで読んでいる |
| キャッシュする | 同じ結果を何度も計算・取得している(アプリ内・HTTP・CDN) |
| ページングを見直す | OFFSETが大きいページほど遅い。前のページの最後のキーから続きを取る |
| まとめて処理する | 1件ずつINSERTやUPDATEをしている |
| 非同期にする | メール送信や画像変換など、画面を待たせなくてよい処理が同期で走っている |
| 転送量を減らす | 画面の表示が遅い。画像・フォント・スクリプトが重い |
N+1問題は、一覧で親を1回取得したあと、子を1件ずつ取りに行くことで、SQLが「1+件数」回発行される問題です。このブログでも、本番のデータベースで実際に再現しました(パフォーマンス改善ガイド)。
直したらデグレのテストも要る
コードを変えたら、ほかの場所が壊れていないか(デグレが起きていないか)をテストで確かめる必要があります。速くなったかどうかの計測と、正しく動くかどうかの確認の両方が要ります。
調べる範囲が広く、直し方の知識も要り、最後にテストもある。パフォーマンスチューニングは、そういう難易度の高い作業でした。
今はAIが調べてくれる
コードベースを読んでボトルネックを探してくれる
今は、Claude Codeのようなコーディングエージェントにリポジトリを渡せば、AIがコードベースを読んでボトルネックになっている箇所を探してくれます。自分でコードを一から追いかける必要はありません。
SSHでつなげばサーバーの状態も調べてくれる
SSHでサーバーにつなげられる環境なら、AIがコマンドを実行して、サーバーの状態も調べてくれます。前に挙げたメモリやディスクIOを見るコマンドも、AIが選んで実行し、結果を読んでくれます。
自分でサーバーに入って調べたい場合も、「メモリを多く使っているプロセスを見たい」のように聞けば、使うコマンドを教えてくれます。コマンドの名前やオプションを覚えておく必要はありません。
このブログの表示速度もAIと直した
このブログの表示速度の改善も、AIに任せて進めました。流れは次のとおりです。
- 何が重いのかを測る
AIがLighthouseで転送量を種類別に分け、日本語のWebフォントが半分以上を占めていることを突き止めた - 本番を変えずに試す
本番のページのフォント指定だけを差し替えて表示し、見た目と転送量を比べた - 本番に適用する
見出しと本文のWebフォントをやめ、OS標準のフォントに切り替えた - 同じ条件で測り直す
元のフォント指定を再現した状態と適用後を、Lighthouseで3回ずつ測って中央値で比べた

| 項目 | 適用前 | 適用後 |
|---|---|---|
| スコア | 56 | 67 |
| FCP(最初の描画) | 9.6秒 | 4.3秒 |
| LCP(表示の速さ) | 10.4秒 | 5.9秒 |
| 転送量 | 1,992 KB | 755 KB |
| Webフォント | 1,099 KB(93ファイル) | 38 KB(4ファイル) |
自分でやったのは、「この対応を試したい」「本番に適用して」「スコアも測って」と頼んだことと、ビフォーアフターのスクショを見て判断したことだけです。フォントが重かった理由と計測の詳しい数字は、Lighthouseの記事にまとめています。
まとめ
- AIがない頃は調べる範囲が広かった
コード(開発者ツール・IDEのデバッグ)、データベース(EXPLAIN・テーブル定義書・ER図)、サーバー(Linuxのコマンド)をそれぞれの知識で調べていた - 直し方の知識とテストも要った
N+1・インデックス・キャッシュなどの手法を知っていて、直したあとはデグレがないかを確かめる必要があった - 今はAIがコードもサーバーも調べてくれる
SSHでつなげばサーバーの状態も見てくれるし、自分で調べるときはコマンドを教えてくれる - 専門知識がなくても解決できる
このブログのフォントの改善は、頼んで結果を見て判断するだけで、LCPが10.4秒から5.9秒になった
次に読む記事



