PROFILE BEFORE OPTIMIZE

TypeScript 런타임 병목 분리

TypeScript로 작성했다는 사실만으로 앱이 느려지지는 않는다. 느린 원인은 대개 React 렌더, 네트워크 waterfall, 큰 번들, CPU long task, heap 증가 중 하나이며, profiler와 전후 수치로 원인을 분리해야 한다.

01

증상 정의

초기 로드, 클릭 반응, 스크롤, 입력, API 응답 중 어디가 느린지 먼저 나눈다.

증상 없는 최적화는 방향이 흐리다
02

렌더 측정

React Profiler로 어떤 컴포넌트가 왜 다시 렌더링되는지 확인한다.

memo는 측정 뒤에 적용한다
03

CPU 분석

Performance 패널에서 long task, scripting time, layout 비용을 본다.

타입은 빌드 후 사라지고 JS 실행이 남는다
04

메모리 추적

heap snapshot과 allocation timeline으로 이벤트 리스너, 캐시, 전역 참조 누수를 찾는다.

닫은 화면의 객체가 남는지 본다
05

네트워크 비교

waterfall에서 중복 요청, 큰 payload, 캐시 미스, 직렬 요청을 분리한다.

빠른 코드도 느린 네트워크에 묶일 수 있다
Profiler
렌더 비용 컴포넌트별 commit 시간과 rerender 원인을 본다.
props identity를 확인한다
Performance
메인 스레드 비용 long task, layout, paint, script 시간을 시간축으로 본다.
입력 지연과 연결한다
Heap
메모리 증가 스냅샷 비교로 해제되어야 할 객체가 남는지 본다.
전역 store와 listener를 의심한다
Network
요청 병목 payload 크기, 캐시, waterfall 순서, compression을 확인한다.
API 병목과 프론트 병목을 나눈다

개선 확인

전후 수치 수정 전후 같은 시나리오에서 렌더 시간이나 long task가 줄었는지 확인한다.
회귀 memoization이나 lazy load가 기존 동작과 접근성을 깨지 않았는지 본다.
원인 분리 네트워크 지연과 JS 실행 지연을 같은 문제로 묶지 않았는지 확인한다.