행 추적하기
안녕하세요. 그린입니다 🍏
이번 포스팅에서는 Xcode와 디바이스를 이용해 행을 추적하는 방법에 대해 학습해보겠습니다 🙋🏻
누구나 개발 중 행이 걸린다 즉, 버벅이는 현상을 마주할때가 있습니다.
언제 어느 코드에서 이런 성능적으로 행이 걸리는지 추적을 해서 해결해야할 경우가 많죠 🥲
WWDC 2022의 Track down hangs with Xcode and on-device detection 섹션에서 Xcode와 디바이스를 통해 이 행을 추적하는 방법에 대해 자세히 설명해주고 있습니다.
그래서 해당 섹션을 같이 학습해봐요 😃
Track down hangs with Xcode and on-device detection
What are hangs
가장 먼저 알아볼것은 행이 무엇인가? 입니다.
행이라는것은 응답이 없는 순간을 의미합니다.
우리는 어떤 화면을 들어가서 다양한 사진을 서버로부터 불러와서 나타낼 수 도 있는데, 이때도 뷰를 그리기 위해 메인 스레드가 차단되어 사용자의 인터랙션 등을 받을 수 없고 화면이 멈춘것처럼 어떠한 이벤트도 우리가 실행할 수 없을때가 있죠.
그럴때가 우리는 행이 걸렸다고 말할 수 있습니다.
탭을 통해 뷰를 업데이트하기 위해 메인 스레드가 차단이 되기에 발생하는데, 이때 걸리는것이 행입니다.
물론, 당연히 이 행들은 걸릴 수 밖에 없는데 오래 걸려있다면 앱이 정상적인 동작을 한다고 느껴지지 않고 멈췄구나~ 생각이 들 수 있죠.
그렇기에 앱의 응답성을 높이는것은 사용자로 하여금 긍정적인 사용 경험을 높이는데 중요합니다 😀
그래서 우리는 앱의 행이 오래걸린다면 어디서 어떻게 행이 얼마나 걸리는지 추적하고 개선하는것이 중요합니다!
혹시 이 행에 대해 더 이해하고 제거하는 방법에 대해서는 WWDC 21에서 소개된 아래 섹션을 보시는걸 추천드립니다 🙋🏻
앱 개발 과정은 크게 3단계로 나눠집니다.
Xcode를 이용해 앱을 개발하는 Development 단계
그리고 개발된 앱을 TestFlight와 같이 베타 테스트를 해보는 Beta 단계
마지막으로, 실제 앱 스토어에 출시하여 사용자들이 사용을 할 수 있는 Public release 단계
아무리 잘 개발을 했어도, 당연히 릴리즈 배포가 된 앱에서도 이 행에 대해서 문제를 겪을 수 있어요.
그렇기에 각 단계들에서 문제를 추적하고 해결할 장치들을 두는것이 좋을거에요.
Xcode 14이전엔 행을 발견하고 진단하는 툴을 두가지 제공했습니다.
MetricKit이라는 Beta와 Public release에서 사용자에게서 발생한 집계되지 않은 행 메트릭과 진단 보고서 수집을 지원하는 프레임워크가 있습니다.
또, Xcode Metrics Organizer을 이용해 Public release 단계에서 사용자에게 집계된 행 메트릭을 제공해줄 수 있습니다.
그런데 이 툴들은 허점이 존재합니다 🥲
개발중인 앱이나 출시된 앱의 어떤 소스 코드가 행을 일으키는지 파악하기가 힘들죠.
그래서 Xcode 14부터는 도움이 되는 새로운 툴 몇개를 소개합니다 🙋🏻
각 단계에서 적절한 툴들이 존재해요.
Development 단계에선 스레드 성능 검사를 통해 앱을 디버깅하는 동안 능동적으로 추적하지 않고도 행을 일으키는 스레드 문제를 알려줍니다.
또한, Instruments에서는 행 탐지기를 통해 행을 감지하고 표시해줍니다.
Beta때는 Xcode를 사용하지 않거나 추적하지 않을때도 기기에서의 행 탐지기를 통해 실시간 행 알림과 진단을 해줄 수 있습니다.
Public release 단계에선 Xcode Reports Organizer를 통해 실제 사용자로부터 집계된 행 정보들의 리포트를 제공해줍니다.
이제 행이라는것에 대해 자세히 알아봤고 어떤 단계들에서 일어날 수 있는지 등도 학습해봤으니 본격적으로 각 단계에서 행을 추적하고 다루는지 자세히 알아볼께요 🙋🏻
Development tooling
먼저 개발 단계에서 알아봅니다.
Xcode 14의 새로운 스레드 성능 검사는 Xcode Issue Navigator에서 행이 걸릴만한 메인 스레드의 Non-UI 작업이나 우선순위가 역전되는 작업을 감지해서 알려줍니다.
예시로 이렇게 우선순위가 역전되는 작업을 감지한다면 알려줍니다.
우선순위가 높은 작업이 우선순위가 낮은 작업하고 동기화를 시도해서 행이 걸릴 수 있다고 알려주는것이죠.
앱의 메인 스레드에서 우선순위 역전과 Non-UI 작업을 탐지하려면 아래와 같이 Thread Performance Checker를 활성화해주면 됩니다.
이렇게 스레드 성능 검사를 통해 어디서 행이 발생하는지를 알 수 있습니다.
이제 더 나아가, 행이 걸린 시간에 다른 스레드가 뭘 했는지를 다른 툴을 이용해 알아볼 수 있습니다 😁
바로 Instrument죠.
Instrument의 Time Profiler는 콜 스택을 제공하면서 앱의 각 스레드가 시간에 따라 뭘 하고 있는지 알 수 있어요.
Profile로 앱 실행 후 Time Profiler를 선택해줍니다.
그리고 앱을 동작시켜보면, 아래와 같이 행이 걸린것을 직관적으로 확인할 수 있어요.
좀 더 자세히 살펴보면, 메인 스레드에서 많이 잡아먹는게 아니라, 다른 스레드의 동작을 메인 스레드가 기다리는 우선순위 역전이 일어난거죠.
이걸 통해 어떤 작업이 어떻게 문제가 되었는지 파악하고 해결할 수 있는 밑거름이 되는것입니다.
이것 외에도 CPU Profiler를 이용할 수도 있습니다 😀
Beta tooling
이제는 베타 앱 환경에서 행 현상을 탐지해보는 방법을 알아볼께요.
개발이 완료되고 이제 앱을 TestFlight를 통해 개인들의 기기에 다운했어요.
이제 많은 개발자 및 테스터들이 실제로 해당 앱을 상용 출시하기전에 테스트 해보겠죠?
근데, Xcode가 연결되있지 않은 상황에서 어떻게 행을 추적할 수 있을까요?
iOS 16부터는 개발자 설정에서 기기 내 행 감지 기능을 도입했습니다 🔥
만약 행이 걸리는 현상이 발생하면 요렇게 상단에 행이 걸린 시간 알림이 표시됩니다.
더 자세히 알아보기 위해선 진단 정보를 확인해봐야겠죠?
앱이 개발자용으로 설정되어 있으면, 설정 > 개발자 > 행 감지 기능을 활성화 해줘야합니다.
여기서 아래 Hang Threadhold는 행을 감지할 기준값을 정해줍니다.
즉, 250ms로 설정되있으면 250ms보다 낮게 행이 걸리면 무시하고 그 이상만 비정상적인 행으로 감지한다는것이죠.
해당 수치는 각자 앱에서의 상황에 맞게 설정해줘야 하겠죠?
그 다음 앱이 설치되면 모니터링 되는 앱 목록에 나타납니다.
그리고, 아래 지금까지 감지한 비정상적인 행 항목을 시간 순으로 기록하여 목록으로 나타냅니다.
그런데 이런 진단 자체는 백그라운드에서 낮은 우선순위로 처리되기에, 늦게 나타날수도 있습니다.
해당 목록에서 항목을 들어가면 더 자세한 정보를 볼 수 있어요.
행 현상에 대한 구체적인 정보가 들어있죠.
(Tailspin 파일 포함)
물론 더 자세히 조사하려면 Instrument에서 Tailspin을 이용해 프로세스 내 스레드의 상호 작용을 보거나 시스템 리소스 사용을 구별하는 등의 활동을 할 수 있습니다.
이런식으로 문자 기반 형식의 정보들을 볼 수 있어요.
Public release tooling
마지막으로 이제 상용 배포된 앱 단계에서 행을 추적하는 방법을 알아봅니다.
Xcode 14부터는 Xcode Organizer에서 Hang reports를 지원해 사용자들의 기기로부터 비정상 행 진단을 집계해 전달받을 수 있습니다 😄
물론, 앱 분석 공유에 동의한 사용자로부터 한해 행 현상에 대한 메인 스레드 스택의 추적 정보가 제공되죠.
Xcode Organizer에서 Hang 리포트 부분에서 유사한 스택 추적들이 그룹으로 묶여 나타납니다.
해당 스택에서 행 로그의 몇가지 샘플들을 볼 수 있어요.
각 로그엔 메인 스레드 스택의 추적 정보가 들어있습니다.
그 외에도 행 지속 시간, 기기 및 OS 정보, OS 별 집계 통계 등 다양한 정보가 담겨있습니다.
특히 좋은점은 어떤 메서드에서 행이 일어났는지 메서드 정보를 보여줍니다.
훨씬 행 원인을 추적하기 쉽겠죠?
다른 방법으로는 App Store connect의 API를 이용해 동일한 행 리포트 데이터를 검색할 수도 있습니다.
더 자세히 알아보고 싶다면, WWDC 20에서 소개된 Identify trends with the Power and Performance API 세션을 살펴보면 좋습니다.
Xcode Organizer를 더 편리하게 활용하려면 앱 스토어 제출 시 심볼 정보를 같이 제출하는것이 좋습니다.
심볼 정보가 있으면 앱의 함수 이름이 Xcode Organizer 보고서에 추가됩니다.
그럼 추적 자체가 쉬워지겠죠?
이제 개발 초기 단계부터 행을 진단하고 이상이 있으면 수정하는 자세가 필요합니다.
Instruments를 적극 활용해보면 좋을것 같아요.
또한, 베타 테스트때도 기기를 활용해 행 탐지를 활성화시켜 더욱 보완을 해봅니다.
마지막으로 릴리즈 시 Xcode Organizer를 활용해 어떤 행 문제가 있었는지도 지속적으로 파악하는것이 좋습니다.
마무리
쉽게 행을 추적하고 수정해볼 수 있을것 같아요.
괜히 까다롭고 어렵겠지 했었는데, 이제 단순 앱 개발을 넘어 성능까지도 세세하게 더 신경써야겠다고 반성합니다 🥲
다음 포스팅에선 더 나아가 WWDC 23 세션을 보면서 Instruments로 행 분석하는 자세한 영상으로 돌아오겠습니다!