Power AppsのOnStartとOnVisible。どちらに書くべき?使い分けの鉄則

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のグローバル変数とコンテキスト変数——違いと使い分けを図解

判断基準をまとめると

どちらに書くか迷ったときの判断基準はシンプルです。

判断基準OnStartOnVisible
実行タイミングアプリ起動時に1回だけ画面表示のたびに毎回
スコープアプリ全体その画面
変数種別グローバル変数(Set)コンテキスト変数(UpdateContext)・コレクション
データ取得一度だけ取れば十分なもの最新データが必要なもの

私がアプリを設計するとき、OnStartはできるだけ軽くしておくのを心がけています。グローバル変数の初期値設定程度にとどめて、データ取得はすべてOnVisibleに回す、という方針にしてからアプリの起動が体感で早くなりました。

Concurrent関数で並列実行する

OnVisibleに複数のコレクション取得処理を書くと、上から順番に実行されるため時間がかかります。関係のない処理を並列で実行したいときはConcurrent関数が使えます。

Concurrent(
    ClearCollect(colRequests, 申請リスト),
    ClearCollect(colMembers, 社員マスタ),
    Set(locTitle, "申請一覧")
)

3つの処理が同時に走るので、順番に書くより速くなります。ただし処理が互いに依存している(AのコレクションをBで使うなど)場合は並列にできないので注意が必要です。

まとめ

OnStartはアプリ起動時に一度だけ、OnVisibleは画面表示のたびに実行されます。ほとんどの初期化処理はOnVisibleで対応できますし、そのほうがデータの鮮度も保てます。OnStartはグローバルな設定値の初期化など、本当に一度だけでいいものに絞るのが正解です。

この使い分けを意識するだけで、データが更新されないバグはかなり減ります。アプリ開発の地道な基礎ですが、ここを押さえておくと後々の開発がずっと楽になります。

Xでフォローしよう