signpost로 분석하고 스크롤 부드럽게 만들기
iOS에서 부드러운 스크롤은 항상 달성하려고 노력해야 하는 성능 목표 중 하나이다. 그렇지만 달성하기 어려운 목표이기도 하다. 어려운 많은 이유 중 하나는 어디가 느리게 만드는지 파악하기 어렵다는 것이다.
그런데 올해 WWDC에는 유독 성능 관련된 세션이 많았다. 그 중에서도 Session 405 Measuring Performance Using Logging에서 소개한 signpost는 병목 지점을 찾아낼 수 있는 간단하면서 강력한 툴이다.
가장 중요한 성능 목표 중 하나인 부드러운 스크롤을 달성하기 위해서 signpost로 어디서 많은 시간이 걸리는지 알아보고 개선해보려고 한다. 샘플로 사용할 소스 코드는 사진 라이브러리에 있는 라이브포토를 보여주고 자동으로 재생하는 앱이다.
소스 코드: https://github.com/jongwonwoo/CodeSamples/tree/master/Performance/signposts
signpost를 사용하는 방법 중 하나는 측정하고 싶은 구간의 시작과 끝에 os_signpost(.begin)과 os_signpost(.end)를 추가하는 것이다.
라이브포토를 보여주는 셀을 만드는 데 얼마나 많은 시간이 걸리는지 알아내기 위해서 os_signpost(.begin)을 cellForItemAt 함수의 시작 부분에 추가하고, os_signpost(.end)는 라이브포토를 읽어들여서 셀에 표시하는 부분에 추가했다. os_signpost(.end)가 삽입된 곳은 비동기 콜백이기 때문에 os_signpost(.begin)과 짝을 맞춰주기 위해서 signpostId를 맞춰주었다. OSLog()의 subsystem, category와 os_signpost()의 name은 잠시 후 살펴볼 Instruments에서 잘 정리된 측정값을 만드는데 사용된다.
이제 Xcode에서 Product 메뉴의 Profile을 선택한다. 그리고 “Blank” 템플릿을 선택하고, “Add” 버튼을 눌러서 os_signpost를 선택한다. “Record” 버튼을 누르면 앱이 실행되고 스크롤을 하면 하늘색 그래프가 그려지기 시작한다.
configure cell 아래로 각 셀의 indexPath를 표시하고 소요 시간을 보여준다. 그리고 configure cell 행을 보면 사진 하나를 셀에 그리는데 평균 48.05 ms가 걸린다는 것을 알 수 있다. 60 FPS를 달성하기 위해서 주어진 시간은 16 ms인 것을 생각하면 셀 하나를 그리는데 너무 오래 걸리고 있다. 이제 원인을 찾기 위해서 소스 코드의 어느 부분을 좀 더 깊이 파고 들어야 하는지 알게 됐다.
사진을 불러올 때 고화질로 가져오도록 되어 있었다. 사실 스크롤하는 동안은 사진이 휘리릭 지나가기 때문에 굳이 고화질로 가져올 필요가 없다. 그래서 저화질로 가져오도록 수정하고 다시 측정해 보았다.
이제 평균 5.21 ms가 걸린다. 43 ms 정도 줄였고, 16 ms 이내에 완료됐다.
그런데 처음 2개 셀은 23.78 ms, 16.54 ms가 걸렸다. signpost를 이용하면 원인을 찾을 수 있을 것이다.