성능 최적화: 애플리케이션 리소스

WPF를 사용하면 유사한 형식의 요소에서 일관된 모양이나 동작을 지원할 수 있도록 애플리케이션 리소스를 공유할 수 있습니다. 이 항목에서는 이 영역에서 애플리케이션의 성능을 개선하는 데 도움이 될 수 있는 몇 가지 권장 사항을 제공합니다.

리소스에 대한 자세한 내용은 XAML 리소스를 참조하세요.

리소스 공유

애플리케이션이 사용자 정의 컨트롤을 사용하고 ResourceDictionary(또는 XAML 리소스 노드)에서 리소스를 정의하는 경우 Application 또는 Window 개체 수준에서 리소스를 정의하거나 사용자 지정 컨트롤의 기본 테마에서 리소스를 정의하는 것이 좋습니다. 사용자 지정 컨트롤의 ResourceDictionary에서 리소스를 정의하면 해당 컨트롤의 모든 인스턴스 성능에 영향을 미칩니다. 예를 들어 사용자 지정 컨트롤의 리소스 정의의 일부로 정의된 성능 집약적인 브러시 작업과 사용자 지정 컨트롤의 많은 인스턴스가 있는 경우 애플리케이션의 작업 집합이 크게 증가합니다.

이 점을 설명하려면 다음을 고려하세요. WPF를 사용하여 카드 게임을 개발하고 있다고 가정해 보겠습니다. 대부분의 카드 게임에는 52가지 다른 면이 있는 52개의 카드가 필요합니다. 카드 사용자 지정 컨트롤을 구현하기로 결정하고 카드 사용자 지정 컨트롤의 리소스에 52개의 브러시(각각 카드 면을 나타냄)를 정의합니다. 주 애플리케이션에서는 처음에 이 카드 사용자 지정 컨트롤의 52개 인스턴스를 만듭니다. 카드 사용자 지정 컨트롤의 각 인스턴스는 52개의 Brush 개체 인스턴스를 생성하며, 애플리케이션에 총 52 * 52개의 Brush 개체를 제공합니다. 카드 사용자 지정 컨트롤 리소스에서 Application 또는 Window 개체 수준으로 브러시를 이동하거나 사용자 지정 컨트롤의 기본 테마에서 브러시를 정의하면 이제 카드 컨트롤의 52개 인스턴스 간에 52개의 브러시를 공유하기 때문에 애플리케이션의 작업 집합을 줄일 수 있습니다.

복사하지 않고 브러시 공유

동일한 Brush 개체를 사용하는 요소가 여러 개 있는 경우 XAML에서 브러시 인라인을 정의하는 대신 브러시를 리소스로 정의하고 참조합니다. 이 메서드는 하나의 인스턴스를 만들고 다시 사용하는 반면 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>

참고 항목