Power Appsが重い・遅いときの改善方法まとめ|OnStart最適化・名前付き計算式・委任の3ステップ

Power Appsが重い・起動が遅いと言われたとき、原因はほぼ3つに絞られます。OnStartへの処理詰め込み、変わらないデータの毎回取得、委任の警告放置。この3つを順番に改善するだけで、アプリの起動体感は大きく変わります。

原因1:OnStartへの処理詰め込みすぎ

OnStartプロパティは、アプリが起動する前にすべての処理をブロッキング実行します。つまり、OnStartに100個の処理があれば、ホーム画面が表示されるまでその100個が全部終わるのを待つことになります。ClearCollect や Set で10個、20個の変数を定義していれば、その分だけ起動が遅くなります。

SharePointリストのキャッシュやユーザー情報の取得など、「とりあえずOnStartに書いておこう」という習慣がある方は多いと思います。私もそうでした。ただ、そのアプリが重いと言われたとき、真っ先に疑うべき場所がまさにそのOnStartです。

典型的なNG例

よくあるパターンを一つ挙げます。

ClearCollect(colDepartments, Departments)

こうしてSharePointリストをコレクションにキャッシュしているケースです。部署リストは起動中に変わらないので、OnStartでキャッシュするのは一見合理的に見えます。ところが、このコレクションをホーム画面で使わない場合でも、アプリが起動するたびにこの処理が走ります。ホーム画面に関係ないデータを取りに行くせいで、表示が遅くなっているわけです。

OnStartを残すか、名前付き計算式に移すかの判断基準

名前付き計算式(App.Formulas)は、OnStartの代替として使えるケースがあります。最大の違いは実行タイミングです。OnStartがアプリ起動時に全処理をまとめて実行するのに対して、名前付き計算式はその値が実際に必要になった瞬間に初めて計算されます。

OnStartに残すべきか、名前付き計算式に移すべきかは、次の1つの問いで判断できます。

その値は、アプリが起動した時点で確定している必要があるか?

値の種類判断理由
変わらないリストのキャッシュ名前付き計算式へ移行起動時に計算する必要がない
ユーザー情報(User関数)名前付き計算式へ移行変更不要・必要な画面で計算すればよい
テーマカラーの定数名前付き計算式へ移行変更不要・一元管理できる
深リンク処理(URLパラメーターで遷移先を決める)OnStartのまま起動時点で確定している必要がある
後から変更する可能性がある変数OnStartのまま名前付き計算式は変更不可(immutable)

移行手順:ClearCollect → 名前付き計算式

先ほどのClearCollectの例を名前付き計算式に移す手順を示します。

まずOnStartから次のコードを切り取ります。

ClearCollect(colDepartments, Departments)

次にアプリを選択した状態(App)で、上部メニューからFormulaプロパティ(日本語UIでは「計算式」)を開き、次のように書きます。

nfDepartments = Departments;

末尾のセミコロンが必須なので忘れずに。ClearCollectとは構文が違い、データソース名をそのまま右辺に書きます。あとはアプリ内でcolDepartmentsを使っていた場所をnfDepartmentsに書き換えるだけです。ギャラリーのItemsプロパティに nfDepartments と指定すれば、その画面が表示されたタイミングで初めてデータを取りに行きます。ホーム画面では計算が走らないため、起動が速くなります。

移行後に気をつけること

名前付き計算式はimmutable(変更不可)です。OnStartで Set(varUser, User()) と書いていた場合、後からボタンで Set(varUser, Blank()) と上書きできましたが、名前付き計算式では後から変更できません。書き換えが必要な値には引き続き変数を使います。

また、名前付き計算式はPower Appsの変数一覧パネルに表示されません。変数(Set/ClearCollect)と区別するために、nf というプレフィックスをつける命名ルールを採用することをおすすめします。nfUser、nfDepartments のようにしておくと、数式バーで見たときに名前付き計算式だとすぐわかります。

Concurrent関数との違い

OnStartを速くする方法として、Concurrent関数で複数の処理を並列実行するテクニックがあります。ただし、Concurrent内では処理同士がお互いを参照できないという制限があります。同じConcurrent内でnfExecutivesを先に計算してからnfExecutiveCountを計算するといった依存関係は書けません。

名前付き計算式にはその制限がありません。

nfExecutives = Filter(Employees, Department = "Executives");
nfExecutiveCount = CountRows(nfExecutives);

このようにnfExecutivesを参照するnfExecutiveCountが書けます。Power Appsが依存関係を自動で解決してくれるからです。ただし相互参照(AがBを参照し、BがAを参照する)はループになるため不可です。

名前付き計算式の構文や型別の書き方については 名前付き計算式(App.Formulas)とは名前付き計算式の書き方チートシート で詳しく解説しています。

原因2:変わらないデータを毎回取得している

都道府県リストや業種分類といった、アプリ起動後に変わらないデータを、毎回 Filter や Lookup で取得していないでしょうか。その都度データソースに問い合わせされるため、ネットワーク遅延やサーバー負荷に左右されます。

名前付き計算式でキャッシュする考え方が有効です。

nfDepartments = Departments;
nfStatusChoices = Table({Value:"申請中"},{Value:"承認済み"},{Value:"却下"});

遅延評価のため、参照されない計算式は計算されず、無駄な処理が削減されます。複数の画面で同じリストを使う場合は特に効果的で、1箇所の定義で全画面に反映されます。

原因3:委任の警告を無視している

Power Appsで赤い波線とともに表示される委任の警告を見かけたことがあります。これは、データ件数が上限(通常500件)に達するとフィルタリング結果が不完全になるという警告です。

Filter 関数を Dataverse や SharePoint に委任できる書き方に変更することで、警告を解消できます。例えば、Filter(Employees, Department = "Sales") と書く場合、Department列がインデックス化されていれば、委任が可能になります。委任可能な関数や演算子は限定されているため、詳細は 委任の警告の意味と対処法 を参照してください。

まとめ:3ステップで起動を速くする

起動速度の改善は、小さな最適化の積み重ねです。OnStart の処理を名前付き計算式に移す、変わらないデータをキャッシュする、委任の警告に対応する。この順番で見直すと、アプリの応答性は大きく向上します。

まず自分のアプリの OnStart を開き、ClearCollect や Set の数を確認するところから始めてみてください。移行候補が見つかれば、体感速度の改善はすぐそこです。

関連記事:名前付き計算式(App.Formulas)とは / 名前付き計算式の書き方チートシート / Power Apps Tips / Power Apps開発全体マップ

Xでフォローしよう