메모리 누수 찾기
앱을 오래 쓰면 느려지는 이유가 메모리 누수였다. Chrome DevTools Memory 탭으로 범인을 찾는 과정을 정리했다.

개발과 기술에 대한 이야기를 기록합니다.
앱을 오래 쓰면 느려지는 이유가 메모리 누수였다. Chrome DevTools Memory 탭으로 범인을 찾는 과정을 정리했다.

배포 후 '잘 되는데요?' 했는데 사용자만 에러를 겪고 있었다. Sentry 도입 후 에러를 실시간으로 잡게 된 이야기.
빨간 에러 메시지가 뜨면 당황해서 그냥 구글에 복붙했는데, 스택 트레이스를 읽는 법을 알고 나니 디버깅 속도가 10배 빨라졌다.

React 앱이 느린 이유를 찾지 못해 코드만 뒤지고 있었는데, React DevTools의 Profiler와 Components 탭이 범인을 바로 찾아줬다.

API 응답이 이상한데 코드 문제인지 서버 문제인지 구분이 안 될 때, 브라우저 네트워크 탭 하나로 원인을 찾는 방법.

console.log 100개 찍어가며 디버깅하던 시절을 끝내고, 브라우저 debugger와 breakpoint로 효율적으로 버그를 잡는 방법.

검색창에 글자 하나 칠 때마다 API 콜이 날아가고, 스크롤할 때마다 이벤트가 폭주하는 문제를 디바운스와 스로틀로 해결한 이야기.

복잡한 페이지 깊숙이 있는 컴포넌트를 수정할 때마다 로그인을 다시 하고 클릭을 5번 해야 하나요? Storybook으로 컴포넌트를 격리(Isolation)해서 개발하는 CDD 방법론.

컴포넌트 하나에서 에러가 났는데 전체 페이지가 흰색이 됩니다. `react-error-boundary`로 에러를 격리하고, 우아한 폴백 UI를 보여주는 방법.

TypeScript만 믿고 있다가 런타임 에러로 앱이 터졌습니다. 컴파일 타임이 아닌 '런타임'에 데이터를 검증해야 하는 이유와 Zod 활용법.

`useEffect`와 `useState`로 범벅된 비대해진 컴포넌트. Custom Hook으로 로직을 분리하여 UI와 비즈니스 로직을 깔끔하게 나누는 실제 리팩토링 가이드.

기능 추가할 때마다 늘어나는 번들 사이즈, 그대로 두면 사용자는 떠납니다. Code Splitting, Tree Shaking, Dynamic Import로 JS 다이어트하는 실제 기법.

습관적으로 모든 변수에 `useMemo`를 감싸고 있나요? 그게 오히려 성능을 망치고 있습니다. 메모이제이션 비용과 올바른 최적화 타이밍.

API 요청 상태를 관리할 때 불리언 플래그 여러 개를 쓰시나요? 'impossible state(불가능한 상태)'를 방지하고, if 문 도배를 없애는 Discriminated Unions 패턴.

전역 상태 관리를 위해 Redux 대신 Context API를 선택했습니다. 하지만 `UserContext`에 모든 정보를 담자마자 앱 전체가 리렌더링되기 시작했습니다. Context 분리(Splitting) 전략.

멋진 히어로 이미지를 `<img>` 태그로 넣었더니 LCP 점수가 빨간색입니다. Next.js의 `Image` 컴포넌트가 어떻게 이미지 사이즈, 포맷, 로딩 시점을 자동 최적화하는지, 그리고 `sizes` 속성의 비밀을 파헤쳐봤습니다.

`window.addEventListener('scroll')`로 무한 스크롤을 구현하면 성능이 박살 납니다. Intersection Observer API로 리팩토링하여 CPU 사용량을 90% 줄이는 방법.

TypeScript를 배우다 보면 만나는 `Function<T>`. 외계어 같던 제네릭을 '투명 스티커'와 '자판기' 비유로 완벽하게 이해하고, `any`와의 차이점을 정리해봤습니다.

빨간 줄을 없애려고 습관적으로 `as unknown as Type`을 쓰시나요? `as`가 사실 컴파일러의 눈을 가리는 행위인 이유와 Type Guard를 통한 올바른 해결법.

`npm install`을 했는데 모듈을 못 찾는다고 합니다. 로컬에선 되는데 CI에서만 터지는 이유와 `package.json`의 `exports`, 그리고 TypeScript 설정까지 완벽 분석.
