パフォーマンスの最適化 : アプリケーション リソース

WPF では、アプリケーション リソースを共有して、同じような種類の要素の間で外観や動作の一貫性を維持することができます。 このトピックでは、アプリケーションのパフォーマンス向上に役立つリソース関連の推奨事項について説明します。

リソースの詳細については、「リソースの概要」を参照してください。

リソースの共有

アプリケーションでカスタム コントロールを使用していて、ResourceDictionary (または XAML Resources ノード) でリソースを定義している場合は、Application オブジェクトまたは Window オブジェクトのレベルで定義するか、カスタム コントロールの既定のテーマで定義することをお勧めします。 カスタム コントロールの ResourceDictionary でリソースを定義すると、そのコントロールのすべてのインスタンスにパフォーマンスの影響が及びます。 たとえば、負荷の高いブラシ操作がカスタム コントロールとその多くのインスタンスのリソース定義の一部として定義されていると、アプリケーションの作業セットが大幅に増大します。

これを実際の例で考えてみましょう。 WPF を使用してトランプ ゲームを開発するとします。 ほとんどのトランプ ゲームでは、それぞれ異なる面を持つ 52 枚のカードが必要です。 そのためにカード カスタム コントロールを実装することにして、そのリソースで 52 のブラシを定義します (各ブラシはそれぞれカードの面を表します)。 メイン アプリケーションでは、最初にこのカード カスタム コントロールの 52 のインスタンスを作成します。 カード カスタム コントロールの各インスタンスでは、それぞれ Brush オブジェクトの 52 のインスタンスが生成されます。その結果、全部で 52 × 52 の Brush オブジェクトがアプリケーションに存在することになります。 ブラシをカード カスタム コントロールのリソースから Application オブジェクトまたは Window オブジェクトのレベルに移動するか、カスタム コントロールの既定のテーマで定義すると、カード コントロールの 52 のインスタンスの間で 52 のブラシが共有されるようになるため、アプリケーションの作業セットが縮小されます。

ブラシはコピーせずに共有する

同じ Brush オブジェクトを使用する複数の要素がある場合は、ブラシを XAML でインラインで定義するのではなく、リソースとして定義して参照するようにします。 この方法を使用すると、1 つのインスタンスを作成してそれを再利用することができます。一方、ブラシを XAML でインラインで定義した場合は、各要素に対して新しいインスタンスが作成されます。

この例を次のマークアップ サンプルに示します。

<StackPanel.Resources>
  <LinearGradientBrush x:Key="myBrush" StartPoint="0,0.5" EndPoint="1,0.5" Opacity="0.5">
    <LinearGradientBrush.GradientStops>
      <GradientStopCollection>
        <GradientStop Color="GoldenRod" Offset="0" />
        <GradientStop Color="White" Offset="1" />
      </GradientStopCollection>
    </LinearGradientBrush.GradientStops>
  </LinearGradientBrush>
</StackPanel.Resources>

<!-- Non-shared Brush object. -->
<Label>
  Label 1
  <Label.Background>
    <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5" Opacity="0.5">
      <LinearGradientBrush.GradientStops>
        <GradientStopCollection>
          <GradientStop Color="GoldenRod" Offset="0" />
          <GradientStop Color="White" Offset="1" />
        </GradientStopCollection>
      </LinearGradientBrush.GradientStops>
    </LinearGradientBrush>
  </Label.Background>
</Label>

<!-- Shared Brush object. -->
<Label Background="{StaticResource myBrush}">Label 2</Label>
<Label Background="{StaticResource myBrush}">Label 3</Label>

可能な限り静的リソースを使用する

静的リソースは、既に定義されたリソースに対する参照を検索することによって、任意の XAML プロパティ属性の値を指定します。 そのリソースに関する検索動作は、コンパイル時の検索に似ています。

一方、動的リソースは、初期コンパイル中に一時的な式を作成し、それによって、要求されたリソース値がオブジェクトを構成するために実際に必要になるまで、リソースに関する検索を遅延します。 そのリソースに関する検索動作は、実行時検索に似ています。これはパフォーマンスに影響します。 アプリケーションでは可能な限り静的リソースを使用し、動的リソースを使用するのは必要な場合だけにしてください。

次のマークアップ サンプルでは、この両方の種類のリソースが使用されています。

<StackPanel.Resources>
  <SolidColorBrush x:Key="myBrush" Color="Teal"/>
</StackPanel.Resources>

<!-- StaticResource reference -->
<Label Foreground="{StaticResource myBrush}">Label 1</Label>

<!-- DynamicResource reference -->
<Label Foreground="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">Label 2</Label>

参照

概念

WPF アプリケーションのパフォーマンスの最適化

アプリケーション パフォーマンスの計画

パフォーマンスの最適化 : ハードウェアの活用

パフォーマンスの最適化 : レイアウトとデザイン

パフォーマンスの最適化 : 2D グラフィックスとイメージング

パフォーマンスの最適化 : オブジェクトの動作

パフォーマンスの最適化 : テキスト

パフォーマンスの最適化 : データ バインディング

パフォーマンスの最適化 : その他の推奨事項