내용으로 건너뛰기
15가지 WPF 성능 팁

15가지 WPF 성능 팁

WPF 개발자이신가요? 여기에서는 WPF 응용 프로그램의 성능을 식별하고 개선하는 데 도움이 되는 15가지 팁을 제공합니다. 더 읽어보기.

8min read

WPF 개발자이신가요? WPF 앱의 성능이 좋지 않은 영역이 있거나 원하는 만큼 빠르게 실행되지 않습니까?  그렇다면 WPF 응용 프로그램의 성능을 식별하고 개선하는 데 도움이 되는 15  가지 팁이 있습니다.

WPF는 10년이 넘었고 수년에 걸쳐 크게 개선되었지만 여전히 성능 저하로 어려움을 겪을 수 있는 몇 가지 영역이 있습니다.  이러한 성능 저하의 이유에는 잘못된 코딩 관행, 손상된 바인딩, 복잡한 레이아웃, UI 가상화 부족 등이 포함됩니다. 다행히도 약간의 계획과 WPF 플랫폼에 대한 확실한 이해만 있으면 WPF 응용 프로그램을 초고속으로 끌어올리고 몇 밀리초 만에 우주를 가로질러 도약할 수 있습니다.

WPF 앱의 성능을 향상시키는 데 도움이 되는 15가지 팁을 모았습니다.

1. 시각적 트리를 단순화하십시오.

성능 문제의 일반적인 원인은 심층적이고 복잡한 레이아웃입니다. XAML 태그를 가능한 한 간단하고 단순하게 유지합니다.UI 요소가 화면에 그려지면 각 요소에 대해 "레이아웃 패스"가 두 번 호출됩니다(측정 패스 및 정렬 패스).레이아웃 패스는 수학을 많이 사용하는 프로세스로,요소의자식 수가 많 을수록 필요한 계산 수가 많아집니다.  

2. ItemsControls 가상화

앞서 언급했듯이 복잡하고 심층적인 시각적 트리는 메모리 사용량이 커지고 성능이 느려집니다. ItemsControls는 일반적으로 가상화되지 않기 때문에 심층적인 시각적 트리의 성능 문제를 증가시킵니다. 이것은 컨트롤의 각 항목에 대해 지속적으로 생성되고 소멸되고 있음을 의미합니다. 대신 VirtualizingStackPanel을 항목 호스트로 사용하고, VirtualizingStackPanel.IsVirtualizing을 사용하고, 매번 새 항목 컨테이너를 만드는 대신 항목 컨테이너를 다시 사용할 수 있도록 VirtualizationMode를 Recycling으로 설정합니다.

3. DynamicResources보다 StaticResources 선호

StaticResources는 이미 정의된 리소스에 대한 참조를 조회하여 모든 XAML 속성 특성에 대한 값을 제공합니다. 해당 리소스에 대한 조회 동작은 컴파일 시간 조회와 동일합니다. DynamicResources는 임시 표현식을 만들고 요청된 리소스 값이 필요할 때까지 리소스 조회를 연기합니다. 해당 리소스에 대한 조회 동작은 런타임 조회와 동일하며, 이는 성능에 영향을 미칩니다. 가능하면 항상 StaticResource를 사용합니다.

4. 요소 대신 브러시의 불투명도

Brush를 사용하여 요소의 Fill 또는 Stroke를 설정하는 경우 요소의 Opacity 속성을 설정하는 것보다 Brush에서 Opacity를 설정하는 것이 좋습니다. 요소의 Opacity 속성을 수정하면 WPF에서 임시 표면을 만들어 성능이 저하될 수 있습니다.

5. Avoid Using Run to Set Text Properties

TextBlock 내에서 Runs를 사용하면 성능이 훨씬 더 많이 소모되는 작업이 발생하므로 사용하지 마십시오. Run을 사용하여 텍스트 속성을 설정하는 경우 대신 TextBlock에서 직접 설정합니다.

6. Favor StreamGeometries over PathGeometries

StreamGeometry 개체는 PathGeometry를 대체할 수 있는 매우 가벼운 개체입니다. StreamGeometry는 많은 PathGeometry 개체를 처리하는 데 최적화되어 있습니다. 많은 PathGeometry 개체를 사용하는 것과 비교할 때 메모리를 덜 사용하고 성능이 훨씬 뛰어납니다.

7. Use Reduced Image Sizes

앱에서 더 작은 썸네일을 표시해야 하는 경우 축소된 크기의 이미지 버전을 만드는 것이 좋습니다. 기본적으로 WPF는 이미지를 전체 크기로 로드하고 디코딩합니다. 이는 ItemsControl과 같은 컨트롤에서 전체 이미지를 로드하고 축소판 크기로 축소하는 경우 많은 성능 문제의 원인이 될 수 있습니다. 가능하면 여러 이미지로 구성된 필름 스트립과 같이 모든 이미지를 단일 이미지로 결합합니다.

8. Lower the BitMapScalingMode

기본적으로 WPF는 시스템 리소스를 소비하여 프레임 속도가 저하되고 애니메이션이 끊길 수 있는 고품질 이미지 다시 샘플링 알고리즘을 사용합니다. 대신 BitMapScalingMode를 LowQuality로 설정하여 "품질 최적화" 알고리즘에서 "속도 최적화" 알고리즘으로 전환합니다.

9. Freezables 사용 및 동결

Freezable은 고정되지 않은 상태와 고정된 상태의 두 가지 상태를 가진 특수한 유형의 개체입니다. Brush 또는 Geometry와 같은 개체를 고정하면 더 이상 수정할 수 없습니다. 가능할 때마다 개체를 고정하면 응용 프로그램의 성능이 향상되고 메모리 사용량이 줄어듭니다.

10. Fix your Binding Errors

바인딩 오류는 WPF 앱에서 가장 일반적인 유형의 성능 문제입니다. 바인딩 오류가 발생할 때마다 앱은 성능 저하를 겪고 바인딩을 해결하려고 시도하고 추적 로그에 오류를 기록합니다. 상상할 수 있듯이 바인딩 오류가 많을수록 앱의 성능 저하가 커집니다. 시간을 내어 모든 바인딩 오류를 찾아 수정하십시오. DataTemplates에서 RelativeSource 바인딩을 사용하는 것은 바인딩이 일반적으로 DataTempate가 초기화를 완료할 때까지 제대로 해결되지 않기 때문에 바인딩 오류의 주요 원인입니다. 어떤 경우에도 RelativeSource.FindAncestor를 사용하지 마십시오. 대신, 연결된 속성을 정의하고 속성 상속을 사용하여 시각적 트리를 조회하는 대신 시각적 트리 아래로 값을 푸시합니다.

11. Label.Content 속성에 대한 데이터 바인딩 방지

Label을 사용하여 String 속성에 데이터 바인딩하는 경우 성능이 저하됩니다. 이는 String 소스가 업데이트될 때마다 이전 문자열 개체가 삭제되고 새 String이 만들어지기 때문입니다. Label의 Content가 단순 텍스트인 경우 TextBlock으로 바꾸고 대신 Text 속성에 바인딩합니다.

12. Bind ItemsControls to IList instead of IEnumerable

ItemsControl을 IEnumerable에 데이터 바인딩할 때 WPF는 IList<T> 유형의 래퍼를 만들며, 이는 두 번째 개체를 만들 때 성능에 부정적인 영향을 줍니다. 대신 ItemsControl을 IList에 직접 바인딩하여 래퍼 개체의 오버헤드를 방지합니다.

13. Use the NeutralResourcesLanguage Attribute

NeutralResourcesLanguageAttribute를 사용하여 ResourceManager에 중립 문화권이 무엇인지 알리고 실패한 위성 어셈블리 조회를 방지합니다.

14. 별도의 스레드에서 데이터 불러오기

성능 문제, UI 멈춤 및 응답을 중지하는 앱의 매우 일반적인 원인은 데이터를 로드하는 방법입니다. UI 스레드를 오버로드하지 않도록 별도의 스레드에서 데이터를 비동기적으로 로드하고 있는지 확인하십시오. UI 스레드에서 데이터를 로드하면 성능이 매우 저하되고 최종 사용자 환경이 전반적으로 좋지 않습니다. 다중 스레딩은 모든 WPF 개발자가 응용 프로그램에서 사용하는 것이어야 합니다.

15. Beware of Memory Leaks

메모리 누수는 대부분의 WPF 응용 프로그램에서 성능 문제의 가장 큰 원인입니다.  그들은 가지고 있기 쉽지만 찾기가 어려울 수 있습니다.  예를 들어 DependencyPropertyDescriptor.AddValueChanged를 사용하면 WPF 프레임워크가 DependencyPropertyDescriptor.RemoveValueChanged를 수동으로 호출할 때까지 제거되지 않은 이벤트의 원본에 대한 강력한 참조를 사용할 수 있습니다. 뷰나 동작이 개체 또는 ViewModel(예: INotifyPropertyChanged)에서 발생하는 이벤트에 의존하는 경우 약하게 구독하거나 수동으로 구독을 취소해야 합니다. 또한 INotifyPropertyChanged 를 구현하지 않는 ViewModel 의 속성에 바인딩하는 경우 메모리 누수가 발생할 수 있습니다.

마지막으로 보너스 팁입니다. 경우에 따라 성능 문제가 있을 때 문제의 원인을 정확히 식별하기가 매우 어려울 수 있습니다. 응용 프로그램 성능 프로파일러를 사용하여 코드 베이스에서 이러한 성능 병목 현상이 발생하는 위치를 식별하는 것이 좋습니다. 사용할 수 있는 프로파일러 옵션이 많이 있습니다. 일부는 유료이고 일부는 무료입니다. 개인적으로 가장 많이 사용하는 것은 Visual Studio 2019에 직접 내장된 진단 도구입니다.

Twitter에서 저와 소통하고, 제 YouTube 채널을 구독하여 새로운 비디오 콘텐츠에 대한 알림을 받고, Twitch에서 저를 팔로우하여 라이브 스트리밍을 시청하세요. Ultimate UI for WPF를 사용하는 경우 Infragistics 엔지니어 및 다른 고객과 상호 작용할 수 있는 커뮤니티 포럼을 통해 다양한 팀과 연결하십시오.

데모 요청