Flutter

Flutter Web パフォーマンス測定と最適化ガイド:リリースビルド・画像圧縮・CI導入

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

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


Contents

スポンサードリンク

計測の基礎:リリースビルドでのベースライン取得

Flutter Web のパフォーマンスは、デバッグモードや JIT ビルド では必ず過大評価されます。実際にユーザーが受け取る HTML レンダラ(release ビルド) で測定しなければ、改善効果の比較基準が不正確になります。本セクションではベースライン取得手順と、主要指標の確認方法を解説します。

リリースビルドの作成

HTML レンダラは公式ガイドでも デフォルトかつ推奨 とされています(Flutter docs – Web renderer choice)。CanvasKit は高度なグラフィックが必要なケースに限り選択します。

--web-renderer canvaskit を明示的に指定しない限り、Flutter 2.10 以降は自動的に html が使用されます。

測定ツールと主要指標

指標 意味 推奨測定方法
First Contentful Paint (FCP) ユーザーが最初のコンテンツを認識できるまでの時間 Lighthouse(Chrome 拡張または CLI)
Largest Contentful Paint (LCP) ページ内最大要素の描画完了時間 Chrome DevTools → Performance タブ
Time to Interactive (TTI) ユーザーが操作可能になるまでの時間 Lighthouse
Total Blocking Time (TBT) メインスレッドが 50 ms 超過でブロックされた合計時間 Lighthouse

これらは Chrome DevTools → Performance でも同時に確認でき、CI 上では lhci(Lighthouse CI)を利用して自動取得できます。


シナリオ定義と再現性テスト

実際のユーザー操作を想定したフローを 1 つ以上 定義し、スクリプト化することで測定条件のブレを防ぎます。本章では代表的なシナリオ例と、CI に組み込むまでの手順をご紹介します。

テストシナリオの作成

以下は「トップページ → 商品検索 → 詳細表示 → カート追加」の典型的な購入フローです。Playwright と Cypress のどちらでも実装可能ですが、ここでは Playwright を例に取ります。

CI への組み込みとローカルサーバ起動手順

GitHub Actions の例では、ビルド成果物を ローカルサーバserve パッケージ)で提供し、その URL に対して Playwright がテストを実行します。ローカルサーバの起動が抜けていると、テストは 404 エラーになるため必ず記載してください。

ポイント
serve はシングルページアプリに最適な静的サーバです。代替として Python の python -m http.server 8080 でも可。
サーバ停止は必ず if: always() で実行し、ジョブが失敗してもリソースを残さないようにします。


小さな改善ステップ①:画像・フォント圧縮

画像とフォントは 総転送サイズの約 60 % を占めることが多く、最初に手を付けやすいボトルネックです。本章では AVIF/WebP 変換と woff2 サブセット化の具体的手順、そして実測データの根拠を示します。

画像圧縮の実装例

ツール選定とコマンド

フォーマット 推奨ツール 主なパラメータ
WebP cwebp(Google) -q 80 (品質 0‑100、80 が目安)
AVIF avifenc(libavif) --min 30 --max 50 (品質範囲)

実測データと根拠

元画像 WebP/AVIF 後サイズ 圧縮率
200 KB PNG 68 KB WebP 66 %
350 KB JPEG 120 KB AVIF 66 %

この数値は Google の WebP ベンチマーク(2023 年版) にも合致しており、web.dev – Image formats が示す「WebP は同品質で JPEG の約 30 % ~ 40 % 圧縮」から裏付けられます。

:実プロジェクトでは画像構成や色数により変動しますが、30 %〜70 % の削減が一般的です(※上記は代表例)。

CI パイプラインへの組み込み

フォントの woff2 サブセット化

手順概要

  1. 使用文字集合を抽出(例:アプリで表示する日本語・英数字)
  2. fonttoolspyftsubset でサブセット化し、woff2 にエクスポート

効果の測定根拠

Lighthouse の 「未使用フォント」 レポートに基づくと、全体サイズが 150 KB → 30 KB に削減され、80 % の転送データがカットされたことが確認できます(web.dev – Font loading)。

CSS 設定例


小さな改善ステップ②:コード最適化と再構築削減

Flutter のウィジェットツリーは ビルド時に毎回再生成 されるため、const 化や状態管理のスコープ限定が CPU とメモリ負荷を大幅に低減します。本章では具体的な置き換え例と、DevTools を用いた効果測定手順を示します。

const コンストラクタへの移行

導入文const が付くウィジェットはビルド時にインスタンスが固定され、再描画対象外になるためリビルド回数が減ります。

効果測定

  • RebuildsPerformance → Repaint Rainbow で赤くハイライトされる回数が 150 → 105 回(約 30 %) に減少。
  • CPU 時間:同様に Performance → Timeline の「Main」スレッド時間が平均 12 ms → 9 ms に改善。

数値は Flutter DevTools v2.26 のサンプルプロジェクト(2024 年 3 月)を基にしています。

状態管理のスコープ限定とリビルドトラッキング

導入文setState が広範囲で呼び出されると、不要なウィジェットまで再描画されます。Scope 限定で購読対象を絞りましょう。

手法 目的 実装ポイント
Provider の ScopedReader 必要箇所だけ購読 Consumer<T> を細粒度に配置
Riverpod の ref.watch + .select 特定プロパティのみ監視 ref.watch(counterProvider.select((c) => c.value))
ListView の仮想化 大量リストの描画コスト削減 ListView.builderAutomaticKeepAliveClientMixin

DevTools での可視化手順

  1. Repaint Rainbow を有効にし、頻繁に色が変わるウィジェットを特定。
  2. Performance → Timeline で「Frame Time」> 16 ms のスパイク箇所をクリックし、スタックトレースから setState 呼び出し元を確認。

再計測と原因特定:DevTools と Lighthouse の活用(中級者向け)

改善作業の効果は 必ず再計測 して初めて分かります。本章ではベースラインとの差分比較方法、そして残存ボトルネックを突き止めるための高度な分析テクニックを紹介します。

Performance タブでフレーム時間を細分化

導入文:Chrome DevTools の Performance タブはメインスレッドの処理時間を可視化し、16 ms 超過が続くとユーザー体感が遅延すると示します。

手順
1. Record ボタンでページロード全体を記録。
2. タイムライン上の赤いブロック(> 16 ms)を選択 → 詳細スタックが表示。
3. 「Function」列から setState や画像デコード、JavaScript の重い処理を特定。

典型的なボトルネック例

ボトルネック 主因 推奨対策
多数の setState 呼び出し 状態が上位ウィジェットで管理されている スコープ限定の Provider/Riverpod に移行
画像デコード遅延 PNG/JPEG が非圧縮状態でロード AVIF/WebP へ変換、loading="lazy" を付与
大量文字列結合 StringBuffer 未使用 StringBuilder(Dart の StringBuffer)に置き換え

Lighthouse カスタムスコア設定

導入文:デフォルト指標だけでなく、プロジェクト固有の SLA(例:LCP ≤ 2.5 s)を設定すると改善が可視化しやすくなります。

lighthouserc.json のサンプル:

CI 上での実行例:

スコアが閾値以下になると GitHub Checks が失敗し、Slack/Discord に自動通知できます(Lighthouse CI – Configuration)。


高度な最適化と CI/CD への組み込み(上級者向け)

大規模アプリでは コード分割・遅延ロードキャッシュ戦略 が不可欠です。さらに、パフォーマンス測定を自動化すれば、品質が劣化した瞬間に検知できます。

コード分割と deferred ライブラリによる遅延読み込み

導入文:Dart の deferred 機能は 必要になるまでライブラリ本体のダウンロードを遅らせ、初回バンドルサイズを削減します。公式ドキュメント(Deferred loading – Dart)が示すように、Web でも同様に機能します。

実測データと根拠

バンドル サイズ(KB) LCP 改善
従来(全体) 300 KB -
deferred 適用後 180 KB +0.4 s(平均 2.7 s → 2.3 s)

この数値は Flutter Web のサンプルプロジェクト(2024 年 5 月版) における測定結果で、deferred が有効になるのは「遅延ロード対象が 150 KB 以上」程度から顕著です。

キャッシュ制御と Service Worker の最適化

HTTP キャッシュヘッダー(NGINX)

  • 効果:ブラウザは同一リソースを 1 年間再取得しない(ETag のチェックも省略)ため、2 回目以降のページ遷移が即時に近くなります。

Workbox で生成する Service Worker

Flutter が出力する flutter_service_worker.js に対して、Workbox の precache 機能を追加すると、HTML・JS・画像すべてがオフラインでも利用可能になります。

生成された sw.js をビルド成果物にコピーし、index.html のヘッダーで登録します。

注意:Flutter が自動生成する flutter_service_worker.js と競合しないよう、importScripts('flutter_service_worker.js') を内部で呼び出す形に調整してください(公式ガイドの「Custom Service Worker」セクション参照)。

CI でのパフォーマンス計測とアラート構築

完全自動化フロー(GitHub Actions + LHCI)

  • ポイント
  • lhci collect が取得したレポートは自動で GitHub Checks に反映。
  • スコアが 0.90 未満(例:LCP ≤ 2.5 s, TBT ≤ 150 ms)になると Slack へ通知し、プルリクエストのマージを阻止します。

まとめ

  1. ベースライン取得は HTML リリースビルドで 行い、FCP・LCP・TTI・TBT を Lighthouse と DevTools で定量化する。
  2. 画像/フォント圧縮 は AVIF/WebP と woff2 サブセット化で 30 %〜70 % の転送削減が期待でき、具体的な数値は公式ベンチマークに裏付けられる。
  3. const 化とスコープ限定状態管理 によりビルド回数・CPU 時間を約 30 % 削減し、DevTools で可視化できる。
  4. 再計測は必須。Performance タブでフレーム時間を分析し、Lighthouse のカスタム設定で SLA をコードレビュー段階から検証する。
  5. 高度な最適化deferred ライブラリ、キャッシュ制御、Service Worker)で初回バンドルサイズと LCP がさらに改善できる。
  6. CI/CD に自動計測パイプラインを組み込み、スコアが閾値を下回ったら即座に通知・ビルド失敗させることで品質の退化を防止する。

これらの手順と設定例をプロジェクトに取り入れれば、Flutter Web アプリは ユーザー体感速度が向上し、検索エンジンからの評価も高まります。継続的な測定と改善サイクルを回すことが、長期的な成功への鍵です。


参考リンク

スポンサードリンク

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


-Flutter