高品質の Power BI カスタム ビジュアルを作成するためのパフォーマンスに関するヒント
この記事では、開発者がカスタム ビジュアルをレンダリングするときにハイ パフォーマンスを実現できる手法について説明します。
視覚エフェクトのレンダリングに時間がかかるのは、誰にとっても好ましいことではありません。 コードを記述するときは、視覚エフェクトが可能な限り速くレンダリングされるようにすることが重要です。
注意
プラットフォームが継続的に改善および強化されており、新しいバージョンの API が常にリリースされています。 Power BI ビジュアルのプラットフォームと機能セットを最大限に活用するために、最新のバージョンで最新の状態を維持することをお勧めします。 使用しているバージョンを確認するには、pbiviz.json ファイルの apiVersion
を確認してください。
カスタム ビジュアルのパフォーマンスを最適にするための推奨事項を次に示します。
プラグインのサイズを小さくする
カスタム ビジュアル プラグインのサイズを小さくすると、次のようになります。
- ダウンロード時間の短縮
- 視覚エフェクトが実行されるときのインストールが常に高速化
使われていないコードを削除する方法やツリー シェイキングとコード分割のことがわかるこれらのサード パーティ リソースは、プラグインのサイズを小さくするのに役立ちます。
視覚エフェクトのレンダリング時間を調べる
さまざまな状況で視覚エフェクトのレンダリング時間を測って、最適化が必要なスクリプトの部分 (ある場合) を突き止めます。
Power BI Desktop のパフォーマンス アナライザー
Power BI Desktop のパフォーマンス アナライザー ([表示]>[パフォーマンス アナライザー]) を使って、次の場合に視覚エフェクトがどのようにレンダリングされるかを調べます。
- 視覚エフェクトの最初のレンダリング
- 数千のデータ ポイント
- 1 データ ポイント/メジャー (視覚エフェクトのレンダリング オーバーヘッドを特定するため)
- Filtering
- スライス
- サイズ変更 (パフォーマンス アナライザーでは機能しない可能性があります)
可能な場合は、これらの測定値を似たコア視覚エフェクトのものと比べて、最適化できる部分があるかどうかを確認します。
User Timing API を使用する
User Timing API を使って、アプリの JavaScript のパフォーマンスを測定します。 この API は、最適化が必要なスクリプトの部分を判断するのにも役立ちます。
詳しくは、User Timing API の使用に関する記事をご覧ください。
カスタム ビジュアルをテストするその他の方法
コードのインストルメンテーション - 次のコンソール ツールを使って、カスタム ビジュアルのパフォーマンスに関するデータを集めます (これらのツールは外部のサード パーティ製ツールにリンクされていることに注意してください)。
次の Web 開発者ツールも視覚エフェクトのパフォーマンスを測るのに役立ちますが、Power BI のプロファイリングも行われることに注意してください。
最適化が必要な視覚エフェクトの部分がわかったら、以下のヒントを確認してください。
メッセージを更新する
視覚エフェクトを更新するとき:
- 一部の要素のみが変更されている場合は、視覚エフェクト全体を再レンダリングしないでください。 必要な要素のみをレンダリングします。
- 更新時に渡されたデータ ビューを格納します。 前のデータ ビューとは異なるデータ ポイントのみをレンダリングします。 変更されていない場合、再レンダリングする必要はありません。
- 多くの場合、サイズの変更はブラウザーによって自動的に行われ、視覚エフェクトの更新は必要ありません。
DOM ノードをキャッシュする
ノードまたはノード リストを DOM から取得するときは、後の計算で (場合によっては、次のループの反復で) それらを再利用できるかどうかを考えます。 関連領域内のノードを追加または削除する必要がない限り、これらのノードをキャッシュすることで、アプリケーションの全体的な効率を向上させることができます。
コードが高速で、ブラウザーの速度が低下しないようにするには、DOM アクセスを最小限に抑えます。
次に例を示します。
変更前:
public update(options: VisualUpdateOptions) {
let axis = $(".axis");
}
次のように変更してみます:
public constructor(options: VisualConstructorOptions) {
this.$root = $(options.element);
this.xAxis = this.$root.find(".xAxis");
}
public update(options: VisualUpdateOptions) {
let axis = this.axis;
}
DOM の操作を回避する
可能な限り DOM 操作を制限します。 prepend()
、append()
、after()
などの "挿入操作" は時間がかかるため、必要なときにだけ使うようにしてください。
次に例を示します。
変更前:
for (let i=0; i<1000; i++) {
$('#list').append('<li>'+i+'</li>');
}
次のように変更してみます:
上の例は、html()
を使用し、事前にリストを構築することで、さらに高速になります。
let list = '';
for (let i=0; i<1000; i++) {
list += '<li>'+i+'</li>';
}
$('#list').html(list);
JQuery を再検討する
可能な限り JS フレームワークを制限してネイティブ JS を使用することで、使用可能な帯域幅が増え、処理のオーバーヘッドが減ります。 このようにすると、古いブラウザーとの互換性の問題も減る可能性があります。
JQuery の show
、hide
、addClass
などの関数に関する別の例について詳しくは、youmightnotneedjquery.com を参照してください。
アニメーション
アニメーションのオプション
アニメーションを繰り返し使う場合は、SVG ではなくキャンバスまたは WebGL の使用を検討してください。 SVG とは異なり、これらのオプションを使用すると、コンテンツではなくサイズによってパフォーマンスが決まります。
その違いについて詳しくは、「SVG とキャンバス: 選択する方法」をご覧ください。
キャンバスのパフォーマンスに関するヒント
キャンバスのパフォーマンス向上に関するヒントについては、次のサード パーティのサイトを確認してください。
たとえば、位置ではなく色でレンダリングすることでキャンバスの不必要な状態変化を回避する方法を理解してください。
アニメーション関数
requestAnimationFrame を使って画面上のアニメーションを更新し、ブラウザーが別の再描画を呼び出す前に、アニメーション関数が呼び出されるようにします。
アニメーション ループ
アニメーション ループで、変更されない要素は再描画しますか?
そうだとしたら、フレーム間で変わらない要素を描画するのは、時間の浪費です。
解決策: フレームを選択的に更新します。
静的な視覚エフェクトをアニメーション化するときは、すべての描画コードを 1 つの更新関数にまとめて、アニメーション ループの反復ごとに新しいデータでそれを繰り返し呼び出したくなります。
代わりに、ビジュアル コンストラクター メソッドを使って、すべての静的なものを描画することを検討します。 そうすると、更新関数では変化する視覚化要素を描画するだけで済みます。
ヒント
軸と凡例で、非効率的なアニメーション ループがよく見られます。
一般的な問題
- テキスト サイズの計算: 多くのデータ ポイントがある場合は、ポイントごとにテキスト サイズを計算して時間を無駄にしないでください。 いくつかのポイントを計算してから推定します。
- 視覚エフェクトの一部の要素がディスプレイに表示されない場合、それらをレンダリングする必要はありません。
関連するコンテンツ
その他の質問Power BI コミュニティを割り当て。