SniffMEET. 프로필 이미지 다운샘플링과 썸네일 분리하기

개요 사용자가 고해상도 사진을 그대로 업로드하면, 앱에서는 훨씬 작은 크기로만 이미지를 표시하는데도 원본 이미지를 계속 전송하고 저장하게 된다. SniffMeet에서도 프로필 이미지는 홈 화면의 프로필 카드나 메이트 리스트의 작은 썸네일로 표시되는 경우가 대부분이었다. 그런데 원본 이미지를 그대로 업로드하고, 목록에서도 같은 이미지를 다시 내려받고 있었다. 불필요한 네트워크 사용량과 메모리 사용을 줄이기 위해 두 가지를 적용했다. 업로드 전에 프로필 이미지를 앱에서 필요한 크기로 다운샘플링한다. 메이트 리스트에서는 원본 프로필 이미지가 아니라 별도의 썸네일 이미지를 내려받는다. 다운샘플링 기준 정하기 이미지를 어느 크기까지 줄일지 먼저 정해야 했다. 기준은 앱에서 프로필 이미지가 가장 크게 표시되는 홈 화면의 프로필 카드로 잡았다. ...

January 17, 2025

SniffMEET. OSSignposter로 앱 내부 작업 구간 측정하기

들어가며 성능 개선을 하려면 먼저 어떤 작업이 얼마나 걸리는지 볼 수 있어야 한다. CPU 사용량만 보면 어느 시점에 부하가 생겼는지는 알 수 있지만, 앱 내부의 어떤 작업이 그 구간에 실행됐는지는 바로 드러나지 않는다. 그래서 Instruments에서 앱 내부 작업 구간을 이름으로 확인할 수 있도록 OSSignposter를 래핑해보기로 했다. 어디에 붙일까? 처음에는 측정용 타입을 따로 만들지, 기존 SNMLogger에 붙일지 고민했다. private static let logger: Logger = Logger( subsystem: "SniffMeet", category: "SNMLogger" ) 별도의 SNMBenchMarker 같은 타입을 만들 수도 있었지만, 이미 프로젝트에 로그 시스템이 있었기 때문에 기존 SNMLogger에 통합하는 쪽을 선택했다. ...

January 14, 2025

SniffMEET. Instruments로 성능 개선 후보 찾기

들어가며 성능 개선이 필요해 보이는 지점을 감으로 고르지 않기 위해, 먼저 SniffMeet의 주요 흐름에서 CPU와 네트워크 사용량을 훑어봤다. 이 측정만으로 병목 원인을 확정할 수는 없다. 다만 어떤 화면과 기능을 먼저 의심해야 하는지, 이후 리팩토링 후보를 정하는 기준으로는 충분했다. CPU 사용량 측정 Instruments의 Time Profiler로 주요 사용자 흐름을 따라가며 CPU 사용량이 튀는 구간을 확인했다. 측정 중 비교적 사용량이 높았던 지점은 다음과 같았다. 시점 동작 관찰 0:26 프로필 입력 뷰 로드 CPU 70% 0:53 텍스트 필드 입력 CPU 70% 1:44 사진, 닉네임 입력 뷰 로드 CPU 70% 2:08 포토피커 CPU 90% 3:00 등록 완료 버튼 터치 CPU 100%, 약 0.7초 유지 3:28 메이트 리스트 뷰 로드 CPU 50% 3:41 산책 요청 보내기 터치 CPU 80% 4:10 지도 로드 CPU 95% 5:05 요청 보내기 CPU 100%, 약 0.2초 6:36 MPC 연결 CPU 100%, 약 1.2초 특히 회원가입 완료 버튼을 눌렀을 때와 MPC 연결 시점이 눈에 띄었다. 회원가입 완료 시점에는 메인 스레드에서만 작업이 몰리는 것처럼 보였고, MPC 연결 시점에는 MultipeerConnectivity 관련 스레드가 지속적으로 동작했다. ...

January 7, 2025