
OnStartとOnVisibleは何が違うのか
Power AppsのOnStartとOnVisibleは、どちらに初期化処理を書くべきか迷う人が多いプロパティです。結論から言うと、ほとんどのケースでOnVisibleに書くほうが正解です。
OnStartはアプリ起動時に一度だけ実行されます。OnVisibleは画面が表示されるたびに実行されます。この違いを理解していないと、一覧を更新したはずなのに古いデータが表示され続けるという問題が起きます。実際に私も最初のころはOnStartに全部書いてしまい、画面遷移後にデータが更新されないというバグに何度もはまりました。

OnStartの特徴と使い所
OnStartはAppオブジェクトのプロパティで、アプリが起動したとき(または開発中にCtrl+Rでアプリを再実行したとき)に一度だけ実行されます。
OnStartに書くべき処理
OnStartに向いているのは、アプリ全体を通して一度だけ取得すればよい情報の初期化です。
- ログインユーザー情報の取得(User()関数など)
- アプリ全体で使うグローバル変数の初期値設定
- 環境によって変わる設定値の読み込み
例えば、ログインユーザーのメールアドレスをグローバル変数に格納しておくなら、OnStartに書くのが自然です。
Set(gblCurrentUser, User())
これをOnVisibleに書くと、画面を遷移するたびに毎回User()を呼び出すことになります。軽い処理なら問題ありませんが、SharePointリストからユーザー情報を引っ張るような処理は毎回実行したくないはずです。
OnStartの注意点:パフォーマンスへの影響
OnStartに重い処理(大量データの取得や複数のコレクション初期化など)を詰め込むと、アプリの起動が遅くなります。体感として、OnStartが3秒以上かかるとユーザーから苦情が来ます。重い処理はOnVisibleで遅延ロードするか、Named Formulasへの移行を検討しましょう。

OnVisibleの特徴と使い所
OnVisibleは各画面(スクリーン)のプロパティです。その画面が表示されるたびに実行されます。Navigate関数で画面遷移してくるたびに動くと考えてください。
OnVisibleに書くべき処理
OnVisibleに向いているのは、画面を開くたびに最新データを取得したい処理です。
- ギャラリー用コレクションの更新
- 画面に表示するデータのフィルタリング
- 画面ローカルの変数の初期化
例えば、申請一覧画面を開くたびに最新の申請データを取得するなら、こうなります。
ClearCollect(colRequests, Filter(申請リスト, 担当者 = gblCurrentUser.Email))
OnVisibleにこれを書いておけば、他の画面から戻ってきたときも常に最新のデータが表示されます。OnStartに書いてしまうと、アプリ起動後に他の人が申請データを追加しても、自分の画面には反映されません。
コンテキスト変数の初期化はOnVisibleで
その画面だけで使うコンテキスト変数(UpdateContext)の初期化もOnVisibleに書きます。コンテキスト変数はその画面のスコープでしか使えないので、OnStartから操作することはできません。
UpdateContext({locIsLoading: false, locSelectedId: 0})
変数の使い分けについては別記事で詳しく解説しています。
→ Power Appsのグローバル変数とコンテキスト変数——違いと使い分けを図解
判断基準をまとめると
どちらに書くか迷ったときの判断基準はシンプルです。
| 判断基準 | OnStart | OnVisible |
|---|---|---|
| 実行タイミング | アプリ起動時に1回だけ | 画面表示のたびに毎回 |
| スコープ | アプリ全体 | その画面 |
| 変数種別 | グローバル変数(Set) | コンテキスト変数(UpdateContext)・コレクション |
| データ取得 | 一度だけ取れば十分なもの | 最新データが必要なもの |
私がアプリを設計するとき、OnStartはできるだけ軽くしておくのを心がけています。グローバル変数の初期値設定程度にとどめて、データ取得はすべてOnVisibleに回す、という方針にしてからアプリの起動が体感で早くなりました。

Concurrent関数で並列実行する
OnVisibleに複数のコレクション取得処理を書くと、上から順番に実行されるため時間がかかります。関係のない処理を並列で実行したいときはConcurrent関数が使えます。
Concurrent(
ClearCollect(colRequests, 申請リスト),
ClearCollect(colMembers, 社員マスタ),
Set(locTitle, "申請一覧")
)
3つの処理が同時に走るので、順番に書くより速くなります。ただし処理が互いに依存している(AのコレクションをBで使うなど)場合は並列にできないので注意が必要です。
まとめ
OnStartはアプリ起動時に一度だけ、OnVisibleは画面表示のたびに実行されます。ほとんどの初期化処理はOnVisibleで対応できますし、そのほうがデータの鮮度も保てます。OnStartはグローバルな設定値の初期化など、本当に一度だけでいいものに絞るのが正解です。
この使い分けを意識するだけで、データが更新されないバグはかなり減ります。アプリ開発の地道な基礎ですが、ここを押さえておくと後々の開発がずっと楽になります。
