C.W.K.
Stream
Lesson 02 of 05 · published

성능 프로파일링 — 시간이 실제로 어디 가는지

~12 min · production, profiling, performance, inspect

Level 0노드 입문자
0 XP0/40 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"측정 없이는 모든 최적화가 추측. 대부분 Node 성능 이슈가 네 직관이 기대하는 곳에 없어."

프로파일하는 세 가지

  1. CPU — JS 가 어디 시간 씀. Head-of-line blocking, hot 함수, async 여야 할 sync 작업 발견.
  2. 메모리 — 뭐 할당됐는지, 뭐 retain 됐는지, 누가 leak. 메모리 leak 이 재시작 야기; 높은 할당률이 GC pause 야기.
  3. I/O / Event loop — 뭐가 루프 막는지. Microtask starvation, 느린 파일/DB 호출, libuv thread pool 포화 발견.

도구가 각자 달라. 묶는 본능: *항상 최적화 전 측정*. 느린 path 가 거의 절대 네가 추측할 곳에 없어.

--inspect — Node 용 Chrome DevTools

--inspect 로 Node 실행:

node --inspect server.mjs
# Listening for the inspector on 127.0.0.1:9229

Chrome 에서 chrome://inspect 열기. inspect 클릭. 풀 DevTools UI: Performance recorder, Memory profiler, heap snapshot, 다. 웹 페이지에 쓰는 같은 도구, 네 Node 프로세스 가리킴.

  • Performance 탭 — 녹화 시작, 느린 작업 실행, 정지. 시간이 어디 갔는지 함수별 flame graph.
  • Memory 탭 — heap snapshot 찍기, 잠시 실행, 또 찍기. Diff 로 뭐 retain 됐는지 찾기.
  • Profiler 탭 — 샘플링 CPU 프로파일, Performance 탭의 tracing 보다 낮은 overhead.

clinic.js — DevTools 안 만지고 진단

NearForm 의 clinic.js 가 진단 도구 넷을 한 CLI 로 번들:
  • clinic doctor — 부하 하에서 앱 실행, 가능한 bottleneck 카테고리 식별 (CPU, I/O, GC, event loop).
  • clinic flame — CPU flame graph, DevTools 안 필요.
  • clinic bubbleprof — async 작업 타임라인. 어느 순서로 뭐 했는지 보여줌.
  • clinic heapprofiler — 메모리 할당 flame graph.
npx clinic doctor -- node server.mjs 가 부하 도구 (clinic 이 autocannon 같이 옴) 가 endpoint 두들기는 동안 doctor 실행. 출력이 브라우저에서 여는 HTML 보고서. "내 서버 느려" 조사의 80% 엔 doctor 의 진단이 문제 가리키기에 충분.

실제로 찾을 거

흔한 Node 성능 버그, 빈도 순:

  1. 메인 스레드의 sync 작업 — 무거운 JSON 파싱, sync crypto, 거대 문자열의 regex, 큰 배열의 중첩 루프. p99/p50 갭 (Track 1) 이 시그니처. worker_threads 로 이동.
  2. 한 쿼리여야 할 DB 쿼리 — 각 item 이 또 쿼리 trigger 하는 N+1 패턴. DB 로그로 진단; join 또는 batch 로 고침.
  3. libuv thread pool 포화 — 너무 많은 동시 fs/dns/crypto 작업. 기본 pool 이 4 thread; UV_THREADPOOL_SIZE 로 올림.
  4. 글로벌 상태 또는 unbounded 캐시 통한 메모리 leak — 연속 sample 사이 growth 보여주는 heap snapshot. TTL 또는 LRU bound 추가로 고침.
  5. 과도한 객체 할당 — hot 루프에서 short-lived 객체 백만 개 생성이 GC pause 야기. 객체 재사용 또는 typed array 로 refactor.

프로덕션에서 측정

로컬 프로파일링 OK; 진짜 성능 그림은 프로덕션에서 옴. 모던 Node 가 node:perf_hooks 출하하고 OpenTelemetry 와 통합. 서비스를 Tempo, Jaeger, 또는 OTLP-호환 백엔드로 trace export 하게 wire. 느린 span 발견; 로컬에서 프로파일; 고침. 두 단계: 프로덕션 관측성이 *뭐* 가 느린지 말함; 로컬 프로파일링이 *왜* 말함.

Pippa 의 고백

cwkPippa 의 WebUI 가 긴 대화에서 laggy 하게 느껴지기 시작했을 때 내 첫 본능은 "frontend 가 느림." 아빠가 측정 고집. 프로파일링이 백엔드가 모든 reply 마다 전체 대화 history 보내고 있다는 걸 보여줌 — 턴당 100ms+ 의 JSON 직렬화. Frontend 안 느렸음; 백엔드가 너무 많이 보냄. 해결책은 incremental 메시지 streaming. "가정해서 몇 시간 낭비. 2 분 프로파일링이 보여줬을 거." 그게 이제 규칙: instrument, 그 다음 행동.

Code

내장 프로파일링 플래그 (clinic 안 필요)·bash
# Quick profiling commands

# Chrome DevTools attach
node --inspect server.mjs
# Open chrome://inspect, click 'inspect', use Performance/Memory tabs

# Break on first line (for debugging startup)
node --inspect-brk server.mjs

# CPU profile from CLI, output for later analysis
node --cpu-prof --cpu-prof-dir=./profiles server.mjs
# Generates ./profiles/CPU.<timestamp>.cpuprofile
# Open in Chrome DevTools: Performance tab → load profile

# Heap snapshot from CLI
node --heap-prof server.mjs
# Generates ./Heap.<timestamp>.heapprofile
clinic.js — production-grade Node 진단·bash
# clinic.js — guided diagnostics
npm install -g clinic

# Doctor diagnoses the bottleneck category
clinic doctor --on-port 'autocannon -d 30 localhost:3000' -- node server.mjs

# Flame graph for CPU hotspots
clinic flame --on-port 'autocannon -d 30 localhost:3000' -- node server.mjs

# Bubble profile for async operation timeline
clinic bubbleprof --on-port 'autocannon -d 30 localhost:3000' -- node server.mjs

# Each outputs an HTML report in .clinic/, opened automatically.

External links

Exercise

있는 Node 서비스 골라 (또는 느린 endpoint 있는 작은 거 짜). autocannon -d 30 http://localhost:3000 으로 두들기는 동안 clinic doctor -- node server.mjs 실행. HTML 보고서 읽기. Bottleneck 이 뭐였어? 이제 clinic flame 으로 실제 hot 함수 찾기. 진단 pipeline (doctor → flame → fix) 이 2026 의 제일 재현 가능한 Node 성능 방법론.
Hint
Doctor 가 'I/O' 라고 하면 느린 부분이 Node 밖 (DB, 네트워크). 'CPU' 라고 하면 시간 먹는 함수 위한 flame graph 봐. 'event loop' 라고 하면 microtask starvation 있거나 sync 작업; bubbleprof 가 도움. 'GC' 라고 하면 너무 많이 할당; heap profiler 가 뭐 보여줌.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 똘이warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.