성능 최적화: 컨트롤
WPF(Windows Presentation Foundation)에는 대부분의 Windows 애플리케이션에 사용되는 일반적인 UI(사용자 인터페이스) 구성 요소가 다수 포함되어 있습니다. 이 항목에서는 UI의 성능을 향상시킬 수 있는 기술에 대해 설명합니다.
대용량 데이터 세트 표시
ListView 및 ComboBox와 같은 WPF 컨트롤은 애플리케이션의 항목 목록을 표시하는 데 사용됩니다. 표시할 목록이 크면 애플리케이션의 성능에 영향을 줄 수 있습니다. 그 이유는 표준 레이아웃 시스템에서는 목록 컨트롤과 연결된 각 항목에 대해 레이아웃 컨테이너를 만들고 해당 레이아웃의 크기와 위치를 계산하기 때문입니다. 대개는 모든 항목을 동시에 표시할 필요가 없습니다. 대신 항목의 일부만 표시하고 사용자가 목록을 스크롤하면 됩니다. 이 경우에는 UI 가상화를 사용하는 것이 적합합니다. 가상화를 사용하면 항목이 실제로 표시될 때까지 해당 항목에 대한 항목 컨테이너 생성 및 연결된 레이아웃에 대한 계산이 지연됩니다.
UI 가상화는 목록 컨트롤의 중요한 요소입니다. UI 가상화를 데이터 가상화와 혼동해서는 안 됩니다. UI 가상화의 경우 표시 가능한 항목만 메모리에 저장되지만 데이터 바인딩 시나리오에서는 전체 데이터 구조가 메모리에 저장됩니다. 반면 데이터 가상화의 경우 화면에 표시되는 데이터 항목만 메모리에 저장됩니다.
기본적으로 UI 가상화는 ListView 및 ListBox 컨트롤의 목록 항목이 데이터에 바인딩될 때 해당 컨트롤에 대해 사용할 수 있도록 설정됩니다. TreeView 가상화는 VirtualizingStackPanel.IsVirtualizing 연결된 속성을 true
로 설정하여 활성화할 수 있습니다. ItemsControl에서 파생된 사용자 지정 컨트롤 또는 StackPanel 클래스(예: ComboBox)를 사용하는 기존 항목 컨트롤에 대해 UI 가상화를 활성화하려면 ItemsPanel을 VirtualizingStackPanel로 설정하고 IsVirtualizing을 true
로 설정하면 됩니다. 그러나 자신도 모르게 이러한 컨트롤의 UI 가상화 기능이 해제될 수 있습니다. UI 가상화는 다음과 같은 경우에 해제됩니다.
항목 컨테이너는 ItemsControl에 직접 추가됩니다. 예를 들어 애플리케이션이 ListBoxItem 개체를 ListBox에 명시적으로 추가하는 경우 ListBox는 ListBoxItem 개체를 가상화하지 않습니다.
ItemsControl의 항목 컨테이너는 형식이 다릅니다. 예를 들어, Separator 개체를 사용하는 Menu는 항목 재활용을 구현할 수 없습니다. Menu에 Separator 및 MenuItem 형식의 개체가 포함되어 있기 때문입니다.
CanContentScroll를
false
로 설정합니다.CanContentScroll를
false
로 설정합니다.
항목 컨테이너를 가상화할 때 항목에 속한 항목 컨테이너와 관련된 추가 상태 정보가 있는지 여부를 고려해야 합니다. 이 경우 추가 상태를 저장해야 합니다. 예를 들어 Expander 컨트롤에 항목이 포함되어 있고 IsExpanded 상태가 항목 자체가 아니라 항목의 컨테이너에 바인딩되어 있을 수 있습니다. 새 항목에 대해 컨테이너를 재사용하면 IsExpanded의 현재 값이 새 항목에 사용됩니다. 또한 이전 항목은 올바른 IsExpanded 값을 잃게 됩니다.
현재 모든 WPF 컨트롤은 데이터 가상화를 기본적으로 지원하지 않습니다.
컨테이너 재활용
.NET Framework 3.5 SP1에서는 ItemsControl에서 상속받는 컨트롤에 대해 사용할 수 있는 UI 가상화에 컨테이너 재활용이라는 기능이 추가되었으며 이를 통해서도 스크롤 성능을 높일 수 있습니다. UI 가상화를 사용하는 ItemsControl이 채워지면 스크롤하여 표시되는 각 항목의 항목 컨테이너가 만들어지고, 스크롤하여 더 이상 표시되지 않는 각 항목의 항목 컨테이너는 소멸됩니다. 컨테이너 재활용을 사용하면 컨트롤이 서로 다른 데이터 항목에 기존 항목 컨테이너를 재사용하기 때문에 사용자가 ItemsControl을 스크롤할 때 항목 컨테이너가 만들어지고 소멸되는 과정이 반복되지 않습니다. VirtualizationMode 연결된 속성을 Recycling으로 설정하여 항목 재활용을 활성화하도록 선택할 수 있습니다.
가상화를 지원하는 모든 ItemsControl에 컨테이너 재활용 기능을 사용할 수 있습니다. ListBox에서 컨테이너 재활용을 활성화하는 방법의 예는 ListBox의 스크롤 성능 개선을 참조하세요.
양방향 가상화 지원
VirtualizingStackPanel은 기본적으로 UI 가상화가 가로 또는 세로 중 한 방향으로 지원됩니다. 컨트롤에 양방향 가상화를 사용하려면 VirtualizingStackPanel 클래스를 확장하는 사용자 지정 패널을 구현해야 합니다. VirtualizingStackPanel 클래스는 OnViewportSizeChanged, LineUp, PageUp 및 MouseWheelUp과 같은 가상 메서드를 노출합니다. 이러한 가상 메서드를 사용하면 목록의 보이는 부분에서 변경 사항을 감지하고 그에 따라 처리할 수 있습니다.
템플릿 최적화
시각적 트리에는 애플리케이션의 모든 시각적 요소가 포함됩니다. 여기에는 직접 만든 개체뿐만 아니라 템플릿 확장에 따른 개체도 포함됩니다. 예를 들어, Button을 만들면 시각적 트리에서 ClassicBorderDecorator 및 ContentPresenter 개체도 가져옵니다. 컨트롤 템플릿을 최적화하지 않으면 시각적 트리에 수많은 불필요한 개체가 만들어질 수 있습니다. 시각적 트리에 대한 자세한 내용은 WPF 그래픽 렌더링 개요를 참조하세요.
스크롤 지연
기본적으로 사용자가 스크롤 막대의 위치 조정 컨트롤을 끌면 콘텐츠 뷰가 지속적으로 업데이트됩니다. 컨트롤의 스크롤 속도가 느린 경우에는 스크롤 지연을 사용하는 것이 좋습니다. 스크롤 지연을 사용하면 사용자가 위치 조정 컨트롤을 놓을 때만 콘텐츠가 업데이트됩니다.
스크롤 지연을 구현하려면 IsDeferredScrollingEnabled 속성을 true
로 설정합니다. IsDeferredScrollingEnabled는 연결된 속성이며 ScrollViewer 및 해당 컨트롤 템플릿에 ScrollViewer가 있는 모든 컨트롤에 설정할 수 있습니다.
성능 기능을 구현하는 컨트롤
다음 표에서는 데이터를 표시하는 일반적인 컨트롤 및 각 컨트롤에 성능 기능이 지원되는지 여부를 보여 줍니다. 이러한 기능을 설정하는 방법은 이전 섹션을 참조하세요.
컨트롤 | 가상화 | 컨테이너 재활용 | 스크롤 지연 |
---|---|---|---|
ComboBox | 사용할 수 있음 | 사용할 수 있음 | 사용할 수 있음 |
ContextMenu | 사용할 수 있음 | 사용할 수 있음 | 사용할 수 있음 |
DocumentViewer | 사용할 수 없음 | 사용할 수 없음 | 사용할 수 있음 |
ListBox | 기본값 | 사용할 수 있음 | 사용할 수 있음 |
ListView | 기본값 | 사용할 수 있음 | 사용할 수 있음 |
TreeView | 사용할 수 있음 | 사용할 수 있음 | 사용할 수 있음 |
ToolBar | 사용할 수 없음 | 사용할 수 없음 | 사용할 수 있음 |
참고
TreeView에서 가상화 및 컨테이너 재활용을 사용하는 예제는 TreeView의 성능 개선을 참조하세요.
참고 항목
.NET Desktop feedback