- 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:) 메소드를 오버라이드 하지 말라
- 뷰를 최대한 재사용하라. 뷰를 추가/제거하는 작업은 비싼 작업이다.
- 비싸거나 중복된 레이아웃 작업을 줄여라
- layoutIfNeeded()대신 setNeedsLayout()을 활용하라
- layoutIfNeeded는 현재의 트랜잭션 시간을 늘려서 hitch를 발생시킬 위험이 있다.
- 최소한의 constraint만 사용하라
- 뷰는 자기 자신이나 자식뷰만 invalidate 시키라. 형제나 부모뷰를 invalidate 시키는 것은 비싼 작업이다.
- 부모뷰를 invalidate 시키면, 자기 자신이 다시 invalidate될 수 있기 때문이다.
- 특히 재사용 셀을 주의할 것