WPF프로젝트를 지난 5년간 진행하면서 덩치가 너무 커진탓인지
속도가 너무 늦다는 지적을 현장에서 받아오면서, 이 문제를 어떻게 처리할까... 한참을 고민하던끝에 다음달 릴리즈를 앞둔 마당에 이 글을 적어봅니다.

초기 표시 (렌더링) 속도개선방법
여기에서는 초기 표시, 즉 화면을 인스턴스화해서 그려 질 때까지의 시간을 단축하기위한 개선책과
화면을 다시그릴때의 처리시간 단축방법을 이야기 하고자 합니다.

1. 컨트롤의 재배치 처리횟수를 줄이자
  WPF 는 기본적으로 화면의 각 요소는 상대적 좌표 크기를 결정합니다.
  컨트롤의 "HorizontalAlignment"또는 "Width"에 "Auto"를 설정할 수있는 것이 그 증거입니다.
  이렇게함으로써 사용자가 화면 크기를 변경하거나 해상도가 다른 디스플레이에서도
  화면의 표시내용을 담아내는것을 제작하는 것이 가능하게되어 있습니다.

  그러나 이때의 배치 구조는 Xaml 부모 요소에서 자식 요소에 여러 번 왕래하고 크기를 조정하고
  최종 렌더링된다는 것입니다.
  이 재배치 처리에 시간이 걸리면 당연히 표시 할 때까지의 시간도 늦어집니다.

  이 문제를 해결하려면 다음 방법을 검토하십시오.

크기를 고정한다.
  ⇒Width / Height는 고정값으로 합니다.
부모 패널을 Canvas 한다.
  ⇒ 절대 좌표로 지정하여 그리기 좌표를 재계산하지 않아도됩니다.
문자 혹은 도형을 코드로 렌더링한다.
  ⇒ Xaml 대신 코드 측에서 직접 그리는 방법입니다.
   자세한 내용은 코드로 문자 나 도형을 그리기를 참조하십시오.

2. 자신 컨트롤을 UserControl에서 사용자 지정 컨트롤로 변경한다.
  WPF 에서 컨트롤을 만드는 방법은 주로 다음 두 가지입니다.
  (1) UserControl에서 컨트롤을 복합적으로 사용한다.
  (2) 사용자 지정 컨트롤 모양과 구조를 직접 구현한다.
    (또는 기존의 컨트롤을 상속 기능을 추가한다.)

  기본적인것이지만, 컨트롤 클래스는 파생 할 정도로 기능이 증가 · 복잡화하고
  재배치 처리에 시간이 걸릴 수 있습니다.
  UserControl은 Window와 마찬가지로 View를 가지고 있기 때문에 재배치 처리에 시간이 걸립니다. 
  UserControl의 수가 증가할수록 내부의 요소가 복잡할수록 그것은 눈에 띄게됩니다.

  이를 방지하려면 사용자 정의 컨트롤을 구현하십시오.
  사용자 정의 컨트롤을 구현하는 프로젝트는 Visual Studio 에 포함되어 있습니다.
  (프로젝트의 추가 메뉴에서 " WPF 사용자 정의 컨트롤 라이브러리"라는 항목이 있습니다.)
  일반 프로젝트에 사용자 지정 컨트롤을 추가하지 않도록 주의합시다.

3. 의존관계 속성을 정확히 사용한다.
  의존관계 속성은 데이터 바인딩을 사용하는 구조에서
  사용자 컨트롤의 속성은 기본적으로 이를 구현합니다.
  일반적 속성도 처음에만 데이터 바인딩은 작동하지만,
  이후의 속성 값의 변화에 대응할 수 없습니다.
  또한 일반적인 속성은 런타임에 데이터 바인딩을 사용할 때,
  리플렉션을 이용하고 있기 때문에 의존관계 속성보다 속도가 느립니다.

4. 렌더링 속도를 향상시킬 수있는 속성
  사용자 컨트롤의 기본 클래스 "Control"또는 "FrameworkElement"에는
  값을 설정하여 렌더링 속도를 향상시킬 수있는 몇 가지 속성이 존재합니다.
  Xaml 의 상대적인 레이아웃 설정의 장점을 없애는 것도 있지만,
  다음의 속성을 설정하는 것을 고려하십시오.

· IsHitTestVisible (기본값 : false)
   true로 설정하면 컨트롤을 수행 할 수 없습니다.
   마우스 오버와 클릭 등의 작업을 일체행하지 않습니다.
   조작이 불필요한 컨트롤에 이것을 설정하여 불필요한 이벤트가 발생하지 않고,
   속도의 향상을 기대할 수 있습니다.

· ClipToBounds (기본값 : false)
   true로 설정하면 컨트롤의 자식 요소가 자신의 그리기 범위를 벗어난 영역에 그려지지 않습니다.
   그리기 영역이 한정되기 때문에, 동작 속도의 향상을 기대할 수 있습니다.
   그러나 재배치 작업이 발생하는 점에 주의하십시오.

· Width / Height (기본값 : Auto)
   고정 값으로 설정하면 재배치 처리 횟수를 줄일 수 있습니다.
   마찬가지로 "MaxWidth", "MinWidth", "MaxHeight", "MinHeight"도 고정 값으로 설정하는 것을 권장합니다.

UserControl 전반적으로 위의 문제를 다시한번 생각하고 재배치하여, 
기존 3초정도의 렌더링완료가 되었던 화면이 1초만에 완료되도록 개선되었기에 
정보를 정리해두도록 합니다.

+ Recent posts