mcpField
M
maui-performance

maui-performance

github.com/davidortinau開発176129 回インストール16 週間前に更新
リポジトリ

maui-performance について

.NET MAUI アプリ開発者向けのパフォーマンス最適化スキルです。プロファイリング、バインディングやレイアウト、起動処理、トリミング、NativeAOT を扱います。

主な機能

  1. 01dotnet-trace と PerfView による分析
  2. 02コンパイル済みバインディングとリフレクション削減
  3. 03レイアウトとコレクション計測の最適化
  4. 04画像サイズとキャッシュの調整
  5. 05起動処理の削減とトリミング・NativeAOT の設定

活用シーン

  1. 01MAUI アプリの CPU・メモリ負荷の特定
  2. 02ページレイアウトとコレクション描画の改善
  3. 03トリミングや NativeAOT 公開前の互換性確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/davidortinau/maui-skills --skill maui-performance

インストール後、Claude Code で/maui-performanceを入力して読み込まれたか確認します。

詳細

.NET MAUI のパフォーマンス最適化

プロファイリング

  • dotnet-trace:すべての MAUI ターゲットに対応するクロスプラットフォームのプロファイラーです。次のコマンドでトレースを収集します。
    dotnet-trace collect --process-id <PID> --providers Microsoft-DotNETCore-SampleProfiler
    
  • PerfView(Windows のみ):WinUI ターゲットでの詳細なメモリ割り当てと CPU の分析に使用します。
  • 最適化の前にプロファイリングを行ってください。推測ではなく、測定しましょう。

コンパイル済みバインディング

  • コンパイル済みバインディングを有効にするため、ページやビューには必ず x:DataType を設定します。
  • コンパイル済みバインディングは、リフレクションベースのバインディングより8~20 倍高速です。
  • NativeAOT と完全なトリミングでは必須です。リフレクションバインディングはトリミング時に機能しなくなります。
  • x:DataType は、合理的に設定できる最も上位のスコープ(ページまたはルート要素)に設定します。
<ContentPage xmlns:vm="clr-namespace:MyApp.ViewModels"
             x:DataType="vm:MainViewModel">
    <Label Text="{Binding Title}" />
</ContentPage>
  • CollectionView/ListView 内の DataTemplate では、テンプレートのルートに x:DataType を設定します。
<DataTemplate x:DataType="model:Item">
    <Label Text="{Binding Name}" />
</DataTemplate>
  • 不要なバインディングを最小限にします:変化しない静的なコンテンツに {Binding} は不要です。代わりにリテラル値または x:Static を使用します。

レイアウトの最適化

  • 子要素が 1 つだけのレイアウトの入れ子は避けます。子要素が 1 つだけの StackLayout は無駄なオーバーヘッドになります。
  • 入れ子の StackLayout/VerticalStackLayout より Grid を優先します。Grid は 1 回のパスでレイアウトを解決します。
  • 実行時に要素をツリーに追加・削除するのではなく、IsVisible="False" を使って非表示にします。
  • 不要なラッパーコンテナーを削除します。レイアウトを追加するたびに、計測と配置のパスが増えます。
  • Grid の行/列定義で同じ結果を実現できる場合は、AbsoluteLayout を避けます。
  • サイズが分かっている場合は WidthRequest/HeightRequest を明示的に設定し、計測のパスを減らします。

CollectionView と ListView

  • 項目の高さが均一な CollectionView では、ItemSizingStrategy="MeasureFirstItem" を使用します。これにより、項目ごとの計測を避けられます。
<CollectionView ItemSizingStrategy="MeasureFirstItem"
                ItemsSource="{Binding Items}">
  • 新規開発では ListView より CollectionView を優先します。
  • DataTemplate のビジュアルツリーは浅く保ちます。項目ごとの入れ子レイアウトを減らします。

画像の最適化

  • 表示解像度に合わせて画像のサイズを調整します。200×200 の表示に 4000×3000 の画像を読み込まないでください。
  • Aspect="AspectFill" または AspectFit を使用し、サイズを明示的に設定します。
  • ダウンロードした画像をキャッシュします:UriImageSource では CachingEnabled="True"(デフォルト)を使用し、CacheValidity を設定します。
  • プラットフォームに適した形式を使用します(Android では WebP、iOS では HEIF/PNG)。
  • アイコンやシンプルなグラフィックには、SVG またはベクターベースのフォントアイコンを優先します。

リソースディクショナリ

  • アプリレベル(App.xaml):複数のページで使用する共通のスタイル、色、コンバーター。
  • ページレベル:特定のページに固有のスタイル/リソースを定義し、App.xaml を簡潔に保ちます。
  • ディクショナリ間でリソースを重複させないようにします。
  • 大規模なリソースセットを整理するには MergedDictionaries を使用し、単一ファイルの肥大化を防ぎます。

起動時の最適化

  • App コンストラクターと MainPage コンストラクターでの処理を最小限にします。
  • 必須ではないサービスの登録を遅らせ、可能な場合は遅延初期化を使用します。
  • 起動時に解析する XAML ページの数を減らします(遅延読み込みには Shell ルーティングを使用します)。
  • MauiProgram.cs から未使用の Handlers/Effects の登録を削除します。
  • Android では、起動時に不要な権限チェックが強制されないよう、AndroidManifest.xml を確認します。

トリミング

IL トリミングを有効にして、アプリのサイズを縮小し、未使用のコードを削除します。

<PropertyGroup>
    <PublishTrimmed>true</PublishTrimmed>
    <TrimMode>full</TrimMode>
</PropertyGroup>
  • 十分にテストしてください。トリミングによって、リフレクション経由でのみアクセスされるコードが削除される場合があります。
  • リフレクションの対象を保持するには、[DynamicDependency] または [UnconditionalSuppressMessage] を使用します。
  • コンパイル済みバインディングは不可欠です。リフレクションベースのバインディングはトリミングによって削除されます。

NativeAOT

  • NativeAOT は事前にネイティブコードへコンパイルするため、起動が速くなり、フットプリントが小さくなります。
  • 要件:コンパイル済みバインディング、制約のないリフレクションを使用しないこと、トリミング互換のコード。
<PropertyGroup>
    <PublishAot>true</PublishAot>
    <PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
  • サードパーティ製 NuGet パッケージのトリミング/AOT 互換性を監査します。
  • リフレクションベースの JSON シリアル化の代わりに、[JsonSerializable] ソースジェネレーターを使用します。
  • リリース前に AOT を有効にして dotnet publish を実行し、警告がないことを確認します。

クイックチェックリスト

  1. ✅ すべてのページ、テンプレート、データバインドされたビューに x:DataType を指定します
  2. ✅ 単一の子要素を持つレイアウトの入れ子を避けます
  3. ✅ 入れ子になった StackLayouts より Grid を優先します
  4. ✅ 画像を表示サイズに合わせ、キャッシュを有効にします
  5. ✅ 均一な CollectionViews に ItemSizingStrategy="MeasureFirstItem" を指定します
  6. ✅ 起動時の処理を最小限に抑え、後回しにします
  7. ✅ トリミングを有効にしてテストします
  8. ✅ 変更の前後に dotnet-trace でプロファイルを取得します

コメント