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

WPFWPF を使用すると、類似した型の要素全体で一貫した外観や動作をサポートできるように、アプリケーションリソースを共有できます。allows you to share application resources so that you can support a consistent look or behavior across similar-typed elements. このトピックでは、アプリケーションのパフォーマンスを向上させるために役立ついくつかの推奨事項について説明します。This topic provides a few recommendations in this area that can help you improve the performance of your applications.

リソースについて詳しくは、「XAML リソース」をご覧ください。For more information on resources, see XAML Resources.

リソースの共有Sharing resources

アプリケーションでカスタムコントロールを使用して、ResourceDictionary (または XAML リソースノード) 内のリソースを定義する場合は、Application または Window のオブジェクトレベルでリソースを定義するか、カスタムコントロールの既定のテーマでそれらを定義することをお勧めします。If your application uses custom controls and defines resources in a ResourceDictionary (or XAML Resources node), it is recommended that you either define the resources at the Application or Window object level, or define them in the default theme for the custom controls. カスタムコントロールの ResourceDictionary にリソースを定義すると、そのコントロールのすべてのインスタンスのパフォーマンスに影響が生じます。Defining resources in a custom control's ResourceDictionary imposes a performance impact for every instance of that control. たとえば、カスタムコントロールのリソース定義の一部として定義されているパフォーマンスを集中的に使用するブラシ操作と、カスタムコントロールの多くのインスタンスがある場合、アプリケーションのワーキングセットは大幅に増加します。For example, if you have performance-intensive brush operations defined as part of the resource definition of a custom control and many instances of the custom control, the application's working set will increase significantly.

この点を説明するために、次の点を考慮してください。To illustrate this point, consider the following. たとえば、WPFWPFを使用してカードゲームを開発しているとします。Let's say you are developing a card game using WPFWPF. ほとんどのカードゲームでは、52の異なる顔を持つ52カードが必要です。For most card games, you need 52 cards with 52 different faces. カードのカスタムコントロールを実装し、カードのカスタムコントロールのリソースに52のブラシ (それぞれカードの表面を表す) を定義します。You decide to implement a card custom control and you define 52 brushes (each representing a card face) in the resources of your card custom control. メインアプリケーションでは、最初にこのカードカスタムコントロールの52インスタンスを作成します。In your main application, you initially create 52 instances of this card custom control. カードカスタムコントロールの各インスタンスは、Brush オブジェクトの52インスタンスを生成します。これにより、アプリケーションで合計 52 * 52 Brush オブジェクトが得られます。Each instance of the card custom control generates 52 instances of Brush objects, which gives you a total of 52 * 52 Brush objects in your application. ブラシをカードのカスタムコントロールリソースから Application または Window オブジェクトレベルに移動したり、カスタムコントロールの既定のテーマで定義したりすることにより、52ブラシを52間で共有しているため、アプリケーションのワーキングセットを減らすことができます。カードコントロールのインスタンス。By moving the brushes out of the card custom control resources to the Application or Window object level, or defining them in the default theme for the custom control, you reduce the working set of the application, since you are now sharing the 52 brushes among 52 instances of the card control.

コピーせずにブラシを共有するSharing a Brush without Copying

同じ Brush オブジェクトを使用している複数の要素がある場合は、XAML でブラシをインラインで定義するのではなく、ブラシをリソースとして定義し、それを参照します。If you have multiple elements using the same Brush object, define the brush as a resource and reference it, rather than defining the brush inline in XAML. このメソッドは、1つのインスタンスを作成して再利用します。一方、XAML でブラシをインラインで定義すると、要素ごとに新しいインスタンスが作成されます。This method will create one instance and reuse it, whereas defining brushes inline in XAML creates a new instance for each element.

次のマークアップサンプルは、この点を示しています。The following markup sample illustrates this point:

<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>

可能な場合は静的リソースを使用するUse Static Resources when Possible

静的リソースは、既に定義されているリソースへの参照を検索することによって、任意の XAML プロパティ属性の値を提供します。A static resource provides a value for any XAML property attribute by looking up a reference to an already defined resource. このリソースの参照動作は、コンパイル時の参照に似ています。Lookup behavior for that resource is analogous to compile-time lookup.

一方、動的リソースでは、初期コンパイル中に一時式が作成されます。そのため、オブジェクトを構築するために要求されたリソース値が実際に必要になるまで、リソースの参照を延期します。A dynamic resource, on the other hand, will create a temporary expression during the initial compilation and thus defer lookup for resources until the requested resource value is actually required in order to construct an object. そのリソースの参照動作は、実行時の検索に似ており、パフォーマンスに影響します。Lookup behavior for that resource is analogous to run-time lookup, which imposes a performance impact. 必要な場合にのみ動的リソースを使用して、アプリケーションで可能な限り静的リソースを使用します。Use static resources whenever possible in your application, using dynamic resources only when necessary.

次のマークアップサンプルは、両方の種類のリソースの使用方法を示しています。The following markup sample shows the use of both types of resources:

<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>

関連項目See also