[Power Apps]キャンバスアプリ、大規模開発における勘所①パフォーマンス編

# ご挨拶 #
はじめまして。susumu tanakaです。
Power Platform界隈には長らくいるのですが、この記事が初アドベンティスト投稿となります。

いま、とある会社に所属して、Slerとして、
お客様のPower Platfromを活用した大規模ワークフローシステムを構築しているものです。

<!--
コメントかくしておく
■参考URL（Markdown記法 チートシート）
https://qiita.com/Qiita/items/c686397e4a0f4f11683d
-->

# なんの話するの？ そう、パフォーマンスの話#
<!--
元々はMSにて、昨年レイオフされて、今の会社にいますが、
奇跡的に、Powerの大規模開発の案件に携わっています。
-->

そんななかで、今プロジェクトでホットな話題が、
Power apps（＆Power Automateクラウドフロー）のパフォーマンスになります。
※もちろん、Power Pagesの話もあるのですが...

基本、Power Appsだけでは構築してなく、ロジック部分はPower Automateクラウドフローの部分もあるのですが、
この記事では、Power Appsのパフォーマンスの部分に特化して、
僕なりの解釈を踏まえてお話しさせていただこうかなと思います。
※Power Automateのクラウドフローのパフォーマンスについては、12/23のアドベンティストの方で解説します。

<!--
# 3階層の話（プレゼンテーション層・アプリケーション層・データ層）
:::note info
この章は、読み飛ばしてもOKです。
:::


まず、Power Platform というよりかは、世間一般的な
システムを構築していくうえで重要とされる三階層アーキテクチャーの話します。

なぜ、３回層アーキテクチャーの話をするかというと、
その上で、打ち手（対策）の話をしたほうが、すーっと、入ってくるような気がしているのと、
まとめやすいかなと思ったからです。


まずは、以下３つのURLの記事を読むと、3階層アーキテクチャーの話が、
雰囲気伝わってくるかなと思いますので、斜め読みしてください。

□3層クライアントと2層クライアント、どっちが良いの？
https://itmanabi.com/3-layer-2-layer/

□Web3層構造とは？Webシステムの基本とメリット・デメリットを解説！
https://ryonotes.com/web-3-layer-architecture/

□3層アーキテクチャーとは
https://www.ibm.com/jp-ja/topics/three-tier-architecture

## Power Platformを3階層アーキに当てはめてみる

所説ある気がするのですが、僕の解釈としては...
アプリケーション層にPower Automateのクラウドフローがあるのですが、
微妙じゃない？という突っ込みはありそうですが、
再利用可能なロジックとしての処理ということであれば、Power AutomateのクラウドフローでOKな気がします。
また、プレゼンテーション層の概念的なものは、
上記の記事を参考にすると、CSS、JavaScriptで、クライアントサイドで動くものは、プレゼンテーション層ということでPower Appsでいい気がしますが、
Power FXの立て付けとして、ここでいいか？という気もしますが、
製品カットで見た場合は、こう整理したほうがわかりよいような気がします。

重要なのは、それぞれの打ち手に何があるか？ということなので、一旦この解釈で進めさせてもらいます。

|3階層 | Power Platform製品 | コメント |
|:---|:--|:--|
|プレゼンテーション層|Power Apps|アプリ、画面、Power FX？など|
|アプリケーション層|・Power FX<br>・Power Automate <br> (クラウドフロー)<BR>・コネクター|Power Automateをここにおくとわかりづらいのですが、ロジックと置き換えてください。<BR>プレゼンテーション層から直接、データ層へのアクセスはできない？観点から、アプリケーション層にコネクターもいれてます。|
|データ層|Dataverse|裏側は、SQL-Serve,BLOB,COSMODBなど、Azure製品ががっつり使われていますが、パフォーマンス観点でやれることは、ほとんどない印象|

■Power FXとは。。
https://learn.microsoft.com/ja-jp/power-platform/power-fx/overview
わかりづらいかはこちら↓Qiita記事

□【Power Automate Desktop】Power Fxとは何ぞや？
https://qiita.com/wannaget_idea/items/984dffdb4ca91ca624fa

□Microsoft Power Fx 概要
https://qiita.com/spumoni/items/397ef6d28ae2057ddb5d

-->

# Power Appsでのパフォーマンスについて 
で、ここからが本題で、大規模開発時における注意点として、
どんなプロジェクトの進め方（WF/アジャイル etc..）にかわらず、設計・実装はさけては通れない。
最初から大規模につくるな（小規模から始めよ）見たいな話もありますが、
お客様提案して、契約して大規模開発と進める場合の視点とは、
設計・実装でわけたほうが、手戻りも少ないと考えます。

それぞれ意識しなければならないことをまとめてみました。
※Learnにも記載があるのですが、
体系だっているようにみえて、体系だたれてないようにみえるので、僕なりの解釈も踏まえてます。


そのうえで、
①設計時に意識しなくてはいけないこと
と、
②処理記述時（実装・コーディング時）に意識しなくてはいけないこと
の2つに分けお話させてください。
<!--
<details><summary>(独り言)
</summary>

（3階層アーキテクチャーといい、また、設計・実装で2分割してはなるだと？
という突っ込みはさておき、開発工程としての設計時に注意するポイント、実装時だとやることが異なるので、僕の頭の整理としても分けた方がいいと解釈してますので、申し訳ないですが、そうさせてください。）
</details>
-->

## ①設計時に意識しなくてはいけない/注意ポイント
まずはサマリとして、以下、3つを上げさせていただきます。

**①-1 大規模の場合のアプリ分割**
　キャンバスアプリとしての制約として、
以下2つの制約があると解釈してますので、アプリ分割が大前提になります。
 
[(1)コントロールが多すぎると描画に時間がかかる](https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/performance-tips#%E3%83%87%E3%83%BC%E3%82%BF%E6%8E%A5%E7%B6%9A%E3%81%AE%E5%88%B6%E9%99%90)
        （１つのアプリに500個以上はおいてはならぬ）

 [(2)コネクターで接続するテーブル数が30以上あると時間がかかる](
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/performance-tips#%E3%83%87%E3%83%BC%E3%82%BF%E6%8E%A5%E7%B6%9A%E3%81%AE%E5%88%B6%E9%99%90)

  
　設計していくなかで、さらにアプリ分割しないといけない場合などでてきますので、このあたりは抑えておくのがいいかなと思います。
 
**①-2 ファイルの保存場所**
　Dataverseはストレージ高いので、Azure BLOB ストレージをファイルの格納先として活用とする方法の検討
　※ファイル添付要件が多いアプリの場合は必須要件かなと思います。
 
**①-3 Power FXで記述すべきか？ Power Automate クラウドフローでやるべきか？**
　もしかすると、設計時ではないかもしれないですが、共通処理などで確実にクラウドフローでやる場合は、設計時の検討の訴状にあがるかなと..
　ただ、この[記事](https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/fast-app-page-load?source=recommendations#consider-avoiding-calling-power-automate-to-populate-a-collection)にもあるとおり、クラウドフロー起動には、約0.6秒かかるらしいので、すべからく、クラウドフローでやるのは得策でもない気がします。
 ただ、共通処理などの場合は、クラウドフローを活用したほうが効果的なので、このあたりのバランスが難しい。

 このあたりの記事を読むと理解が進みますので、参考してください。
 [ビジネス ロジックを構築する](https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/app-business-logic)
 　やればやるほどわかるのですが、クラウドフローの非同期・同期をどっちでやるべきか？みたいな問題はあると思います。

あと、[2000件？・委任](https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/delegation-overview#changing-the-limit)などの問題もあるので、
データを大量に表示しないといけない場合、テーブルにデータが大量にたまってしまう場合は、
配慮が必要になると思います。
（今のプロジェクトだと、同期・非同期のハイブリッドの感じやるケース出てきました。汗）

## ②処理記述時（実装・コーディング時）に意識しなくてはいけない/注意ポイント

これは、Power FXの記述の仕方であり、Learn上でも大量にあるためリンクで
１つ１つ解説したいところですが、長くなりすぎるため、僕が重要と思うところだけ、
ピックアップしたいと思います

**②-1 起動時の並列化**
    起動時の処理として、onStartイベントに処理記述すると思いますが、
    無邪気にコード書くと、直列に、処理が実行されることになるので、
    Concurrent関数で並列処理を心がける。
    
[OnStart プロパティを最適化する](https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/performance-tips#onstart-%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%82%92%E6%9C%80%E9%81%A9%E5%8C%96%E3%81%99%E3%82%8B)
    
**②-2 ForAllは極力避ける**
 大量データがはいっているテーブルをForALLするととんでもないことになるので注意しましょう。

**②-3 ビューの活用**
　委任問題とかありますが、Dataverseのテーブルの場合は、ビューを作成して、サーバ側で条件絞りこんだ状態で、受け取った方がデータ量的には有利なので積極的に活用しましょう。



あとは、ちょっと、複数の記事にあるので、カテゴライズしておきます。

# 参考URL #

参考URLだけでも少なくともこのくらいはあります。
それぞれ重要なことを言っているのだけれども、読まずに進めるとハマるポイントが満載です。
一読して理解できなくとも、困ったときのそんな話あったなぁ位でいると、
パフォーマンス問題で行き詰った時に、役に立つ気がします。

■大規模で複雑なキャンバス アプリを構築する
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/working-with-large-apps

■キャンバス アプリのパフォーマンス低下の一般的な原因
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/slow-performance-sources

■ヒントとベスト プラクティスを使用して、キャンバス アプリのパフォーマンスを向上させる
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/performance-tips

■一般的なキャンバス アプリのパフォーマンスの問題と解決策
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/common-performance-issue-resolutions

■キャンバス アプリのパフォーマンス低下の一般的な原因
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/common-performance-issue-resolutions#onstart-event-needs-tuning

■アプリ分割
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/working-with-large-apps#partition-the-app

■ビュー活用
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/common-performance-issue-resolutions#performance-considerations-for-using-dataverse-as-the-data-source

■ピーク パフォーマンスのためにアプリまたはページの負荷を最適化する
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/fast-app-page-load?source=recommendations


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322851/9b30f836-4a10-6bf0-110a-31e8e622c310.png)


■App.formula で数式を分割する
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/efficient-calculations#split-up-formulas-with-appformula


■Forallの対応
※大量案件
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/efficient-calculations#place-forall-appropriately

■オンライン データソースを使用したデータ コール フロー
データコールの内容を理解する
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/execution-phases-data-flow#data-call-flow-with-online-data-sources


最適化されたクエリ データ パターン
■StartsWith または Filter の使用
inだとテーブルスキャンしちゃうので。。
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/optimized-query-data-patterns#use-startswith-or-filter

■サーバー側ビューを使用する
ビューを推奨
https://learn.microsoft.com/ja-jp/power-apps/maker/canvas-apps/optimized-query-data-patterns#use-server-side-views

□サジェッション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322851/c3cce84b-2b13-7d6c-1570-f5ffae70716b.png)

ここは重要そうな気もする

この目標を達成するには、次の質問と提案を考慮してください。

>顧客にとって、ギャラリーまたはデータ グリッドでデータ値を確認することはどの程度重要ですか? 最初にレコードを選択してから、フォームにデータを表示することは許容されますか?
データを正しい形式で表示するために必要な事前作業をビューで実行できますか?
「StartsWith」が機能する「IN」演算子を使用していますか?
データはどの程度最新である必要がありますか? 既定で単一のテーブルに対してクエリを実行するために使用できるデータ複製戦略はありますか?

如何だったでしょうか？
最後駆け足になっちゃいましたが、、、

パフォーマンスは、ほんと最後の最後でハマるケースが大半化と思いますので、
このあたりを意識した開発を進めると気持ち多少楽になるのではないかと思います。
※あと、非機能要件で、厳しすぎるパフォーマンス要件は問題のタネなので、めちゃ注意してください。

では。Power Platform 生活をエンジョイしてください。
今後ともよろしくお願いします！


# おまけ #
これは海外の記事ですが、大量なデータを扱う場合にかなり有効なPower FXの書き方の参考例です。僕のプロジェクトでも活用して、数分かかっていた処理時間が、数秒で対応できたという両記事です。

https://www.iammancat.dev/2022/08/sequential-concurrent-forall-in-power-apps/

# あとがき #
もう少し、余裕を持って、まとめたかったのですが、これが現状では限界。
自分自身の考えての整理も踏まえて、どこかで記事をUpadateすると思いますm(__)m
来年のアドベンティストかなで、まとめかな。。