Flutter

Flutter Web パフォーマンス最適化と診断ワークフロー

ⓘ本ページはプロモーションが含まれています

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


短縮まとめ(対象別実行手順)

ここでは短時間で効果が出る優先改善と、詳細プロファイリングやCI導入への導線を示します。初心者・中級者・上級者ごとに最初に取るべき具体アクションを短くまとめます。

初心者(即効改善を最優先にしたい場合)

初心者はまず「計測してから最小限の手を打つ」流れを守ってください。手順は以下の順に実行します。

  • release ビルドでベースラインを取得する(HTML レンダラー推奨)。
  • 画像・フォントを圧縮(AVIF/WebP、woff2 サブセット)して再計測する。
  • const の適用や不要な再構築の除去を行い、改善を小さく複数回に分けて PR にする。

中級者(詳細プロファイリングで原因を特定する場合)

中級者は DevTools と Lighthouse を組み合わせて原因を突き止めます。代表シナリオを定義して再現性を確保してください。

  • profile ビルドで Flame chart とメモリスナップショットを取得する。
  • Lighthouse を複数回実行し JSON を保存、差分で効果を評価する。
  • 長時間タスク(>50ms)や 16ms フレーム超過を優先的に改善する。

上級者(CI 組み込みと運用ルールを回す場合)

上級者は自動化と運用を整え、閾値超過時の対応ルールを作ります。RUM を導入して実ユーザーを監視します。

  • LHCI で PR ゲートを作り、閾値(例: LCP 90th < 2.5s、バンドル増分 < 5%)を設定する。
  • web‑vitals ベースの RUM を導入し、PII 非含有・サンプリング・保存期間を決める。
  • 閾値違反時は自動 Fail → Slack 通知 → 即時ロールバック/Feature‑flag 停止のフローを用意する。

測定(DevTools / Lighthouse / RUM)

まずは正確なデータを取り、条件を揃えて比較できるようにしてください。DevTools でのトレースと Lighthouse のラボ測定、RUM(web‑vitals)を組み合わせると原因特定とユーザー影響度評価が両立できます。

DevTools での CPU・フレーム・メモリ計測

DevTools は JavaScript と Flutter 側の処理を照らし合わせるのに有効です。profile ビルドで実行し、代表シナリオを録画してください。

  • Profile モードでアプリを起動して DevTools の Performance を記録します。
  • Flame chart で長時間タスク(50ms超)を探し、コールスタックで原因関数を特定します。
  • Frame chart では Build / Layout / Paint の比率を確認し、16ms を超えるフレームに注目します。
  • Memory タブでスナップショットを取得し、retained size が増加する箇所を調べます。

Lighthouse(ラボ)と RUM(実ユーザー)の住み分け

Lighthouse は比較的再現性の高いラボ評価を提供しますが、実ユーザーの分布や接続状況は RUM で補完してください。ツールのバージョンで指標定義が変わるため、計測時のバージョンを必ず保存します。

  • Lighthouse(複数回実行、JSON 保存)で FCP/LCP/CLS/TBT/TTI/INP を採取します。
  • RUM は web‑vitals(LCP/CLS/INP 等)で収集すると良いです。PII を含めないこと、サンプリングと保持期間を運用ルールで定めます。
  • ラボと RUM の乖離はユーザ分布差(デバイス・ネットワーク)を示します。SLO はパーセンタイルで設計してください(例: LCP 90th)。

分析(トレース・フレーム・メモリ)

測定結果をもとに、何が遅いか・どの層の改善が効くかを判定します。トレースとフレーム解析でボトルネック箇所を特定し、影響度と実装工数で優先度を付けます。

フレームと Flame chart の読み方

フレームチャートでは UI の Build/Layout/Paint と JS 実行の境界を確認します。どの処理が 16ms を超えているかを見つけるのが基本です。

  • 長時間タスク(50ms)で起点を特定します。JS パース・コンパイルや GC、重い Dart 側処理が典型原因です。
  • Build に偏っていればウィジェット再構築の削減、Paint に偏っていれば RepaintBoundary 等の対策を検討します。

トレース(Trace Events)解析と優先度付け

トレース全体を見て、初回表示に影響する処理(パース・初期化)とインタラクションに影響する処理(長時間タスク)を分離します。

  • FCP/LCP はユーザーがページが「見える」までの時間、TBT はブロッキング時間の合計、INP はインタラクションの応答性です。
  • 影響度×工数で優先度を決め、パーセンタイル(例: 75th/90th/95th)で SLO を設計します。

メモリとイメージリーク解析

メモリは長期的な品質に直結します。ImageCache や未解放のリスナーが典型的なリーク源です。

  • Memory スナップショットを比較して retained size と GC の挙動を確認します。
  • Image のキャッシュや大きな Uint8List 等が残っていないかをチェックします。
  • PaintingBinding.instance.imageCache 等の API は SDK バージョン依存なので、変更時は互換性を検証してください(後述の API 注記を参照)。

改善(ビルド / ランタイム / アセット)

特定したボトルネックに応じて、ビルド設定・ランタイム最適化・アセット最適化を組み合わせて改善します。ここでは実務で使える具体策と落とし穴を示します。

レンダラー選択(HTML レンダラー vs CanvasKit)

レンダラーは見た目と初回ロードのトレードオフです。HTML は軽量で CanvasKit は高品質だがサイズが増します。A/B テストで定量評価してください。

  • まず HTML で要件を満たすか検証し、CanvasKit が必要であれば比較検証を行います。
  • CanvasKit の初回バンドル増は大きいので、部分的ロード戦略や別ルート(iframe)での提供を検討してください。
  • 両者は同一シナリオで Lighthouse/DevTools による比較を必ず行ってください。

CanvasKit の部分遅延ロードと WASM 最適化

CanvasKit を使う場合、WASM と関連ファイルの配布方法で初回体感が大きく変わります。WASM は CDN 配信・Brotli 圧縮が効果的です。

  • 実務的な手法の一つは「主要ルートは HTML レンダラーで提供、重い描画ページだけを CanvasKit ビルドをホストした別 URL(例: /canvaskit-app)で iframe 表示する」方式です。
  • WASM は Brotli 圧縮で配信し、Cache‑Control: public, max‑age=31536000, immutable のようにハッシュ資産で長期キャッシュを有効にします。
  • wasm‑opt 等でさらに最適化可能だが互換性リスクがあるため、検証を厳密に行ってください。

deferred import の実践と Caveat

Dart の deferred import は有効なコード分割手法ですが、chunk 名やキャッシュ挙動に注意が必要です。

  • 実装例(遅延ロード):
    dart
    import 'heavy_page.dart' deferred as heavy;

Future openHeavyPage(BuildContext context) async {
await heavy.loadLibrary();
Navigator.push(context, MaterialPageRoute(builder: (_) => heavy.HeavyPage()));
}

  • 注意点: ビルドごとにチャンクファイル名がハッシュ化されるため、Service Worker や外部参照でファイル名を固定してはいけません。チャンクの読み込み遅延を監視し、ユーザー向けのローディング UI を用意してください。

アセット最適化(画像・フォント・配信)

初回ロードの多くは画像・フォント・JS です。圧縮、サブセット、CDN 配信を組み合わせます。

  • 画像: 写真は AVIF/WebP、アイコンは SVG、解像度別に準備してレスポンシブ配信。
  • フォント: woff2 でサブセット化し、index.html に preload を追加する(crossorigin 属性を忘れずに)。
    html
    <link rel="preload" href="/assets/fonts/Custom.woff2" as="font" type="font/woff2" crossorigin>

  • 配信: CDN + Brotli 優先、HTTP/2/3 を活用し静的資産はハッシュ名で長期キャッシュに設定します。

ランタイム最適化(ウィジェット設計・描画・アニメーション)

ウィジェットの再構築を抑え、描画コストを限定することでフレーム破綻を防ぎます。

  • const コンストラクタの活用、ステートは局所化、広範囲 setState を避けます。
  • RepaintBoundary で重いサブツリーを切り出し、CustomPainter の shouldRepaint を厳密に実装します。
  • アニメーションは transform/opacity に寄せ、layout を伴うアニメーションは最小化します。
  • ImageCache の調整は有効ですが、API は SDK 依存です。次節の互換性注意を参照してください。

Service Worker の具体例(fetch ハンドリング)

Service Worker はキャッシュ戦略で更新体験とパフォーマンスを両立します。以下は概念的な fetch ハンドラの例です。

  • 実運用では ASSETS をビルド出力から自動生成し、activate 時に古いキャッシュの掃除とユーザ通知(更新あり)UI を用意してください。

互換性と実装上の注意(API やツール)

以下は実務でよく問題になるポイントとその対処です。特に API 名やツール仕様は SDK/ツールのバージョン差で変わるため必ず検証してください。

  • PaintingBinding.instance.imageCache のプロパティは SDK によって差があるため、実行前に存在チェックを行ってください。例:
    dart
    void adjustImageCache() {
    final cache = PaintingBinding.instance?.imageCache;
    if (cache != null) {
    try {
    cache.maximumSize = 100; // SDK によっては maximumSizeBytes 等の API 名がある
    } catch (e) {
    // 互換性のない SDK の場合のフォールバック処理
    }
    }
    }

  • Lighthouse / TTI / 指標の扱いはバージョンで変わるので、LHCI や Lighthouse のバージョンを CI artefact として保存してください。

  • CanvasKit の遅延ロードは単純ではないため、iframe を使った別ビルドによる分離や CDN ホスティングを検討すると効果的です。
  • deferred import のチャンク名はビルドごとに変化するため、Service Worker や外部ツールでファイル名をハードコードしないでください。

CI と運用(LHCI / RUM / ロールバック)

CI にパフォーマンスチェックを組み込むことで回帰を防げます。閾値はプロジェクト特性で調整しますが、運用で有用な具体例を示します。

LHCI と閾値設計(実践例)

LHCI による自動判定の例と推奨閾値です。閾値はまず厳しめの「警告」→「本番閾値」へ段階的に設定します。

  • 例示的な目安(パーセンタイル指定が可能なら 90th / 75th を使う):
  • LCP 90th < 2500 ms
  • CLS 75th < 0.10
  • INP (または FID 置換) 95th < 200 ms
  • TBT 75th < 300 ms
  • バンドルサイズ増分(gzip/brotli ベース): PR 増分 < 5%
  • LHCI は assertions を使って閾値判定できます。テストはステージ URL に対して行い、結果を JSON として保存します。

CI フローと閾値超過時の対応

CI に組み込む際の現実的な運用フロー例です。自動化とヒューマンレビューを組み合わせます。

  • PR 時: ビルド → analyze-size 出力保存 → ステージにデプロイ → LHCI 実行 → アーティファクト(Lighthouse JSON, analyze-size JSON)を保存。
  • 閾値超過時の自動処理例: CI Fail → PR に自動コメント(失敗差分と最重点箇所)→ Slack 通知 → 1 時間以内に担当者アサイン。
  • 重大なスローダウンが検出された場合の即時対応: feature flag をオフにする、該当 PR を revert、緊急パッチを切る、などのランブックを用意します。

RUM とプライバシー設計

RUM は実ユーザーの分布を把握するため重要ですが、個人情報保護の観点から設計が必要です。

収集方針(推奨)

RUM を導入する際の推奨ポリシーです。コンプライアンスを満たすように設計してください。

  • PII は送らない(ユーザーID はハッシュ化するか送らない)。IP は可能であれば集計段階で匿名化する。
  • サンプリング戦略: 通常 1%〜5% をデフォルトにし、エラーや新機能ではサンプリング率を上げる。
  • データ保持: 生ログは短期(例: 30 日)、集計データは中長期(例: 365 日)で保持する運用が一般的。
  • 同意管理: GDPR 等の対象領域ではユーザー同意を取得した上で収集を行う(同意がない場合は測定を停止)。

軽量な導入例(web‑vitals)

コマンド参照(ビルド・計測・解析のコマンド集)

この節に主要なコマンドを集約します。繰り返しの説明はここで参照してください。計測時は必ずバージョンを併せて記録してください。

ビルドとサイズ解析

以下は代表的なコマンドです。--analyze-size 出力は JSON 化されるため CI に保存して差分を解析してください。

ローカル配信とプロファイル実行

Lighthouse / LHCI / サイズ確認

バージョン確認(測定時に必ず記録)

チェックリスト・ケーススタディテンプレート

現場で使えるチェックリストと、改善を記録するテンプレートを用意します。数値は必ず同一条件で計測してください。

ケーススタディ記録テンプレート

測定と改善の再現性を高めるため、PR に次を添付してください。

  • 環境: Flutter SDK、Dart、Chrome、OS、デバイス、ネットワーク条件
  • 測定方法: 使用ツール(DevTools/Lighthouse/web‑vitals)、ビルドモード、再現手順
  • 変更点: 施した改善(例: deferred import、AVIF 化、RepaintBoundary 追加)
  • 結果: バンドルサイズ(raw/gzip/brotli)、FCP/LCP/TBT/INP(測定条件明記)
  • 所見と次の対策

実践チェックリスト(優先度別)

初動(即効、数時間〜数日)

  • release ビルドでベースライン取得
  • 大きな静的アセットを圧縮/サブセット化
  • const の適用、不要な再構築を削除

中期(数週間)

  • deferred imports の導入(重ページを遅延ロード)
  • Service Worker のキャッシュ戦略見直し(index.html は network-first)
  • CDN と Brotli 導入

長期(アーキテクチャ改修)

  • CanvasKit と HTML の A/B テスト
  • CI に LHCI と analyze-size を組み込み、PR ゲート化
  • 画像配信のレスポンシブ化(Image CDN 等)

まとめと次のアクション

計測→分析→改善→CI の一連の流れを小さく回すことが最も効果的です。まずは release ビルドでベースラインを取り、初心者向けの即効策で改善効果を確認してください。中・長期的には LHCI と RUM を組み合わせ、閾値とロールバック手順を明確にして運用に落とし込んでください。

参考(公式ドキュメント)

  • Flutter ドキュメント(DevTools, Web のガイド): https://docs.flutter.dev
  • Lighthouse(Google): https://developer.chrome.com/docs/lighthouse/
  • web‑vitals ライブラリ: https://github.com/GoogleChrome/web-vitals

各ツールや API の仕様はバージョンによって変化します。計測時には使用した Flutter / Chrome / Lighthouse / web‑vitals のバージョンを必ず記録し、差分比較を行ってください。

スポンサードリンク

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


-Flutter