【Power Apps】App.OnStartとApp.Formulasの使い分け

ビリビリ☆Power Apps 同好会 登壇大会＃1への登壇ネタとして、App.OnStartとApp.Formulasの使い分けについて考えてみました。

登壇資料：[App.OnStartとApp.Formulasの使い分け (ビリビリ☆Power Apps 同好会 登壇大会＃1)](https://www.docswell.com/s/pplog/Z24XLV-onstartvsformulasbiribiri)


:::note info
細かい話なので読み飛ばしてOK：
便宜上App.OnStartはここで定義するグローバル変数、App.FormulasはGA済みの引数なしの名前付き計算式として説明しています。
厳密に書くと以下ですが、わかりやすさ重視でプロパティ名で説明します。
App：オブジェクト名(プロパティをもつ要素)
OnStart, Formulas：プロパティ名(コードを書く場所)
グローバル変数、名前付き計算式：変数、関数(コード)
:::

[Power Apps の App オブジェクト - Power Platform | Microsoft Learn](https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/object-app)

## 違いまとめ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/092361c1-3b07-1e7c-86af-5f7d73c284ec.png)

App.OnStartとApp.Formulasの違いは大きく以下の3点です。
* 値が動的であるか、静的であるか
* 値の更新タイミング
* コードを書く場所や記述方法

これらを踏まえて、個人的には以下の使い分けをすべきと考えます。
App.OnStart：特定の時点での値を呼び出す回数が多い場合
App.Formulas：最新の値を呼び出す回数が多い場合

## App.OnStartとApp.Formulasの違い
### 値が動的であるか、静的であるか
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/c937d402-3eb8-d023-4a5b-6f61346556b1.png)

最も大きな違いは、値が動的(=関数)であるか、静的(=変数)であるかです。
この差が大きすぎるため、App.FormulasはApp.OnStartの完全な代替手段にはなりません。

### 値の更新タイミング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/9e785869-53cf-07ea-636b-13a3866ca728.png)

動的か静的かという点に大きくかかわってきますが、値の更新タイミングが全く違います。

またOnVisibleはOnStartの処理完了を待たないため、OnStartに長い処理を書く際はOnVisibleにOnStartで定義している変数やコレクションを利用していないか注意が必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/c4980a71-0e1e-0dbd-a5f5-18125abed210.png)

### コードを書く場所や記述方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/4572d67c-f20f-1b0b-692e-2d797e571b5a.png)

App.OnStartのグローバル変数はAppオブジェクトの動作プロパティであるOnStartで定義します。
グローバル変数は他の動作プロパティで更新ができます。

https://powerplatformnikki.com/componentsproperties

一方App.FormulasはAppオブジェクトのプロパティの一つで、他のプロパティとは書き方がかなり異なっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/2e91324c-ed62-4e0d-3a0c-98b05014bbf3.png)

https://powerplatformnikki.com/udfcomponent

名前付き計算式もグローバル変数も左側の変数タブからプレビューで一覧表示できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/4dafd2de-b9bc-2fab-d449-1af5983e378a.png)

## 使用例

### App.OnStart

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/bdb665d7-3199-df77-3c27-f9465349d5f6.png)
最も使うのは、アプリの起動時にユーザーの情報をグローバル変数に格納する使い方です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/d70860c0-58a3-20f5-07a8-9815b847ba41.png)

またマスタのようなデータをコレクションに格納して利用することもありますが、2000行を超えるデータは格納できないのと、数式が複雑だと起動に時間がかかってしまう場合があることに注意です。

### App.Formulas
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/7ba4c632-5306-2bc0-112a-40f19afde317.png)

https://powerplatformnikki.com/counthitsformulas

## パフォーマンス比較してみた

App.OnStartとApp.Formulasで同様の処理をしたときのパフォーマンスをデータソースごとに比較してみました。
ロード画面を作成してOnVisibleでOnStartと同じ動作をさせるという代替案もあるので、併せて計測しました。

### 結果

<figure class="wp-block-table"><table><tbody><tr><td rowspan="2"></td><td colspan="2"><strong>参照なし</strong></td><td colspan="2"><strong>Excel</strong></td><td colspan="2"><strong>SharePoint</strong></td><td colspan="2"><strong>Dataverse</strong></td></tr><tr><td>起動時間</td><td>処理時間</td><td>起動時間</td><td>処理時間</td><td>起動時間</td><td>処理時間</td><td>起動時間</td><td>処理時間</td></tr><tr><td>OnStart</td><td>0.001</td><td>0.008</td><td>3.759</td><td>0.022</td><td>3.996</td><td>0.011</td><td>0.741</td><td>0.025</td></tr><tr><td>OnVisible</td><td>0.339</td><td>0.011</td><td>4.984</td><td>0.014</td><td>5.420</td><td>0.013</td><td>2.141</td><td>0.012</td></tr><tr><td>Formulas</td><td>0.000</td><td>0.022</td><td>0.000</td><td>2.250</td><td>0.000</td><td>2.707</td><td>0.001</td><td>1.259</td></tr></tbody></table><figcaption class="wp-element-caption">データソースごとの各プロパティで値を定義した場合の起動時間と処理時間</figcaption></figure>

この結果から以下のことがわかります。

* OnStartやOnVisibleは起動に時間がかかる一方、処理時間はほぼかかっていない
* Formulasは呼び出すたびに処理時間がかかってしまうため、定数の呼び出しには向いていない
* Formulasは一度目の呼び出しに時間がかかり、その後はOnStart、OnVisibleでの処理と同様の時間しかかからない​

3つ目は時間をあけると同じくらいの処理時間がかかったので、一定の時間は処理結果が保持されるようです。(この動作は通常の数式の出力でも同様です)

### 計測方法

OnStartとOnVisibleはそれぞれのプロパティでマスタ用のコレクションに、Formulasはユーザー定義関数でマスタのテーブルを定義しています。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/bb00df14-46a6-db57-704a-ce4cb3816a29.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/ecd335f6-2ae3-cc21-654a-5acf1b19c52e.png)

このマスタの一行目と各行の値をかける処理を行うことで処理時間を計測しています。

ちなみに「参照なし」はデータソースの参照ではなくTable関数で定義した値を使用しています。
ChatGPTでテストデータを作ると便利です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/317d0027-19b4-e8fb-c1d4-84504a1924bb.png)

## 元記事

https://powerplatformnikki.com/formulasvsonstart/