Power Apps のキャンバスアプリでパフォーマンスを最適化するには(概要編)
Power Apps で作成したアプリが遅いな、起動に時間がかかるな、パフォーマンスが悪いな、と思われたことはありませんか?この回では概要レベルで、どのように最適化していくか、気をつける点についてご紹介していきます。
パフォーマンス最適化シリーズ:
- 概要編(本投稿)
- SharePoint 編
- SQLサーバ 編(公開予定)
- Microsoft Dataverse 編(公開予定)
- Excel 編(公開予定)
- その他編(公開予定)
Power Apps のキャンバスアプリを作る際、SharePointのカスタムリストやMicrosoft Dataverse、オンプレミス上のSQLサーバ、Azure SQL、ExcelやOracleなどと様々なデータへ接続させることができます。キャンバスアプリを作成する際に利用するデータによって、パフォーマンスを最適化させる様々な方法があります。この投稿では多くの作成者が直面する問題点と、その改善方法について深いレベルで解説します。この投稿はIT技術者を読者として想定しており、内容が難しい場合はIT部門へ共有いただくか、IT支援企業に手伝ってもらうことをおすすめします。
Power Apps のキャンバスアプリから実行されるデータ処理はODataプロトコルを経由して各データ元へアクセスします。ODataはデータ元のバックエンドのレイヤーへリクエストを出し、その結果をクライアントへ返すか、データソースへデータをコミットします。
Power Apps で実際にデータはどのように処理されるのか?
キャンバスアプリを作成する際にODataがどのようにサーバサイドで処理されているのかを理解することで、アプリのパフォーマンスを最適化させることができます。
以下の図をご覧ください。ここでは、キャンバスアプリからデータの取得をリクエストする際(左側)に、各サーバ側の処理としてどのように行われ、その結果をクライアントに返してくる処理(右側)を可視化したものです。Microsoft Dataverse を除き、どのコネクタもこのステップを踏んで様々なデータへアクセスしています。Microsoft Dataverse の処理はこの後解説します。
各レイヤーではリクエストを処理するためのオーバーヘッドが微量でも発生します。ほとんどのアプリではここで主に2つ気になるオーバーヘッドが発生します。
- データが実際のバックエンドシステムで処理されている際
- クライアントがリクエストを送信する際またはヒープメモリ上で受信したデータを加工するために処理を行い、関連するJavaScript上の処理を実行し、画面上で表示させるための準備を行っている際
もし作成されているキャンバスアプリがオンプレミスサーバ上にあるSQLサーバなどへ接続する場合、更にもう一つのレイヤーとしてオンプレミスデータゲートウェイがあります。オンプレミスデータゲートウェイはオンプレミス上のサーバにアクセスするためには必須のサービスです。ODataリクエストをSQL DML(データマニピュレーション言語)へと変換する役割を担います。以下の図はオンプレミスデータゲートウェイがどういう形でデータリクエストを処理するかを加えたものです。
もしアプリがオンプレミスのデータソースを利用する場合、データゲートウェイの物理的な位置や、ゲートウェイとして使用しているマシンスペックもデータ処理時のパフォーマンスに影響を与えます。
Microsoft Dataverse コネクタを利用してMicrosoft Dataverse 環境へアクセスする場合、データリクエストは上記のコネクタとは違い、APIマネージメントを経由せずに直接環境のインスタンスへアクセスします。そのため、データ取得までのパフォーマンスが他のデータソースよりも高くなります。新しいキャンバスアプリを作成する際に、既定で Microsoft Dataverse コネクタを用いた接続が作成されてます。
このようにデータの取得方法がどのように行われているかを概要レベルで理解したところで、次にパフォーマンスに関して更に詳細についてお話しましょう。パフォーマンスのオーバーヘッドはクライアント側、APIM、コネクタ、オンプレミスデータゲートウェイ、または接続先のデータソースのどのレイヤーでも発生する可能性があります。
ほとんどの利用者の方で、Power Apps が遅いと感じられた主な原因は以下の5点に関連していることが多い傾向にあります:
- アプリの実装方法
- 接続先のシステムの問題によるボトルネック
- ブラウザの種類などの利用方法
- オンプレミスデータゲートウェイとPower Apps 環境の物理的な位置
- 短期間で大量のデータをバックエンドシステムから取得しようとした場合によるスロットリング
アプリの実装方法
「アプリの実装方法」は多くのことを意味します。 以下のような実装をアプリ作成者が行った場合も影響します。例えば:
- OnStartで最初の瞬間に大量のデータをデータコレクションに取り込んだ場合
- アプリに長い式がある場合
- JOIN、Sort、AddColumn、GroupByなどのクライアントに負荷がかかる操作が実装されている場合
- 複数の画面内でデータを使用する場合
- アプリが画面で多くの不要なデータ呼び出しをトリガーし、各データ呼び出しが大きなデータレコードを返す場合
- 上記のような実装が行われていると、アプリのパフォーマンスが低下します。
このような問題を特定するには、 Power Apps Monitorを使用してアプリの動作を監視し、どのデータ呼び出しに時間がかかっているか、データ呼び出しの数によってアプリのシナリオがトリガーされるかを確認します。 もう1つの回避策は、クライアントとサーバーの間で負荷の分散を図ることです。 ワークロードをなるべくサーバーに委任することもお勧めします。 クライアントのメモリ消費の観点から、クライアントアプリを軽量にすることも重要です。
接続先のシステムの問題によるボトルネック
接続先のデータソースがボトルネックとなるシナリオはたくさんあります。 通常、データソース内のテーブルは、多くのトランザクション/非トランザクションクエリが異なるユーザーから同じテーブルまたはレコードに送信されると、データソースはホットスポットに陥ります。その他の場合として、データソースをホストしているバックエンドシステムがロースペックなシステムだった場合、バックエンドSQLインスタンスではブロッキングとデッドロックが発生してしまい、リソースの競合が発生し、OData呼び出しの速度が低下します。 さらに、オンプレミスのデータゲートウェイがあり、正常に動作していない場合、データゲートウェイからのボトルネックによってOData呼び出しが遅くなる可能性もあります。このような場合、バックエンドデータソースを調整する必要があります。
ブラウザの種類などの利用方法
公開するアプリは、さまざまなデバイス、さまざまなブラウザ、さまざまなネットワーク条件を持つさまざまな場所で多くのユーザーによって使用されます。 Power Appsクライアントを実行する際は、Microsoft EdgeやGoogle Chromeなどの最新のブラウザを使用することを強くお勧めします。 一部のユーザーがInternet Explorerなどのレガシーブラウザーを使用している場合、ユーザーエクスペリエンスに影響が及ぶ可能性があります。 また、作成したアプリは作成者が定期的に再発行することをお勧めします。 Power Appsプラットフォームは継続的に改善され、アップデートされるため、アプリを再発行すると、最新のプラットフォームでアプリが再生成されます。
オンプレミスデータゲートウェイとPower Apps 環境の物理的な位置
ユーザーはアプリにどこからでもアクセスできます。 ただし、最もエンドユーザーが多く存在する物理的地域の近くにデータソースを配置することをお勧めします。 アプリがオンプレミスのデータソースにアクセスする場合、オンプレミスのデータゲートウェイの場所は、ゲートウェイとデータソース間の余分なオーバーヘッドを最小限に抑えるために、データソースの近くに配置することを推奨します。
短期間で大量のデータをバックエンドシステムから取得しようとした場合によるスロットリング
ほとんどの場合、作成したアプリが短い期間内に意図的に大量のデータ呼び出しを行わない限り、スロットル制限は発生しませんが、発生した場合にはこちらとこちらの記事を一読されることをおすすめします。
たとえば、ユーザーごとの接続ごとの呼び出し回数は、1分間のスライドウィンドウで600回に制限されます。アプリが多くのデータ呼び出しを生成するように構築されている場合、呼び出しが抑制されるかどうかに関係なく、ユーザーは最高のエクスペリエンスを得られない可能性があります。そこで、Power Apps Monitorを使用してアプリをプロファイリングすると、この問題を回避できます。
上記ではいくつかの点に簡単に触れました。実際の世界では、アプリ作成者はPower Apps のコネクタを介して任意の数のデータソースを選択できます。多くの選択肢がありますが、アーキテクチャ、パフォーマンス、メンテナンス、拡張性など、多くの観点から適切なデータソースとコネクタを選択することが重要です。
SQL(オンプレミス)、Azure SQLオンライン、SharePoint、Microsoft Dataverse、Dynamics、Excelなどのデータソースごとに、潜在的なパフォーマンス問題になり得る可能性を確認しましょう。これらの情報は、ビジネスプランと成長を念頭に置いて、適切なデータソースを選択するのに役立ちます。
よくある共通のパフォーマンス問題
選択したデータソースに関係なく、共通して発生するパフォーマンスの問題点がいくつかあります。ここでは、いくつかよくある問題点について触れたいと思います。
OnStart での関数の多用
OnStart はアプリがロード中に実行されます。そのため、OnStartでたくさんのデータを取得してしまうと、アプリの読込時間が延びてしまいます。また、最初に表示させるスクリーンが、他のスクリーンに依存し様々な値や結果を取得するような仕組みになると、更に表示速度が低下します。
以下の問題が特によく発生しています:
- OnStart時にたくさんのデータ取得処理を実行してしまったことに、起動時間が非常に遅くなる。大規模な会社の場合、統合されたデータ元からデータ取得をした際にサーバ側がボトルネックとなり、リソースが枯渇してしまう場合もあります。
- N+1 クエリ問題がギャラリーで発生し、サーバ側へのリクエストが頻繁に発生しすぎる。
- データベースへのクエリがインデックスシークではなく、テーブルスキャンになっている。
- OnStartで複雑過ぎる関数を組み込んだことによる大きなレイテンシーの発生。多くのキャンバスアプリで見受けられます。アプリ作成者は起動時に必要なデータだけを取得することをおすすめします。
- 不必要に多くの列を取得する。すべての列を取得すると、その分データのダウンロードも増えます。ただし、処理の種類によっては取得するデータの件数は変わってきます。不必要にデータを取得すると、クライアント側のメモリを消費し、ネットワーク越しの遅延も発生します。可能な限り、必要な列のみを取得することをおすすめします。
- Internet Explorer をブラウザとして利用した場合。
- 環境の場所とユーザーの場所が異なる場合。
- apps.powerapps.com がファイアウォールで許可されていない。ネットワークプロクシを利用している場合は、プロクシ設定を行っていること。
推奨事項:
- キャッシュの仕組みを活用し、データ取得を最適化しましょう。最終的には複数の利用者によって、皆さんが作成したアプリは利用されます。つまり、その人数分、データの取得処理はサーバ側に送信され、スロットリング制限やボトルネックが発生する可能性があるわけです。
- SQLを利用する場合はビューオブジェクトを活用しN+1クエリの問題を解決するか、UIを変更し、問題が発生しないように対応します。
- 「IN」関数の代わりに「StartsWith」を使いましょう。SQLをデータソースとして利用した場合、「StartWith」ではSQLデータベース上、インデックスシークで処理されますが、「IN」関数を量すると、インデックススキャンまたはテーブルスキャンが発生します。
- OnStartイベントでの関数を最適化します。可能であればOnVisibleへいくつかの関数を移行されることを推奨します。そうすることで、アプリの起動は早まり、他の後続のステップはアプリ起動後に実行されます。
- Microsoft Dataverseを利用する場合は、詳細の設定から「明示的な列の選択」をオンにします。有効化することで、Microsoft Dataverseコネクタは自動的にどの列がアプリで利用されているかを認識し、該当する列のみを取得します。
- Internet Explorer を利用している場合はMicrosoft Edgeを利用することを推奨します。Internet Explorer を利用すると、JavaScriptのスクリプト実行時において、正しく動作しない場合があります。
- ユーザーに近い環境(日本の場合は、環境も日本を選択)することをおすすめします。Power Appsは既にコンテンツデリバリーネットワーク(CDN)を活用し、アプリの必要なデータを一番近いCDN拠点から取得できますが、データの要求についてはバックエンドシステムに依存します。もし、アプリが少量のデータのみを都度取得する場合には影響度は少ないですが、レイテンシー、スループット、帯域幅やパケットロスもパフォーマンスに影響を及ぼします。
- ネットワーク管理者と確認し、 *.PowerApps.com などがホワイトリストされていることを確認します。
次回は各データソース別固有の問題についての課題や推奨事項についてご紹介します。
Leave a Reply