マガジン

AIが作ったページが重いとき:画像・外部ライブラリ・読み込み順をweb.devの指標で見直す

AIを使いこなす

Claudeで執筆し、GPTで自動校閲・修正しています。

コードを表示したノートパソコンの横で画像見本を確認する手元
記事の内容をもとに制作したAI生成イメージです。実際の製品画面や検証結果の写真ではありません。

結論から言うと、初学者がまず疑うのは次の三つです。 1. 一番大きく見える画像が重い、または読み込みが遅れている 2. 外部から読み込むもの(ライブラリ、フォント、計測タグなど)が多すぎる 3. スクリプトの読み込み順のせいで、表示がJavaScriptの完了待ちになっている AIにページを作らせると、見栄えのために大きな画像を置き、便利そうなライブラリを複数読み込み、<head>に<script>を並べがちです。ただし、これは傾向であって、あなたのページがそうだとは限りません。計測結果から、どの原因に当たるかを見分けるのがこの記事の目的です。最後の節に、AIに渡す依頼文も載せています。

この記事の目次
  1. 計測結果の読み方メモ
  2. 原因1:画像が大きい、または読み込みが遅れている
  3. 原因2:外部から読み込むものが多い
  4. 原因3:スクリプトの読み込み順
  5. AIに渡す依頼文と、人が確認すること

計測結果の読み方メモ

Lighthouseなどの計測を開いたら、総合スコアの数字ではなく、次の指標を見ます。

web.devでは、ページの良好な目安として、LCP(最大のコンテンツが表示されるまで)は2.5秒以内、INP(操作への反応)は200ミリ秒以下、CLS(表示のずれ)は0.1以下と示されています。評価は、ページ読み込みの75パーセンタイルで、モバイルとデスクトップを分けて見ることが勧められています(Core Web Vitals、2024年10月31日更新と表示されていました)。

同じ記事は、実ユーザーの環境で測るフィールドデータと、手元で測るラボデータは別物だとも述べています。端末や回線で結果が大きく変わるためです。手元で一度測った数字は、再測定でずれる前提で扱います。

  • LCP、意味:最大の画像や文章ブロックが出るまで、主に疑う原因:画像、読み込みの遅れ、サーバー応答
  • CLS、意味:読み込み中に表示がずれる量、主に疑う原因:寸法のない画像、後から差し込まれる外部パーツ
  • TBT、意味:表示後に画面操作を邪魔する処理の合計(ラボ指標)、主に疑う原因:外部ライブラリ、重いスクリプト
  • INP、意味:実際の操作への反応(フィールド指標)、主に疑う原因:同上

TBTはINPの問題を探すためのラボ指標で、INPそのものの代わりにはなりません。平均的なモバイル端末で計測した場合の目安は200ミリ秒未満です(Total Blocking Time)。実ユーザーの操作を反映したINPも確認し、TBTが良くても安心しすぎないようにします。

数字に振り回されないための手順

  • 再測定で数値が変わる前提で、端末や回線などの条件をそろえて比べる
  • 一度に一つだけ直し、直したら同じ方法で測り直す
  • 「赤い項目を全部消す」ことを目標にせず、LCPの対象要素と、TBTの原因になっているスクリプトの二つに絞る

同じ条件での再測定や確認対象の絞り込みは、原因を追いやすくするための編集上の提案です。

原因1:画像が大きい、または読み込みが遅れている

Lighthouseの診断でLCPの対象要素を確認し、それが画像なら画像の読み込み状況を調べます。LCPの対象になりうるのはimg要素、動画のポスター画像、url()で読み込む背景画像、文字を含むブロックなどです(LCP)。

web.devのLCP最適化の記事は、LCPを四つに分けています。サーバーの最初の応答、リソースの読み込み開始までの遅れ、リソース自体の読み込み時間、表示までの遅れです。読み込み開始と表示までの遅れはできるだけゼロに近づけ、ネットワークを使う最初の応答とリソース読み込みには時間がかかる、という考え方です。同記事に示される約40%、各10%未満という比率は、最適化されたページでの目安で、達成を保証する基準ではありません(Optimize LCP)。LCPの内訳を見て、画像自体の読み込みに時間がかかるのか、読み込み開始や表示が遅れているのかを分けて考えます。

画像で確認する四点

1. 最大画像にloading="lazy"が付いていないか。 同記事は、LCP画像を遅延読み込みにしてはいけないと明言しています。不要な読み込み遅延が必ず生じるためです。AIは「画像には lazy を付けるもの」と機械的に付けることがあるので、先頭の大きな画像だけは確認します。

2. LCP画像の読み込み優先度。 fetchpriority="high"を付けると高い優先度で取得できます。MDNでもimgの属性として説明されています(img要素)。

3. 画像がHTMLに直接書かれているか。 LCP画像がJavaScriptで後から追加されたり、CSSの背景画像だったりすると、発見が遅れます。その場合は、img要素として書く方法かプリロードが必要だと、LCP最適化の記事にあります。

4. widthとheightがあるか。 寸法を書くと、ブラウザが読み込み前に縦横比を計算でき、CLSを防げます。MDNもこれを説明しています。

次のコードは、説明用の例です。私は実行・計測していません。

html
<!-- 先頭の大きな画像:lazyにしない・優先度を上げる -->
<img src="hero-800.jpg" width="800" height="450"
     srcset="hero-480.jpg 480w, hero-800.jpg 800w"
     sizes="(max-width: 600px) 100vw, 800px"
     fetchpriority="high" alt="説明用の画像">

<!-- 画面の下のほうの画像:lazyにしてよい -->
<img src="photo-1.jpg" width="400" height="300"
     loading="lazy" alt="説明用の画像">

srcsetとsizesは、画面幅に合った画像をブラウザに選ばせる仕組みです(MDN)。ファイルを幅違いで用意する手間はありますが、スマホに大きな画像を送り続けることは避けられます。なお、loading="lazy"はJavaScriptが有効なときだけ働くとMDNに書かれています。

原因2:外部から読み込むものが多い

ページが読み込む外部リソースを確認します。たとえばブラウザの開発者ツールのネットワークタブで、リクエストのドメインやファイル名を見ます。AIが作ったコードに、使っていない機能のためのライブラリや、複数のフォントやアイコン集が含まれていないか調べます。

初学者向けの判断表を作りました。これは編集上の提案で、web.devの基準そのものではありません。

  • 使っていない機能のライブラリ、まず考えること:削除して表示を確認する
  • 同じ目的のライブラリが2つ、まず考えること:どちらかに統一する
  • 小さな機能のために巨大なライブラリ、まず考えること:数行の自前コードやCSSで済まないか、AIに案を出させる
  • 計測や広告のタグ、まず考えること:本当に必要か、運営判断を確認する
  • アイコンやフォントの大量読み込み、まず考えること:実際に使う分だけに減らす

削るときは、一度に全部消さず、一つ外して画面と操作を確認します。ライブラリの削除は動作を壊しやすいため、AIの提案を鵜呑みにせず、人が画面で確かめてください。

原因3:スクリプトの読み込み順

<head>に普通の<script src="...">を書くと、HTMLの解析がそこで止まり、実行が終わるまで先に進めません。MDNは、スクリプトの属性による違いを次のように整理しています(script要素)。

  • 属性なし、実行のタイミング:その場で実行、解析を止める、順序:書いた順
  • async、実行のタイミング:ダウンロード完了次第、順序:保証なし
  • defer、実行のタイミング:解析の完了後、DOMContentLoadedの前、順序:書いた順
  • type="module"、実行のタイミング:defer相当、順序:書いた順

使い分けの目安は次のとおりです。

  • HTMLの解析後に動かす自作スクリプトはdeferにする
  • 他のスクリプトに依存しない計測タグなどはasyncでもよい
  • ライブラリAのあとにAを使うコードを実行したいなら、asyncは避けてdeferにする(順序が保証されないため)
html
<script defer src="library.js"></script>
<script defer src="app.js"></script>

これも説明用の例で、未実行です。deferにして画面が動かなくなったときは、スクリプトが解析前に要素を探していたり、順序に依存していたりする可能性があります。その場合は元に戻してAIにエラー文を渡します。

AIに渡す依頼文と、人が確認すること

AIには、HTML、計測結果の要点、外部読み込みの一覧を渡します。個人情報、社内のURL、APIキーなどは、説明用のダミーに置き換えてから貼ってください。AIに学習利用の設定があっても、それは秘密を守る保証とは別の話です。

次のページが重いので、原因の候補を3つ以内に絞って、
修正案を小さい順に出してください。

【計測結果】
- LCP: ○秒(モバイル)、最大コンテンツ要素: <img class="hero">
- CLS: ○、TBT: ○ms
【外部読み込み】
- (ドメインとファイル名を列挙)
【HTML】
(<head>と最初のセクションを貼る)

条件:
- 先頭の大きな画像に loading="lazy" が付いていないか確認する
- img に width / height があるか確認する
- script を defer / async にできるか、理由つきで判断する
- 見た目と動作は変えない
- 変更箇所は差分で示し、リスクも書く

AIの回答を受けたら、人が次の点を確認します。

  1. 修正は一つずつ適用したか
  2. 画面の見た目、ボタンやフォームの動作が変わっていないか
  3. 同じ条件で測り直し、LCP・CLS・TBTのどれが動いたか
  4. 動いた指標が、直した箇所と対応しているか

改善が数字に出なくても、直した内容が正しいことはあります。手元の計測はぶれるので、数字が動かないときは、回数を増やすか、実ユーザー側の指標も見る必要があります。

出典・参考資料