データを操作する
学習の目的
この単元を完了すると、次のことができるようになります。
- データの取得を最適化する利点を説明する。
- データをキャッシュする利点を説明する。
固有のパフォーマンス課題に挑む
Lightning Web コンポーネントはクライアント側の 1 つのページで動作し、同じデータを処理する他のコンポーネントと共に、必要に応じて作成、破棄されます。そのため、開発者に Lightning Web コンポーネント固有のパフォーマンス課題が発生する可能性があります。ここでは、このような特徴がパフォーマンスにどのような影響を与えるのかを説明し、Lightning コンポーネントのパフォーマンスを最適化できるベストプラクティスを確認します。
まず、データの取得とキャッシュを最適化します。
データ取得を最適化する
データのないコンポーネントはあまり役立つコンポーネントとは言えません。Lightning Web コンポーネントでは、サーバーからデータを取得するときに使用できる方法が複数あります。次のような方法でサーバーとの往復処理を最適化できます。
- 可能な場合は、Lightning データサービスかキャッシュされたデータを使用します。
- サーバーへのコールを作成する前に、データを取得する方法が他にないかを確認します。
- 必要に応じて、さまざまなコンポーネントで同一データを取得する代わりに、属性、イベント、メソッドを使用してコンポーネント間でデータを渡すことを検討する。
- 特定のページの複数コンポーネントで同一データを取得する場合、UI 要素を含まず、データの照会を 1 回行うだけでデータを他のコンポーネントに渡せるようなサービスコンポーネントを作成することを検討する。
- サーバーへのコールを作成する場合、結果セットの項目と行を制限します。
- 必要な項目のみを「選択」する。
- 一度に大量の行を返さないように、クエリに「制限」を設定する。
- クエリの結果セットが大きくなる可能性がある場合、ページネーションを実装する。
- 稀にしかアクセスされないデータは遅延読み込みします。ユーザーが一度も必要としない可能性のあるデータは事前に読み込まないようにします。ユーザーがクリックしない可能性のあるアクセス頻度の低いコンポーネントは副タブに配置します。
- ページ設定されたデータを操作している場合を除き、クライアント側ですでに所有されているデータの絞り込みや並び替えを行うためのコールをサーバーへ行わないでください。JavaScript 配列には、並び替え、絞り込み、値の検索のような処理を実行する関数が用意されています。
- レコードのみならず、リストビュー、メタデータ、選択リスト値を取得するときも、Apex を使用する代わりに、Lightning データサービスと UI API を活用します。
getRecord
ワイヤーアダプター (UI API の一部) を使用する場合、コンポーネントに必要な項目のみを要求します。具体的に説明します。たとえば、コンポーネントで 1 つの項目が必要な場合、その項目のみを要求します。@wire(getRecord, { recordId:'$recordId', fields:['Contact.Name'] });
- レイアウト単位でのレコードの要求は、そのすべてのデータが本当に必要な場合を除き行わないでください。レイアウトはシステム管理者によって管理される項目のコレクションで、いつでも変更される可能性があります。レイアウトには何百個もの項目が含まれていることが多いため、非常に大きな負荷がかかります。
@wire(getRecord, { recordId:'$recordId', layoutTypes:['Full'] });
データキャッシュを改善する
アプリケーションコンポジションは、自己完結型コンポーネントを組み立ててアプリケーションを作成する強力な方法です。ただし、適切に計画しなければ、組み立てるコンポーネントの自律的な性質によってパフォーマンスに悪影響が生じる可能性があります。たとえば、作成するすべてのコンポーネントがそれぞれ独立したコールをサーバーに行って必要データを取得する場合、サーバーへのコール数が多くなります。小さなコールを何回も行うより、大きなコールを 1 回行う方が効率的です。
クライアント側でデータをキャッシュすると、コンポーネント間でデータが共有されることによってパフォーマンスが向上し、サーバーとの往復処理数が大幅に減少します。LWC では、クライアント側に Lightning データサービスとキャッシュ可能な Apex メソッドという 2 つのキャッシュメカニズムが組み込まれています。どちらも目的に合わない場合、カスタムのキャッシュソリューションを実装することもできます。
Lightning データサービス
Lightning データサービスでは、管理されたレコードアプローチが提供されます。Apex のデータアクセスロジックを記述する必要はありません。ユーザーの代わりに、レコードと項目のアクセシビリティを確認してセキュリティも処理します。フレームワークがレコードを管理する責任を担います。これには、最初の要求時におけるサーバーからのレコード取得、クライアントの非常に効率的なキャッシュへのレコードの保存、レコードを要求するすべてのコンポーネント間でのレコード共有、連動関係にある Salesforce データの変更時における変更内容のサーバーへの送信とキャッシュエントリの無効化などが含まれます。
後に別のコンポーネントで追加項目が必要になった場合、その項目は透過的に読み込まれ、キャッシュのレコードに追加されます。保存可能なアクションでは Apex メソッドによって返される任意の種別の応答をキャッシュできますが、Lightning データサービスでは多くの種別のユーザーインターフェース API データ (レコード、スキーマ、メタデータ、レイアウトメタデータ、レコードのリスト、リストメタデータなど) がキャッシュされます。また、ユーザーインターフェースの一貫性が高まります。コンポーネントでレコードが更新されると、そのレコードを使用する他のすべてのコンポーネントに通知され、通常、自動的に更新されます。
キャッシュ可能な Apex メソッド
Lightning データサービスを使用できない場合、Apex を使用します。キャッシュ可能な Apex メソッドは、同一の引数セットを含む同一のサーバーメソッドへの後続の要求がサーバーではなくキャッシュからアクセスできるように、応答をクライアントのキャッシュに保存するサーバーアクションです。
従来のリモートプロシージャーコール (RPC) アプローチを使用してデータにアクセスでき、リモートで呼び出し可能なメソッドとして、公開するロジックを Apex に実装できます。キャッシュ可能な Apex メソッドでは、サーバーメソッドのコールの戻り値に関係なく、ほとんど何でもキャッシュできます。一般的なガイドラインとして、変更されていない羃等なアクションをキャッシュ (保存可能としてマーク) することをお勧めします。
キャッシュ可能な Apex メソッドは簡単に作成できます。Apex メソッドに @AuraEnabled(cacheable=true)
アノテーションを付加するだけです。
API バージョン 55.0 以降では、@AuraEnabled(cacheable=true)
と共に @AuraEnabled(scope='global')
アノテーションを使用して、Apex メソッドをグローバルキャッシュにキャッシュできます。
@AuraEnabled(scope='global' cacheable=true) public static someObject getIceCream(String flavor) { // your code here }
次の単元では、順次表示と条件付き表示を使用して、データを必要なときにのみ表示する方法について説明します。
リソース
- Lightning Web Components Dev Guide (Lightning Web コンポーネント開発者ガイド): getRecord
- Lightning Web Components Dev Guide (Lightning Web コンポーネント開発者ガイド): getRecordUi
- Lightning Web Components Dev Guide (Lightning Web コンポーネント開発者ガイド): Data Guidelines (データガイドライン)
- 開発者ブログ: Modularizing Code in Lightning Components (Lightning コンポーネントでのコードのモジュール化)
- Trailhead: Lightning Web コンポーネントと Salesforce データ
- 開発者ブログ: Designing Lightning Pages for Scale (拡張を考慮した Lightning ページの設計)
- Lightning Web Components Dev Guide (Lightning Web コンポーネント開発者ガイド): Call Apex Methods (Apex メソッドのコール)
- Apex 開発者ガイド: AuraEnabled Annotation (AuraEnabled アノテーション)