Web高速化の最前線|遅延読み込み(Lazy Load)・コード圧縮・INP対策でLighthouseスコア90点超えを狙う

Web高速化の最前線|遅延読み込み(Lazy Load)・コード圧縮・INP対策でLighthouseスコア90点超えを狙う

Web高速化の最前線|遅延読み込み(Lazy Load)・コード圧縮・INP対策でLighthouseスコア90点超えを狙う

ページ表示が1〜3秒に伸びると直帰率が32%高まる──Google/SOASTAの2017年調査が示すように(モバイル実測値)、「体感の速さ」はコンバージョンの前提条件です。

しかも2025年の今、“速さ”は単なるUX改善ではなく、検索評価を左右する〈Core Web Vitals〉のスコアそのもの。

この記事では遅延読み込み(Lazy Load)コード圧縮を中心に、Lighthouseスコアを即日底上げする実践テクニックを解説します。

目次

Core Web Vitals最新事情──INP時代の3本柱

2024年3月のアップデート以降、主要指標はLCP・CLS・INPの3つです。INP(Interaction to Next Paint)はページ全体の相互作用レイテンシーを評価し、200 ms未満が“良好”の目安。

旧指標FIDはタップやクリックの初動しか測れませんでしたが、INPは「ページ滞在中で最も遅い操作」を拾うため、JavaScript実行時間とレンダリング負荷を同時に最適化する必要があります。

ページ冒頭で不要なスクリプトを遅延ロードし、メインスレッドをブロックしない設計がこれまで以上に重要です。

参考:web.dev | INP が FID の後継指標になった理由

遅延読み込み(Lazy Load)の原理と最新ブラウザ対応

Lazy Loadは「ビューポートに入る直前まで通信を遅らせる」ことで初期表示を軽くする手法です。2025年5月現在、loading="lazy"はChrome 76・Edge 79・Firefox 75・Safari 15.4・Opera 64以降、ほぼすべての主要ブラウザが標準サポート済み。

WordPress 6.4以降は画像に自動付与されますが、ヒーロー画像まで遅延するとLCPが悪化するため、ファーストビュー要素にはloading="eager"または属性省略で即時ロードに切り替えましょう。

ネイティブloading=”lazy”属性の使い方

基本形:

<img src="team.webp" alt="チーム写真" width="600" height="400" loading="lazy">

Chromeの実装では「ビューポート+1画面」でプリロードが走るため、ユーザーが高速スクロールしても白抜けが起きにくい設計です。

YouTube iframeや広告タグにもloading="lazy"が効くため、CLS改善にもつながります。

Intersection ObserverによるカスタムLazy Load

スクロール速度や“手前読み”距離を柔軟に調整したいならIntersection Observerを使います。

// 遅延読み込み対象の画像をすべて取得
const lazyImages = document.querySelectorAll('[data-src]');

// IntersectionObserverのインスタンスを作成
const io = new IntersectionObserver((entries, obs) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      // ビューポートに入ったらdata-srcをsrcに置き換え
      const img = entry.target;
      img.src = img.dataset.src;
      img.removeAttribute('data-src');
      // 監視を解除してパフォーマンス向上
      obs.unobserve(img);
    }
  });
}, { rootMargin: '200px' });   // 200px手前で先読み

// 各画像にObserverを登録
lazyImages.forEach(img => io.observe(img));

rootMarginを広げるほど事前ダウンロードが早まり、UIの“チラ見え”を防げます。Reactならカスタムフック化し、SSR時はクライアントのみでobserverを生成することを忘れずに。

コード圧縮&Tree Shaking──実バイト数を削る王道

Lighthouseの「Reduce JavaScript Execution Time」が赤字なら、まずビルド時にMinify+Tree Shakingを有効化しましょう。

Webpack 5/Esbuild/Viteはいずれもproductionモードで自動的にTerserが走り、未使用exportが除去されます。

Google PageSpeed Insights公式デモでは、同一SPAをミニファイ前767 KB→62 KB(gzip)に削減し、TTIを42%短縮した事例が示されています。

さらに<script type="module">nomoduleフォールバックでモダンブラウザ専用バンドルを分離し、初回ダウンロードを最低限に。

Brotli/Gzipで転送サイズを最小化

Brotli圧縮はGzip比で20〜30%優位ですが、サーバーモジュールが前提です。Apache 2.4ならmod_brotliをロードし、設定例は:

<IfModule brotli_module>
  AddOutputFilterByType BROTLI_COMPRESS text/html text/css application/javascript
  BrotliCompressionQuality 5
  BrotliMinLength 1024  # 1KB以上のファイルのみ圧縮(極小ファイルには非推奨)
</IfModule>

Nginx公式ビルドには含まれていないため、ngx_brotliをソースコンパイルするか、OpenResty系ディストリを採用します。

※もし導入が難しい場合は、CloudflareやFastlyなどのCDNサービスを利用すれば、Brotli圧縮を簡単に有効化できます。既存サーバー構成を変えずに済むため、運用ハードルも下がります。

Cache-Control: public, max-age=31536000, immutableを併用すれば再訪問時はTLSネゴシエーションを省略でき、Core Web Vitalsの「Network Round Trips」節約に直結します。

Lighthouse計測とfetchpriority=”high”の活用

最適化後はChrome DevToolsのLighthouseを再実行し、モバイルPerformance 90点超えを目標に。「Opportunities」の節約時間合計がゼロ近くなら合格です。

なおChrome 101/Edge 101以降はfetchpriority="high"属性で重要リソースの優先度を上げられますが、Firefox・Safari(TP版のみフラグ対応)は未サポートです。

非対応ブラウザでは無視されるだけなので、フォールバック処理は不要ですが、“多用し過ぎると逆効果”という点は覚えておきましょう。

複数の画像・スクリプトすべてに指定すると、ブラウザの優先度制御が機能しにくくなり、かえってLCPが悪化することがあります。

重要なのは「LCPに寄与するメイン画像やヒーロー要素など、本当に優先表示すべきリソース」に絞って使うことです。

参考:MDN | fetchpriority属性のブラウザ対応

HTTP/HTTPSとは?ステータスコード・ヘッダー・TLSの仕組み

まとめ:今日から“赤字”を緑に変えよう

Core Web Vitalsは毎年進化していますが、ユーザーの体感はシンプル──“サクサク動くサイトが好き”。

Lazy Loadで初期転送を削り、Minify+Brotliで実バイト数を圧縮し、LighthouseでBefore/Afterを可視化する。

この3ステップを回すだけで、ページは確実に速くなり、INP・LCP・CLSすべてが改善します。デザインやコンテンツを磨く前に「速さ」を整えれば、読者のエンゲージメントも検索順位もあとから自然と付いてくるはずです。

【HTML】レスポンシブ画像の最適化テクニック|srcset・picture要素の実装と使い分け

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次