• commit transaction?
    • 앱에서 이벤트를 처리하는 과정
      • 이벤트 대기
      • 이벤트가 발생하면(ex. 터치 이벤트) 뷰를 구성하는 프로퍼티에 변화가 일어난다.
        • 디스플레이 요소면 setNeedsDisplay(), 레이아웃 요소면 setNeedsLayout()으로 설정
        • commit phase에서, display가 필요하면 draw를, layout이 필요하면 layoutSubviews()가 호출
    • commit Phase의 4단계
      • layout
        • layoutSubviews가 레이아웃이 필요한 모든 뷰에 대해서 호출됨
        • 어떤 뷰가 레이아웃이 필요한가?
          • 포지션 변경(frame, bounds, transform)
          • 뷰의 추가 및 제거
          • setNeedsLayout을 명시적으로 호출했을 때
      • display
        • 뷰를 다시 그려야 할 때 draw 메소드가 호출됨
        • 어떨 때 추가 되는가?
          • draw(rect:)가 오버라이드 된 뷰를 추가할 때
          • 명시적으로 setNeedsDisplay()를 호출했을 때
      • prepare
        • 이미지 디코딩이 필요하면 수행한다.
          • 큰 이미지에 대해서는 시간이 많이 걸린다.
        • 이미지 포맷을 GPU에 맞게 컨버팅한다. 이 과정에서 이미지가 카피된다. (Images and Graphics Best Practices - WWDC 18)
      • commit
        • 뷰 계층을 재귀적으로 패키징한다.
          • 뷰계층이 복잡하면 패키징 시간이 늘어난다.
        • 렌더링 서버로 전송한다.
  • Instrument에 Animation Hitches 템플릿 추가
    • Time Profiler가 포함되어 있어서 hitcher가 일어나 코드를 확인할 수 있다.
    • Hitch: 일어난 hitch와 그 시간
    • User event: hitch가 발생한 이벤트
    • 커밋, 렌더링에 걸린 시간 확인 가능
    • VSync 간격 확인 가능
    • Hitch Type으로 힌트를 얻을 수 있다.
  • 추천
    • 뷰를 가볍게 하라
      • CALayer의 기본 제공 프로퍼티들을 최대한 활용하라
      • 필요하지 않으면 draw(rect:) 메소드를 오버라이드 하지 말라
      • 뷰를 최대한 재사용하라. 뷰를 추가/제거하는 작업은 비싼 작업이다.
        • 대신 hidden을 최대한 활용하다.
    • 비싸거나 중복된 레이아웃 작업을 줄여라
      • layoutIfNeeded()대신 setNeedsLayout()을 활용하라
        • layoutIfNeeded는 현재의 트랜잭션 시간을 늘려서 hitch를 발생시킬 위험이 있다.
        • 최소한의 constraint만 사용하라
        • 뷰는 자기 자신이나 자식뷰만 invalidate 시키라. 형제나 부모뷰를 invalidate 시키는 것은 비싼 작업이다.
          • 부모뷰를 invalidate 시키면, 자기 자신이 다시 invalidate될 수 있기 때문이다.
    • 특히 재사용 셀을 주의할 것