Power Apps のモデル駆動型アプリが重い・遅い — 原因の特定手順と、ビュー・フォーム設計の改善パターン
- DATE
- 2026-06-12
- REVISION
- A
- AUTHOR
- スルガクラフト合同会社
- SHEET
- 01 / 01
「最近、システムが重いんだけど」
モデル駆動型アプリの本番運用が始まって数ヶ月。順調に使われていたはずのアプリについて、ある日こう言われます。私はこの相談を何度も受けてきました。そして原因の大半は、同じところにあります。
この記事では、モデル駆動型アプリが重くなったときの原因の特定手順と、ビュー・フォーム設計の改善パターンを、実際に対応してきた経験ベースで整理します。
なぜ「後から」重くなるのか
まず押さえておきたいのは、この問題が開発時にはほぼ気づけないことです。
- 開発環境のテストデータが少ない(数十〜数百件では、どんな設計でも速い)
- 開発者の端末・回線が本番ユーザーより恵まれている
- 本番投入直後はまだデータが少なく、運用が進んで初めて症状が出る
つまり遅効性の毒です。データが積み上がるにつれて静かに劣化し、ユーザーが「重い」と口にした頃には、設計起因の問題が成熟しきっています。どのくらいのデータ量で顕在化するかはテーブル構成(列数、Lookup、計算列、インデックスの有無)に強く依存するので、一概な閾値は言えません。言えるのは「件数が増えれば必ず顕在化する設計」と「増えても耐える設計」がある、ということです。
Dataverseの検索が微妙すぎる件でも書きましたが、最悪のケースでは重いビューはそもそも開かなくなります。「重い」は「使えない」の前段階です。
ステップ1: どこが重いのかを切り分ける
「アプリが重い」という報告は、実際には次のどれかです。最初にここを切り分けます。
- ビューの初期表示が遅い — 一覧画面を開いてからレコードが出るまでスピナーが回る
- フォームを開くのが遅い — レコードをクリックしてから詳細画面が表示されるまでが長い
- 保存が遅い — 保存ボタンを押してから完了までが長い
- 特定の操作だけ遅い — 検索、Lookupの候補表示、サブグリッドの展開など
ユーザーへのヒアリングで「どの画面で・何をしたとき」を特定するだけで、調査範囲は一気に絞れます。「全部遅い」と言われた場合も、実際に隣で操作を見せてもらうと、たいてい1〜2箇所のボトルネックに集約されます。
ステップ2: Monitorで事実を取る
体感ではなく数字で確認します。モデル駆動型アプリには Monitor(モニター)という公式の診断ツールがあり、Power Apps のメーカーポータルからアプリをMonitor付きで起動すると、画面操作ごとのネットワーク要求・実行時間・FetchXMLが時系列で記録されます。
見るポイントは3つです。
- どのリクエストに時間がかかっているか — ビューのデータ取得か、フォームのメタデータか、JSウェブリソースか
- 同じ画面で何本のリクエストが走っているか — フォーム表示で大量のリクエストが並ぶなら、フォーム上の部品が多すぎる
- ビューのFetchXMLに何が含まれているか — 取得列数、link-entity(関連テーブルへのJOIN)、ソート条件
ここまでやれば、原因は「ビュー定義」「フォーム定義」「カスタマイズ(JS/プラグイン)」のどれかに特定できているはずです。経験上、最も多いのはビュー定義です。
ステップ3: ビューの改善パターン
列を絞る — 特にLookup・計算列・ロールアップ列
ビューの取得コストは列数に比例して増えます。中でもコストが高いのが、
- Lookup列 — 表示名を出すために関連テーブルへのJOINが発生する
- 計算列・ロールアップ列 — 表示のたびに評価が走る、またはインデックスが効かない
「念のため出しておく」列を削るだけで体感が変わるケースは珍しくありません。ビューは「全項目を見る場所」ではなく「目的のレコードに辿り着く場所」と割り切り、詳細はフォームで見せる設計にします。
デフォルトフィルターを必ず入れる
条件なしで全件を返すビューは、データ量に比例して確実に劣化します。「自分が担当」「アクティブのみ」「直近30日」のように、初期表示の範囲を絞る条件を必ず入れます。特にアプリのホームに表示されるデフォルトビューは、アプリ起動のたびに実行されるので最優先で見直します。
なお「担当者で絞る」設計をするには、そもそも担当者がレコード上で管理されている必要があります。所有者(Owner)をそのまま担当者として使う設計の問題点はDataverse の所有者を個人にするなに書きました。
ソートはインデックスの効く列で
関連テーブル経由のソート(link-entity + order)と、計算列・ロールアップ列でのソートは重くなります。並び順は自テーブルの単純な列(作成日時、伝票番号など)に寄せます。
閲覧用と分析用を分ける
「日常的に開く一覧」と「月次で全件を眺める一覧」を1つのビューに同居させない。前者は軽く絞り込んだビュー、後者は列が多くても割り切った別ビュー(またはExcelエクスポートやPower BI)に分離します。
ステップ4: フォームの改善パターン
フォームが遅い場合に見る場所です。
- 埋め込みサブグリッドの数 — フォーム上のサブグリッドは、それぞれが独立したクエリを発行します。1画面に何個も並べれば、その分だけ初期表示は遅くなります
- タイムラインコントロール — 活動・メモの取得は意外と重い部品です。使っていないなら外します
- タブの構成 — 既定で表示されないタブのコンテンツは遅延読み込みされます。「すべてを1タブ目に詰める」構成は、それだけで初期表示を重くします
- フォーム起動時のJavaScript — OnLoadで同期的にWeb APIを呼んでいるスクリプトは定番のボトルネックです。Monitorで実行時間が見えます
それでも足りないときは、設計の話
ここまでの改善で「日常操作の体感」はかなり戻せます。ただし、こういう要件が残っている場合は話が別です。
全レコードを、いろんな条件で、縦横無尽に絞り込んで検索したい
これはビューのチューニングで解決する問題ではなく、標準のビューに背負わせる仕事ではない、という設計判断の問題です。列を足してヘッダーフィルターで凌ぐ方式は、FetchXMLを重くし、最終的にビュー自体を開かなくする負け筋です。検索が業務の中心にあるなら、PCFコントロールや外部Webアプリで検索画面を別に作るべきです。この判断基準はDataverseの検索が微妙すぎる件で詳しく書きました。
そしてもう1つ。改善後は本番相当のデータ量でテストする運用を必ず残してください。開発環境に運用想定の件数を流し込んで開いてみる。これをリリース前の標準手順にするだけで、「後から重くなる」問題の大半は事前に捕まえられます。
まとめ
- モデル駆動型アプリの「重い」は遅効性。開発時に気づけないのが普通です
- 切り分け(どの画面・どの操作)→ Monitor(数字で特定)→ ビュー/フォーム定義の見直し、の順で潰します
- ビューは列を絞る・デフォルトフィルターを入れる・ソート列を選ぶ・用途で分ける
- フォームはサブグリッド・タイムライン・タブ構成・OnLoadスクリプトを見る
- 「全件を縦横無尽に検索したい」はビューの仕事ではなく、検索画面を別に設計する
「重い」の相談は、原因特定さえできれば多くの場合は設計の見直しで解決します。現状の環境を見てほしいという方は、無料の診断で現状整理と改善提案をお渡ししていますので、お気軽にどうぞ。