Power Apps Component Framework を使用して作成されたコード コンポーネントのベスト プラクティスとガイダンス
コード コンポーネントの開発、展開、および保持には、以下の領域を含む知識が必要です。
- Power Apps Component Framework
- Microsoft Power Apps
- TypeScript および JavaScript
- HTML ブラウザのユーザー インターフェイスの開発
- Azure DevOps/GitHub
この記事では、コード コンポーネントを開発する専門家に向けて、確立されたベスト プラクティスとガイダンスを概説しています。 この記事では、これらのツールやヒントがもたらす使いやすさ、サポート性、パフォーマンスの向上をコード コンポーネントで活用できるように、それぞれの利点を説明することを目的としています。
Power Apps component framework
このセクションには、Power Apps Component Framework 体に関連するベスト プラクティスとガイダンスが含まれています。
開発ビルドを Dataverse にデプロイすることは避ける
コード コンポーネントは、生産または開発モード に組み込むことができます。 パフォーマンスに悪影響を及ぼし、サイズが原因でデプロイがブロックされる可能性があるため、開発ビルドを Dataverse にデプロイすることは避けます。 後でリリース ビルドをデプロイする予定がある場合でも、自動リリース パイプラインがないと、再デプロイを忘れがちです。 詳細: カスタム コントロールのデバッグ。
サポートされないフレームワーク メソッドを使用しない
これらには、ComponentFramework.Context
に存在する文書化されていない内部メソッドの使用も含まれます。 これらのメソッドは機能する場合もありますが、サポートされていないため、将来のバージョンでは機能しなくなる可能性があります。 ホスト アプリケーションの HTML ドキュメント オブジェクト モデル (DOM) にアクセスするコントロール スクリプトの使用はサポートされていません。 コード コンポーネントの境界外にあるホスト アプリケーションの DOM の部分は、予告なしに変更される場合があります。
init
メソッドを使用して、ネットワークに必要なリソースを要求する
ホスティング コンテキストがコード コンポーネントをロードすると、init メソッドが最初に呼び出されます。 updateView
メソッドまで待機する代わりに、このメソッドを使用してメタデータなどのネットワーク リソースを要求します。 リクエストが返される前に updateView
メソッドが呼び出されると、コード コンポーネントはこの状態を処理し、視覚的な読み込みインジケーターを表示する必要があります。
destroy
メソッド内でリソースをクリーンアップする
コード コンポーネントがブラウザーの DOM から削除されると、ホスティング コンテキストが destroy を呼び出します。 destroy
メソッドを使用して任意の WebSockets
をクローズし、コンテナー要素の外部に追加されたイベント ハンドラーを削除します。 React を使用している場合は、destroy
メソッドの内部の ReactDOM.unmountComponentAtNode
を使用します。 このようにリソースをクリーンアップすることは、指定したブラウザ セッション内でコード コンポーネントがロードおよびアンロードされることで発生するパフォーマンスの問題を防止することができます。
データセット プロパティを更新するための不要な呼び出しを回避する
コード コンポーネントのタイプがデータセットの場合、バインドされたデータセット プロパティが refresh
メソッドを公開することで、ホスティング コンテキストがデータをリロードします。 不必要にこのメソッドを呼び出すと、コード コンポーネントのパフォーマンスに悪影響を与えます。
notifyOutputChanged
の呼び出しを最小限に抑える
状況によっては、notifyOutputChanged
の各呼び出しに対する UI コントロールの更新 (キーを押下する作業やマウスを移動する作業など) が望ましくない場合があります。これにより、notifyOutputChanged
は必要以上に多くのイベントが親コンテキストに伝達します。 代わりに、コントロールがフォーカスを失ったとき、またはユーザーのタッチまたはマウス イベントが完了したときにイベントの使用を検討してください。
API の空き状況の確認
異なるホスト (モデル駆動型アプリ、キャンバス アプリ、ポータル) のコード コンポーネントを開発するときは、プラットフォームでサポートとして使用している API の可用性を常に確認してください。 たとえば、context.webAPI
はキャンバス アプリで使用できません。 個々の API の可用性については、Power Apps component framework API リファレンス を参照してください。
updateView
に渡される一時的に null のプロパティ値管理します
データの準備ができていない場合、updateView
メソッドに渡される値は null になります。 コンポーネントはこの状況を考慮し、データがnullになる可能性があること、およびその後の updateView
サイクルには更新された値を含めることができます。 updateView
は 標準 と React コンポーネントの両方で利用可能です。
モデル駆動型アプリ
このセクションには、モデル駆動型アプリ内のコード コンポーネントに関連するベスト プラクティスとガイダンスが含まれています。
formContext
と直接やり取りしないでください
クライアント API を使用した経験がある場合は、formContext
にアクセスして、属性、コントロールにアクセスし、save
、refresh
、setNotification
などの API メソッドを呼び出すことができます。 コード コンポーネントは、モデル駆動型アプリ、キャンバス アプリ、ダッシュボードなどのさまざまな製品で機能することが意図されているため、formContext
に依存することはできません。
回避策は、コード コンポーネントを列にバインドし、OnChange
イベントハンドラーをその列へ追加する方法です。 コード コンポーネントは列の値を更新でき、OnChange
イベント ハンドラーは formContext
にアクセスできます。 将来的には、列構成を追加せずにコントロールの外部で変更を伝達するために使用できるカスタム イベントのサポートを追加する予定です。
WebApi
への呼び出しのサイズと頻度を制限する
context.WebApi
メソッドを使用する場合、呼び出しの数とデータ量を制限します。 WebApi
を呼び出すたびに、ユーザーの API 権利とサービス保護の制限がカウントされます。 レコードに対して CRUD 操作を実行するときは、ペイロードのサイズを考慮してください。 一般に、要求のペイロードが大きいほど、コード コンポーネントは遅くなります。
キャンバス アプリ
このセクションには、キャンバス アプリ内のコード コンポーネントに関連するベスト プラクティスとガイダンスが含まれています。
画面上のコンポーネント数を最小限に抑える
キャンバス アプリにコンポーネントを追加するたびに、レンダリングに限られた時間がかかります。 コンポーネントを追加するたびにレンダリング時間は長くなります。 開発者向けのパフォーマンスのツールを使用して画面に追加するときは、コード コンポーネントのパフォーマンスを注意深く測定してください。
現在、各コード コンポーネントには、Fluent UI や React などの共有ライブラリの独自のライブラリがバンドルされています。 同じライブラリの複数のインスタンスをロードしても、これらのライブラリが複数回読み込まれるされることはありません。 ただし、複数の異なるコードコンポーネントを読み込むと、ブラウザはこれらのライブラリの複数のバンドルバージョンを読み込みます。 将来的には、ライブラリをロードして、コード コンポーネントと共有できるようになります。
メーカーがコード コンポーネントのスタイルを設定できるようにする
アプリ メーカーがキャンバス アプリ内からコード コンポーネントを使用する場合、アプリの他の部分と一致するスタイルを使用すると便利です。 入力プロパティを使用して、色やサイズなどのテーマ要素のカスタマイズ オプションを使用できるようにします。 Microsoft Fluent UI を使用する場合は、これらのプロパティをライブラリが提供するテーマ要素にマップします。 将来的には、テーマ サポートがコード コンポーネントに追加され、プロセスが簡単になります。
キャンバス アプリのパフォーマンスのベスト プラクティスに従う
キャンバス アプリは、アプリとソリューション チェッカー内から幅広いベスト プラクティスを提供します。 コード コンポーネントを追加する前に、アプリがレコメンデーションに従っているかを確認してください。 詳細については、以下を参照してください。
TypeScript および JavaScript
このセクションには、コード コンポーネント内の TypeScript および JavaScript に関連するベスト プラクティスとガイダンスが含まれています。
ES5 と ES6
既定では、コード コンポーネントは ES5 をターゲットにして古いブラウザーをサポートします。 これらの古いブラウザをサポートしたくない場合は、pcfproj
フォルダーの tsconfig.json
内でターゲットを ES6 に変更できます。 詳細情報: ES5 と ES6。
モジュールのインポート
SCRIPT
タグを使用してロードする必要があるスクリプトを使用せずに、コード コンポーネントの一部として必要なモジュールを常にバンドルします。 たとえば、ページに追加された <script type="text/javascript" src="somechartlibrary.js></script>
がサンプルに表示されている Microsoft でない API の使用は、コード コンポーネント内ではサポートされません。 必要なすべてのモジュールをバンドルすると、コード コンポーネントが他のライブラリから分離され、オフライン モードでの実行もサポートされます。
注意
コンポーネント マニフェストでライブラリ ノードを使用しているコンポーネント間での共有ライブラリのサポートは、まだサポートされません。
リンティング
リンティングは、ツールが潜在的な問題に関するコードをスキャンすることです。 pac pcf init が使用するテンプレートは eslint
モジュールをプロジェクトにインストールし、.eslintrc.json
ファイルを追加することで構成します。 Eslint
は、TypeScript および React のコーディング スタイルを構成する必要があります。 また、可能な場合は、問題の一部を自動的に修正するために使用することもできます。 構成するには、コマンドラインで以下を使用します。
npx eslint --init
次に、指示が出たら次の質問に答えます。
ESLint
をどのように使用したいですか。 回答: 構文をチェックし、問題を見つけ、コード スタイルを適用するプロジェクトでは、どのタイプのモジュールを使用していますか。 回答: JavaScript モジュール (インポート/エクスポート)
プロジェクトで使用しているフレームワークはどれですか。 回答: React
あなたのプロジェクトでは TypeScript を使用していますか。 回答: はい
コードはどこで実行されますか。 回答: ブラウザー
プロジェクトのスタイルをどう定義しますか。 回答: スタイルに関する質問に答える
希望する構成ファイルの形式は。 回答: JSON (この答えは、既存の
.eslintrc.json
が更新されます)どのスタイルのインデントを使用しますか。 回答: スペース (このインデントスタイルは Visual Studio Code のデフォルトです)
文字列にはどの引用符を使用しますか。 回答: シングル
行末の種類は何を使用しますか。 回答: Windows (この行の編集は Visual Studio Code のデフォルト CRLF 行編集スタイルです。)
セミコロンが必要ですか。 回答: はい
注意
この構成を特定のニーズに合わせてカスタマイズできます (たとえば、React を使用していない場合)。 詳細: ESLint の使用を開始する。
eslint
を使用するには、package.json
にスクリプトを追加する必要があります。
"scripts": {
...
"lint": "eslint MY_CONTROL_NAME --ext .ts,.tsx",
"lint:fix": "npm run lint -- --fix"
}
eslint
スクリプトは、コードを含むフォルダーを受け入れます。 MY_CONTROL_NAME と pac pcf init を呼び出す際に使用されるコードコンポーネントと同じ名前に置き換えます。
コマンドラインで以下を使用できるようになりました:
npm run lint:fix
このコマンドにより、プロジェクト内のコードが整理され選択したスタイルに統一し、後で解決できる問題も報告されます。
注意
ESLint は、最初にテンプレート コードの問題を指摘します (例: 空のコンストラクター)。 インライン コメントを追加すると、ESLint が // eslint-disable-next-line @typescript-eslint/no-empty-function
などのルールを除外します
さらに、以下を .eslintrc.json
に追加すると、無視するファイル (たとえば、自動生成されたインターフェイス) を追加できます:
"ignorePatterns": ["**/generated/*.ts"]
詳細: 構成ファイルの ignorePatterns 。
ヒント
プロジェクトの .eslintrc.json
ファイルを使用する Visual Studio Code 拡張をインストールして、検出された問題を強調表示するコードを使用することができます (IDE 内での直接修正はオプション)。 詳細: Visual Studio Code で拡張機能を管理する。
HTML ブラウザーのユーザー インターフェイスの開発
このセクションには、HTML ブラウザーの UI 開発に関連するベスト プラクティスとガイダンスが含まれています。
Microsoft Fluent UI React を使用する
Fluent UI React は、公式の オープン ソース React で、幅広いマイクロソフト製品にシームレスに適合するエクスペリエンスを構築するように設計されたフロントエンド フレームワークです。 Power Apps 自体が Fluent UI を使用し、他のアプリと一貫性のある UI を作成できます。
Fluent からのパス ベースのインポートを使用して、バンドル サイズを縮小します
現在、webpack
で使用されるコード コンポーネント テンプレートでは、pac pcf init が使用されていないインポートされたモジュールを検出し削除するツリーシェーキングを使用しません。 以下のコマンドを使用して Fluent UI からインポートする場合、ライブラリ全体をインポートしてバンドルします。
import { Button } from '@fluentui/react'
ライブラリ全体のインポートとバンドルを避けるには、パス ベースのインポートを使用し、特定のライブラリ コンポーネントを明示的なパスを使用してインポートします。
import { Button } from '@fluentui/react/lib/Button';
特定のパスを使用することで、開発ビルドとリリース ビルドでバンドル サイズが削減されます。
compilerOptions
セクション内にある tsconfig.json
を更新して次のモジュール構成を使用すると、ツリーシェイキング (リリース/運用ビルドにのみ影響します) を利用できます。
"module": "es2015",
"moduleResolution": "node"
詳細: Fluent UI - 高度な使用法。
React レンダリングを最適化する
React を使用する際は、コンポーネントのレンダリングを最小限に抑えることに関する React 固有のベスト プラクティスに従うことが重要です。これにより、UI の応答性が向上します。 以下はベスト プラクティスの例です。
- バインドされたプロパティまたはフレームワークのアスペクトが変更された場合に、
updateView
メソッド内でReactDOM.render
を呼び出すと、UI は変更を反映する必要があります。 updateProperties を使用して、変更内容を特定します。 - PureComponent (クラス コンポーネント) か、React.memo (関数コンポーネント) を使用して、可能な場合は入力プロパティが変更されていないときにコンポーネントが不要に再レンダリングされるのを回避します。
- 規模の大きな React コンポーネントの場合は、UI を小さなコンポーネントに分解してパフォーマンスを向上させます。
- これらの慣行はレンダリングごとに新しいコールバック クローズを作成し、親コンポーネントがレンダリングされるときに子コンポーネントが常に再レンダリングされるため、レンダリング関数内で矢印関数と関数バインディングを使用しないでください。 代わりに、コンストラクターで関数バインディングを使用するか、クラス フィールドの矢印関数を使用してください。 イベントの処理 - React を参照する。
アクセシビリティの確認
コード コンポーネントにアクセスでき、キーボードのみ、およびスクリーンリーダーのユーザーが使用できることを確認します。
- マウス/タッチ イベントに代わるキーボード ナビゲーションを提供します。 たとえば、コンポーネントにドロップダウン リストがある場合は、ユーザーがタブを使用してフォーカスを設定し、矢印キーを使用してオプションを移動できることを確認します。
alt
および ARIA (Accessible Rich Internet Applications) 属性が設定され、コード コンポーネント インターフェイスをスクリーン リーダーが適切に把握できることを確認します。 Microsoft Fluent UI ライブラリでは、多くのコンポーネントがすでにアクセス可能であり、スクリーン リーダーと互換性があるため、この属性を使うことが簡単です。- 最新のブラウザ開発者ツールには、アクセシビリティを検査する優れたツールが含まれています。 これらのツールを使用して、コード コンポーネントに関する一般的なアクセシビリティの問題を検索します。
詳細: Power Apps でアクセス可能なキャンバス アプリを作成する。
常に非同期ネットワークの呼び出しを使用する
ネットワークの呼び出しを行うときは、同期ブロック リクエストは絶対に使用しないでください。同期ブロックリ クエストを使用すると、アプリケーションの応答が停止し、パフォーマンスが低下します。 詳細: HTTP および HTTPS リソースを非同期に操作する。
複数のブラウザーに対応したコードを記述する
モデル駆動型アプリ、キャンバス アプリ、ポータルはすべて、複数のブラウザをサポートしています。 最新のすべてのブラウザーでサポートされている手段のみを使用し、対象ユーザーが使用する一般的なブラウザーでテストしてください。
コード コンポーネントは、複数のクライアントと画面形式をサポートする計画が必要です
コード コンポーネントは、複数のクライアント (モデル駆動型アプリ、キャンバス アプリ、ポータル) および画面形式 (モバイル、タブレット、Web) でレンダリングできます。 モデル駆動型アプリで使用する場合、データセット コード コンポーネントは、メイン フォーム グリッド、関連するレコード グリッド、サブグリッド、またはダッシュボードに配置できます。 キャンバス アプリで使用すると、コード コンポーネントをレスポンシブ コンテナー内に配置することができ、アプリの開発者が提供する設定を使用して動的にサイズを変更することができます。
trackContainerResize
を使用すると、コード コンポーネントが使用可能な幅と高さの変更に対応できるようになります。 場合によっては、この設定は使用可能なスペースに適合する別の UI をレンダリングします。allocatedHeight
およびallocatedWidth
とgetFormFactor
を一緒に使用することで、コード コンポーネントが、モバイル、タブレット、または Web クライアントで実行されているかどうかを確認することができます。 詳細情報については、チョイス ピッカーのチュートリアル を参照してください。setFullScreen
を実装すると、ユーザーは、スぺースが限られている場合に利用可能な画面全体を使用できるよう拡張することができます。 詳細: キャンバス アプリ グリッド コンポーネント。- コード コンポーネントが指定されたコンテナー サイズで有意義なエクスペリエンスを実現できない場合は、機能を適切に無効にして、ユーザーにフィードバックを提供する必要があります。
常にスコープ設定されている CSS ルールを使用する
CSS を使用してコード コンポーネントにスタイリングを実装する場合、コンポーネント用のコンテナー DIV
要素に適用され自動生成された CSS クラスを使用して、CSS がコンポーネントに対してスコープ設定されているかを確認します。 CSS がグローバルにスコープ設定されている場合、コード コンポーネントが表示されるフォームまたは画面の既存のスタイルが損なわれる可能性があります。 サード パーティの CSS フレームワークを使用している場合は、名前空間が設定されているフレームワークのバージョンを使用するか、手動で、または CSS プリプロセッサを使用して、そのフレームワークを名前空間にラップします。
たとえば、名前空間が SampleNamespace
でコード コンポーネント名が LinearInputComponent
の場合、次を使用してカスタム CSS ルール追加します。
.SampleNamespace\.LinearInputComponent rule-name
Web ストレージ オブジェクトは使用しないでください
コード コンポーネントは、データを保存するために window.localStorage
や window.sessionStorage
のような HTML Web ストレージ オブジェクトを使用しないでください。 ユーザーのブラウザやモバイル クライアントにローカルに保存されたデータは安全ではなく、確実に利用できることが保証されていません。
ALM/Azure DevOps/GitHub
ALM/Azure DevOps/GitHub を使用したコード コンポーネントのベスト プラクティスに関しては、コード コンポーネント アプリケーションのライフサイクル管理 (ALM) の記事を参照してください。