はじめに
モバイルWebパフォーマンスはもはや二の次ではありません。世界のWebトラフィックの60%以上をモバイルが占め、新興市場ではさらに成長が続いています。サイトのパフォーマンス特性は、ユーザーの継続率、コンバージョン、検索順位に直接影響を与えます。53%のモバイルユーザーは読み込みに3秒以上かかるサイトを離脱します。本記事では、ネットワーク状態に応じたアダプティブローディングからタッチイベント最適化、Core Web Vitalsまで、2024年のモバイルWebパフォーマンス最適化の主要テクニックを解説します。
ネットワーク状態とアダプティブローディング
モバイルネットワークは有線接続とは根本的に異なります。高レイテンシ、パケット損失、変動するスループットが常態です。5Gの普及が進んでいるものの、地域による差は大きく、新興市場では多くのユーザーが3Gや低速4Gに依存しています。Network Information APIを使用すると、実行時にネットワーク状態を検出できます。
const connection = navigator.connection;
if (connection) {
const effectiveType = connection.effectiveType; // "slow-2g" | "2g" | "3g" | "4g"
const isSlow = effectiveType === "slow-2g" || effectiveType === "2g";
if (isSlow) {
// 低解像度画像の配信、アニメーションの無効化
loadLowQualityAssets();
}
}
ユーザーがブラウザのデータセーバーモードを有効にしている場合、Save-Dataヘッダーとnavigator.connection.saveDataプロパティも利用可能です。これらのAPIと、<link rel="preconnect">による重要オリジンへの事前接続、rel="prefetch"による予測ナビゲーションのプリフェッチを組み合わせることで、帯域を浪費せずに高速な体験を提供できます。
Service Workerはモバイルで特に価値のあるオフラインファーストのキャッシュ戦略を可能にします。Workboxなどのライブラリを使用して、APIレスポンスにはstale-while-revalidate、静的アセットにはcache-first戦略を実装しましょう。HTTP/2やHTTP/3では多重化により複数接続のオーバーヘッドが削減され、高レイテンシネットワークでのアセット配信が効率化されます。
デバイスメモリへの対応
2〜4GBのRAMを搭載したローエンドモバイルデバイスは、特に新興市場で広く使われています。Device Memory APIを使用すると、デバイスの利用可能RAMを取得し、リソース使用量を調整できます。
const deviceMemory = navigator.deviceMemory; // 0.25, 0.5, 1, 2, 4, 8
if (deviceMemory < 4) {
// 重いアニメーションを無効化、バンドルサイズを削減
disableExpensiveFeatures();
}
大規模なアセットをキャッシュする前にnavigator.storage.estimate()を使用して利用可能ストレージを確認します。メモリ監視にはperformance.measureUserAgentSpecificMemory() API(Chromium系ブラウザで利用可能)が役立ち、メモリプレッシャーを検出してOOMクラッシュを防げます。ベストプラクティスとしては、メモリ内の大規模データ構造を避け、大量データセットはストリーミング処理し、無限スクロールにはページネーションを実装することが挙げられます。
タッチイベントとスクロールパフォーマンス
タッチ操作はモバイルの主要な入力手段です。タッチハンドラの最適化は60 FPSの体験を実現するために不可欠です。最も効果的な対策は、タッチイベントリスナーにpassiveフラグを追加することです。
document.addEventListener("touchstart", handler, { passive: true });
document.addEventListener("touchmove", handler, { passive: true });
これにより、ハンドラがpreventDefault()を呼び出さないことをブラウザに伝え、スクロールがハンドラを待たずに進行できるようになります。フレームあたり10〜30msの改善が期待できます。
同様に、touch-action CSSプロパティを使用してインタラクティブ要素のダブルタップズームを無効にし、レガシーブラウザでの300msタップ遅延を排除します。
| CSSプロパティ | 効果 |
|---|---|
touch-action: manipulation | ダブルタップズームを無効化、タップを即時反応に |
touch-action: pan-y | 垂直方向のパンのみに制限 |
touch-action: none | すべてのブラウザタッチジェスチャーを無効化 |
Pointer Events APIはマウス、タッチ、ペン入力を統一的に扱います。pointer: fineおよびpointer: coarseメディアクエリと組み合わせることで、入力手段に応じたヒットターゲットやジェスチャー処理を実装できます。タッチハンドラのフレームバジェットは16msを守り、レイアウトプロパティの読み取りと書き込みを分離してレイアウトスラッシングを回避しましょう。
レスポンシブ画像とアダプティブローディング
画像はほとんどのモバイルサイトでページ重量の最大の要因です。<picture>要素とsrcset、sizesを組み合わせることで、アートディレクションと解像度スイッチングを実現します。
<picture>
<source srcset="hero.avif" type="image/avif" />
<source srcset="hero.webp" type="image/webp" />
<img
src="hero.jpg"
srcset="hero-375.jpg 375w, hero-768.jpg 768w, hero-1280.jpg 1280w"
sizes="(max-width: 768px) 100vw, 50vw"
loading="lazy"
fetchpriority="high"
decoding="async"
alt="ヒーロー画像"
/>
</picture>
画面外の画像にはloading="lazy"、ファーストビューのヒーロー画像にはfetchpriority="high"、デコードのメインスレッドブロッキング回避にはdecoding="async"を指定します。Image CDNは最適フォーマット(WebP、AVIF)の自動選択、ビューポートに応じたリサイズ、品質最適化を提供します。
画像以外にも、ルートベースのコード分割、React.lazy/Suspenseによるコンポーネントレベルの分割、CSSのcontent-visibility: autoによる画面外レンダリングのスキップ、TanStack Virtualなどの仮想スクロールライブラリによる長大リストのDOM削減が効果的です。
モバイルCore Web Vitals
Core Web Vitalsはモバイルユーザー体験の標準化された測定フレームワークを提供します。
| 指標 | 良好な目標値 | モバイルでの課題 |
|---|---|---|
| LCP(Largest Contentful Paint) | < 2.5秒 | 低速ネットワークでのヒーロー画像読み込み、フォントレンダリング遅延 |
| INP(Interaction to Next Paint) | < 200ms | 重いメインスレッド、遅いイベントハンドラ、レイアウトスラッシング |
| CLS(Cumulative Layout Shift) | < 0.1 | 動的広告読み込み、フォントスワップによるシフト、サイズ未指定の画像 |
LCP対策には画像CDNへのpreconnect設定、ヒーロー画像へのfetchpriority="high"、レスポンシブ画像、font-display: optionalによるフォントブロッキング防止が有効です。INP対策にはパッシブイベントリスナー、入力ハンドラのデバウンス、50msを超えるロングタスクの分割、navigator.scheduling.isInputPending()による入力待機時の譲歩が重要です。CLS対策には画像への明示的なwidth/height指定、aspect-ratio CSS、動的コンテンツへのmin-height予約スペース設定が必要です。
モバイルパフォーマンスのテスト
エミュレーションのみでのテストは不十分です。Lighthouse MobileでCPUとネットワークをスロットルしたベースライン測定を行い、必ず実機でも検証しましょう。WebPageTestは実際のモバイルデバイスを使ったテストとビデオキャプチャによるフレーム単位の分析を提供します。Chrome DevToolsのデバイスエミュレーションではネットワークスロットルと6倍CPUスロットルが利用できます。
本番監視には**Chrome User Experience Report(CrUX)**とRUMツールによるフィールドデータの収集が不可欠です。web-vitals npmパッケージを使えば、LCP、INP、CLS、FCP、TTFBを本番環境で簡単に測定できます。最後に、CIにパフォーマンスバジェットを組み込み、バンドルサイズや指標がしきい値を超えた場合に自動的に失敗する仕組みを作りましょう。
まとめ
モバイルパフォーマンス最適化には、ネットワーク認識、メモリを意識した読み込み、スムーズなタッチ操作、レスポンシブ画像という全体論的アプローチが必要です。Network Information APIとDevice Memory APIを組み合わせたデバイス能力に基づくアダプティブローディングが、今日の多様なモバイルデバイスに対応する鍵です。Core Web Vitals(LCP、INP、CLS)を測定フレームワークとして活用し、エミュレーションだけでなく実機でテストして実際のパフォーマンス特性を把握しましょう。
