web-dev-qa-db-ja.com

WPF UIレンダリング速度を改善する方法

WPFアプリケーションの画面に多数のプリミティブコントロールが含まれている場合、レンダリングが遅くなります。このような場合、WPFアプリケーションの応答性を改善するための推奨される方法は何ですか?コントロールの追加とより強力なビデオカードの使用は別ですか?

どういうわけかオフスクリーンバッファリングなどを使用する方法はありますか?

41
rem

私たちのチームは、レンダリングパフォーマンスの問題に直面していました。この場合、約400の輸送ユニットがあり、すべてのユニットのチャートを多くの詳細(テキストラベル、特殊マーク、異なる形状など)でレンダリングする必要があります。

最初の実装では、各チャートをプリミティブに分割し、Bindingを介してユニット全体のチャートを構成しました。とても悲しい経験でした。 UIの反応は非常に遅かった。

そこで、各ユニットごとにone UI要素を作成し、DrawingContextでグラフをレンダリングすることにしました。これはパフォーマンスの面でははるかに優れていましたが、レンダリングの改善に約1か月を費やしました。

いくつかのアドバイス:

  1. すべてをキャッシュします。ブラシ、色、ジオメトリ、書式付きテキスト、グリフ。 (たとえば、RenderToolsTextCacheの2つのクラスがあります。各ユニットアドレスのレンダリングプロセスは、両方のクラスの共有インスタンスになります。したがって、2つのチャートのテキストが同じ場合、 )
  2. 長期間使用する場合は、Freezableをフリーズします。特にジオメトリ。複雑なフリーズされていないジオメトリは、HitTestを非常に遅く実行します。
  3. 各プリミティブのレンダリングの最速の方法を選択します。たとえば、テキストレンダリングには約6つの方法がありますが、最速はDrawingContext.DrawGlyphs
  4. プロファイラーを使用して、ホットスポットを検出します。たとえば、このプロジェクトでは、ジオメトリキャッシュを用意し、必要に応じてそれらを適切にレンダリングしました。改善の余地はないようです。しかし、ある日、ジオメトリを一度レンダリングして、すぐに使用できるビジュアルをキャッシュするとしたらどうなるでしょうか?私たちの場合、そのようなアプローチは受け入れられました。ユニットのチャートには、いくつかの状態があります。チャートのデータが変更されると、各状態のDrawingVisualを再構築し、キャッシュに入れます。

もちろん、この方法にはいくつかの投資が必要です。退屈で退屈な作業ですが、結果は素晴らしいです。

ちなみに、WPFキャッシングオプションをオンにすると(答えにリンクが表示されます)、アプリがハングしました。

50
Alex Zhevzhik

1年以来、高度にカスタマイズされたデータグリッドで同じパフォーマンスの問題が発生しており、私の結論は次のとおりです。

基本的にあなたがあなたの側でできることは何もありません(アプリに影響を与えることなく、すなわち、より少ないコントロールを持つか、デフォルトのスタイルのみを使用します)

Jensが言及したリンクは素晴らしいですが、あなたの場合は役に立ちません。

NVMが提供する「WPFアプリケーションパフォーマンスの最適化」リンクは、私の経験ではほとんど同じように役に立たない。それは常識に訴えかけるものであり、読書でも特別なことは何も学ばないと確信している。 多分1つを除いて:このリンクは、アプリのリソースにできるだけ多くを入れるように教えたと言わなければなりません。 WPFはリソースに追加したものを再インスタンス化しないため、同じリソースを何度も再利用するだけです。そのため、できる限り多くをそこに入れてください(スタイル、ブラシ、テンプレート、フォント...)

全体として、オプションをチェックしたり、他のオプションをオフにしたりするだけでは、WPFで高速化する方法はありません。近い将来、MSがレンダリングレイヤーを修正して最適化するように祈ることができますが、その間、エフェクト、カスタマイズされたコントロールなどの必要性を減らすようにしてください...

7
David

新しい(.NET 4.0)キャッシュオプションをご覧ください。 ( こちら を参照してください。)

3
Jens