본문 바로가기

성능 프로파일링

Chrome Performance 기록과 Lighthouse 지표로 CPU·렌더링·네트워크 병목을 측정하고 개선 전후를 비교합니다.

앞 절에서는 브라우저 개발자 도구 기반 고급 디버깅으로 논리 오류를 식별/해결하는 방법을 학습했습니다.

이제는 코드 정확성을 확인하고, 문제 발생 시 원인을 추적해 해결할 수 있는 기반을 갖춘 상태입니다.

하지만 코드가 정확하게 동작하는 것만큼 중요한 것이 얼마나 효율적으로 동작하는가입니다.

웹 애플리케이션의 성능은 사용자 경험에 직접적인 영향을 미칩니다.

느린 로딩 시간, 버벅이는 스크롤, 반응 없는 UI는 사용자를 실망시키고 이탈하게 만듭니다.

반대로 빠르고 매끄러운 웹 애플리케이션은 사용자 만족도를 높이고, 더 많은 참여를 유도합니다.

성능 프로파일링(Performance Profiling)은 웹 애플리케이션의 성능 병목(Bottleneck) 지점을 식별하고 최적화하기 위한 과정입니다.

이는 애플리케이션이 실행되는 동안 CPU 사용량, 네트워크 활동, 메모리 사용량, 렌더링 과정 등을 상세히 분석하여, 어떤 부분이 성능 저하를 일으키는지 정확히 찾아내는 것을 목표로 합니다.

이번 장에서는 크롬(Chrome) 개발자 도구의 Performance 탭과 Lighthouse를 중심으로 성능을 측정/분석하고 최적화 방안을 도출하는 방법을 정리합니다.

동일 조건 성능 조사 루프

PROCESS · B99 WEB FUNDAMENTALS

동일 조건 성능 조사 루프

고정된 사용자 시나리오를 기록하고 network·script·layout·paint 비용을 분리한 뒤 한 변경씩 재측정한다. LCP·INP·CLS는 서로 다른 사용자 경험과 병목을 가리킨다.

동일 조건 성능 조사 루프fix a scenario and conditions, capture a trace, isolate the dominant cost, change one cause, and compare the same run 1. 기준 고정입력 · 환경 · 기대 결과2. 증거 수집trace · network · CPU 비용3. 한 원인 변경가장 작은 수정 단위4. 같은 조건 검증전후 비교 · 회귀 확인같은 조건에서 반복 측정 · 기능 회귀도 확인
동일 조건 성능 조사 루프fix a scenario and conditions, capture a trace, isolate the dominant cost, change one cause, and compare the same run. 모바일에서도 같은 노드와 분기·귀환을 세로로 배치한다. 1. 기준 고정 입력 · 환경 · 기대 결과 2. 증거 수집 trace · network · CPU 비용 3. 한 원인 변경 가장 작은 수정 단위 4. 같은 조건 검증 전후 비교 · 회귀 확인 같은 조건에서 반복 측정 · 기능 회귀도 확인

URL·데이터·기기·CPU/네트워크 제한·캐시 조건을 기록하고 같은 시나리오를 반복 측정한다. 한 번의 실행 차이를 바로 개선 효과로 단정하지 않는다.


왜 성능 최적화가 중요한가?

  • 사용자 경험 개선: 빠른 반응 속도는 사용자 만족도를 높이고 이탈률을 줄입니다.
  • 검색 엔진 최적화 (SEO): Google은 Core Web Vitals를 검색 순위 시스템에서 활용하지만, 좋은 지표만으로 높은 순위를 보장하지는 않습니다. 콘텐츠의 관련성과 다른 신호도 함께 작용합니다(Google 안내).
  • 전환율 증가: 이커머스 등에서는 성능 개선이 직접적으로 매출 증가로 이어질 수 있습니다.
  • 에너지 효율성: 불필요한 자원 소모를 줄여 사용자 기기의 배터리 소모를 줄입니다.
  • 접근성 향상: 저사양 기기나 네트워크 환경이 좋지 않은 사용자도 원활하게 애플리케이션을 이용할 수 있게 합니다.

크롬 개발자 도구의 Performance 탭 활용

Performance 탭은 웹 페이지의 런타임 성능을 상세하게 분석할 수 있는 가장 강력한 도구 중 하나입니다.

페이지 로딩부터 사용자 상호작용까지, 모든 활동을 기록하고 시각화하여 병목 지점을 찾을 수 있습니다.

성능 기록 (Recording) 시작 및 분석

개발자 도구 열기: 웹 페이지에서 F12 또는 Ctrl+Shift+I (macOS: Cmd+Option+I)를 눌러 개발자 도구를 엽니다.

Performance 탭 선택: 탭 목록에서 Performance를 선택합니다.

기록 시작: 원형의 Record 버튼을 클릭하거나 Ctrl+E (macOS: Cmd+E)를 눌러 기록을 시작합니다.

시나리오 수행: 기록이 시작되면 웹 페이지에서 성능을 측정하고 싶은 사용자 시나리오(예: 페이지 로딩, 스크롤, 버튼 클릭, 애니메이션 등)를 수행합니다.

기록 중지: 시나리오가 끝나면 Stop 버튼을 다시 클릭하여 기록을 중지합니다.

결과 분석: 기록이 중지되면 상세한 성능 분석 결과가 표시됩니다.

Performance 탭의 주요 패널

기록이 완료되면 다양한 정보를 담은 패널들이 나타납니다.

  • Overview (개요)
    • 상단의 개요와 각 트랙에서 CPU 활동, 네트워크 요청, 프레임을 시간순으로 확인합니다. 표시 위치와 색상은 도구 버전에 따라 달라질 수 있습니다.
    • Frames와 FPS: 프레임의 소요 시간과 놓친 프레임을 확인합니다. 60Hz 화면의 프레임 간격은 약 1000 / 60 = 16.7ms, 120Hz는 약 8.3ms입니다. 이 시간에는 브라우저의 스타일·레이아웃·페인트 작업도 들어가므로 전부 JavaScript에 쓸 수 있는 예산은 아닙니다.
    • CPU 활동: Scripting, Rendering, Painting 등의 범례와 이벤트 이름을 함께 읽습니다. 함수 호출에 붙는 색상만으로 작업 종류나 병목을 단정하지 않습니다.
    • NET: 네트워크 요청 활동을 보여줍니다.
    • 타임라인에서 특정 영역을 드래그하여 해당 구간의 상세 정보만 확대하여 볼 수 있습니다.
  • Summary (요약)
    • 선택된 타임라인 구간의 각 이벤트 카테고리(Loading, Scripting, Rendering, Painting 등)에 소요된 총 시간을 원형 차트와 목록으로 보여줍니다.
    • 여기서 가장 많은 시간을 차지하는 부분이 주요 병목 지점일 가능성이 높습니다.
  • Main (메인 스레드)
    • 가장 중요한 패널 중 하나입니다. 메인 스레드에서 발생한 모든 활동(JavaScript 실행, 스타일 계산, 레이아웃, 페인팅 등)이 시간순으로 계층 구조로 표시됩니다.
    • Flame Chart (불꽃 차트): 각 함수 호출을 불꽃처럼 시각화하여, 어떤 함수가 얼마나 많은 시간을 소모했는지 직관적으로 보여줍니다. 가로 폭은 실행 시간, 세로의 중첩은 호출 관계를 나타냅니다. 높이만으로 느린 작업이라고 판단하지 않습니다.
    • 특정 활동(예: (anonymous) 함수, update layout)을 클릭하면 하단의 Summary 탭에 해당 활동의 상세 정보와 호출 스택(Call Stack)이 표시되어, 어떤 코드에서 이 활동이 발생했는지 추적할 수 있습니다.
    • Long Tasks (오랜 작업): 메인 스레드의 한 작업이 50ms를 넘으면 긴 작업입니다. Chrome은 빨간 삼각형과 50ms 초과 구간의 음영으로 표시합니다. 긴 작업은 입력과 렌더링을 지연시킬 수 있지만, 긴 작업이 없다는 사실만으로 매 프레임의 예산을 지켰다고 판정할 수는 없습니다.
  • Bottom-Up (상향식), Call Tree (호출 트리), Event Log (이벤트 로그)

    • Bottom-Up: 선택 구간에서 같은 활동의 시간을 합산합니다. Self Time은 해당 활동 자체, Total Time은 자식 활동까지 포함한 시간이며 각 열로 정렬할 수 있습니다.
    • Call Tree: 호출 스택을 보여주어 어떤 함수가 어떤 함수를 호출했는지 계층적으로 파악할 수 있습니다.
    • Event Log: 발생한 모든 이벤트를 시간순으로 나열합니다.

프레임·긴 작업·Self Time의 판독 기준은 Chrome Performance 공식 문서를 참고합니다. 같은 함수의 자식 비용을 Total Time과 다시 더하면 시간을 중복 집계할 수 있으므로 비교할 열을 먼저 정합니다.

성능 최적화의 일반적인 접근 방식

Performance 탭 분석을 통해 얻은 정보로 다음과 같은 최적화 작업을 고려할 수 있습니다.

  • 불필요한 JavaScript 실행 줄이기: Long Tasks를 유발하는 JS 코드를 최적화하거나, 웹 워커를 사용하여 백그라운드로 분리합니다.
  • DOM 조작 비용 줄이기: 변경한 속성과 읽기·쓰기 순서에 따라 스타일 계산·레이아웃 비용이 달라집니다. 불필요한 변경과 강제 레이아웃을 줄이고 관련 작업을 묶습니다. 가상 DOM을 사용하더라도 계산·렌더 범위를 확인해야 하며 성능이 자동으로 좋아지는 것은 아닙니다.
  • CSS 최적화: 복잡한 CSS 선택자나 불필요한 re-layout(reflow)을 유발하는 속성 사용을 지양합니다.
  • 이미지 최적화: 표시 크기에 맞는 이미지를 사용합니다. 화면 아래의 이미지는 지연 로딩을 고려하되, 첫 화면의 LCP 후보 이미지를 지연 로딩하면 주요 콘텐츠 표시가 늦어질 수 있습니다(LCP 최적화 안내).
  • 네트워크 비용 줄이기: 번들링과 캐싱으로 반복 요청·전송을 줄일 수 있습니다. 코드 스플리팅은 초기 전송·파싱 비용을 줄이는 대신 분리된 코드를 추가 요청할 수 있으므로, 요청 수와 초기 로딩 비용을 나누어 확인합니다.
  • 애니메이션 최적화: transform과 opacity는 레이아웃·페인트를 줄이는 합성 후보입니다. 속성만으로 GPU 가속이나 더 빠른 실행을 보장하지 않으므로 실제 비용을 확인합니다. requestAnimationFrame으로 갱신을 브라우저의 렌더링 주기에 맞출 수 있습니다.
Core Web Vitals 원인 진단 지도

FLOWCHART · B99 WEB FUNDAMENTALS

Core Web Vitals 원인 진단 지도

저하된 지표가 LCP·INP·CLS 중 무엇인지 먼저 구분한 뒤, 각 지표에 맞는 network·main-thread·rendering·stability 증거를 확인한다.

Core Web Vitals 원인 진단 지도저하된 LCP, INP, CLS를 각각 network와 render delay, main-thread interaction, layout stability 증거로 라우팅하고 같은 시나리오에서 재측정하는 진단 지도 현장·실험실에서 저하 확인같은 URL · 기기 · 시나리오 기록어떤 사용자 경험이나빠졌는가?주 콘텐츠가 늦게 보임LCP · LOADlargest element timing입력 뒤 paint가 늦음INP · INTERACTinteraction latency예상치 못한 위치 이동CLS · STABILITYlayout shift scoreWaterfallLCP breakdownTTFB · resource loadrender delayInteraction · long taskhandler · main threadlayout / paintLayout Shifts track크기 없는 mediafont · 삽입 DOM원인 하나 변경 → 같은 시나리오 재측정lab 개선을 field data와 함께 확인LCPINPCLS
Core Web Vitals 원인 진단 지도저하된 LCP, INP, CLS를 각각 network와 render delay, main-thread interaction, layout stability 증거로 라우팅하고 같은 시나리오에서 재측정하는 진단 지도. 모바일에서도 같은 노드와 분기·귀환을 세로로 배치한다. 현장·실험실에서 저하 확인 같은 URL · 기기 · 시나리오 기록 어떤 사용자 경험이 나빠졌는가? 주 콘텐츠가 늦게 보임 LCP · LOAD largest element timing Waterfall LCP breakdown TTFB · resource load render delay 입력 뒤 paint가 늦음 INP · INTERACT interaction latency Interaction · long task handler · main thread layout / paint 예상치 못한 위치 이동 CLS · STABILITY layout shift score Layout Shifts track 크기 없는 media font · 삽입 DOM 원인 하나 변경 → 같은 시나리오 재측정 lab 개선을 field data와 함께 확인 LCP INP CLS

Core Web Vitals는 LCP·INP·CLS다. 일반 Lighthouse 로딩 감사에는 사용자 상호작용이 없어 INP를 직접 측정하지 못한다. 상호작용 trace로 원인을 재현하고 현장 데이터로 실제 방문의 개선을 확인한다.


Lighthouse 활용: 웹 성능 측정 자동화

Lighthouse는 Google에서 개발한 오픈소스 자동화 도구로, 웹 페이지의 품질(성능, 접근성, 권장사항, SEO)을 감사(Audit)하고 개선 방안을 제시하는 도구입니다.

개발자 도구 내에서 또는 Node.js CLI로 실행할 수 있습니다.

Lighthouse 실행 및 보고서 분석

개발자 도구 열기: 웹 페이지에서 F12 또는 Ctrl+Shift+I (macOS: Cmd+Option+I)를 눌러 개발자 도구를 엽니다.

Lighthouse 탭 선택: 탭 목록에서 Lighthouse를 선택합니다.

Audit 카테고리 선택: Performance, Accessibility, Best Practices, SEO 중 측정할 카테고리를 선택합니다. PWA 카테고리는 Lighthouse 12에서 제거되었습니다.

기기 선택: Desktop 또는 Mobile 환경을 선택합니다.

(실제 대상 사용자의 기기를 기준으로 선택하고, 모드·CPU/네트워크 제한·캐시 조건·도구 버전을 기록합니다. Mobile 결과와 Desktop 결과를 서로의 개선 전후 값으로 비교하지 않습니다.)

설정 확인 뒤 감사 시작: 페이지 로드 모드에서 기기·카테고리·CPU/네트워크 제한 설정을 확인한 뒤 실제 감사 시작 버튼을 누릅니다. 공식 안내의 흐름은 Analyze page load로 설정 화면을 열고 Run audit로 실행하는 순서입니다. Chrome 버전·모드에 따라 버튼 이름이나 설정 화면은 달라질 수 있으므로, 현재 화면에서 설정을 여는 단계와 실행하는 단계를 구분합니다. 실행 시간은 페이지와 측정 환경에 따라 달라집니다.

결과 보고서 확인: 감사가 완료되면 각 카테고리별 점수와 상세한 개선 제안 목록이 표시됩니다.

Lighthouse 성능 지표

Lighthouse의 실험실 로딩 지표와 Core Web Vitals를 구분해서 읽습니다. 현재 Core Web Vitals는 LCP·INP·CLS이며, 아래 목록의 모든 항목이 이에 속하는 것은 아닙니다.

  • FCP (First Contentful Paint): 페이지에서 처음으로 텍스트나 이미지가 렌더링되는 시점. (사용자가 콘텐츠를 보기 시작하는 시점)
  • LCP (Largest Contentful Paint): 뷰포트 내 가장 큰 콘텐츠 요소(이미지, 동영상, 텍스트 블록 등)가 렌더링되는 시점. (사용자가 페이지의 주 콘텐츠를 인식하는 시점)
  • CLS (Cumulative Layout Shift): 페이지 이용 중 예상치 못한 레이아웃 이동 점수를 세션 창별로 합산한 최댓값. 로딩 이후 이동도 포함합니다. (시각적 안정성)
  • INP (Interaction to Next Paint): 페이지를 방문하는 동안 발생한 클릭, 탭, 키보드 입력의 응답 지연을 관찰해 대표 반응 시간을 측정합니다. 200ms 이하가 좋은 상태입니다.
  • TTI (Time to Interactive): 과거 상호작용 가능 시점을 추정하던 지표이며 Lighthouse 10에서 제거되었습니다. 현재 보고서 항목으로 기대하지 않습니다.
  • Speed Index: 페이지의 콘텐츠가 시각적으로 얼마나 빨리 채워지는지 측정.

Lighthouse의 개선 제안에서 지표에 영향을 미치는 문제를 확인합니다. 기존 Opportunities·Diagnostics 중심 구성은 최신 버전에서 Insights 중심으로 바뀌었으므로 사용하는 버전의 보고서 구조를 따릅니다. 일반적인 페이지 로드 감사는 사용자 상호작용을 수행하지 않으므로 실제 방문의 INP를 직접 측정하지 않습니다. INP는 현장 데이터와 재현한 상호작용의 Performance 기록을 함께 확인합니다.

현장 Core Web Vitals의 좋은 기준은 LCP 2.5초 이하, INP 200ms 이하, CLS 0.1 이하입니다. 모바일과 데스크톱을 나누어 실제 방문의 75백분위 값이 세 기준을 모두 충족하는지 봅니다. 한 번 실행한 Lighthouse 점수나 한 번의 클릭 시간은 이 현장 판정을 대신하지 않습니다(Web Vitals 기준).

예를 들어, 이미지 크기 적절하게 조정, 렌더링 차단 리소스 제거, JS 실행 시간 단축 등의 제안을 따르는 것이 좋습니다.

성능 개선은 한 번 측정하고 끝내기보다 같은 시나리오로 전후를 비교하는 반복 작업에 가깝습니다.

측정 모드와 기기·네트워크 조건을 기록해 전후 비교 기준을 유지합니다.

변경 효과를 수치와 동작으로 함께 판정하기

다음 값은 계산 연습을 위한 가상 측정값이며 이 사이트를 측정한 결과가 아닙니다. 같은 URL·브라우저·모바일 모드·CPU/네트워크 제한·빈 캐시 조건에서, 상품 목록의 첫 로딩을 각각 세 번 기록했다고 가정합니다.

비교 항목변경 전 3회변경 후 3회중앙값 비교
LCP(ms)2800, 3000, 29002300, 2400, 25002900 → 2400
최대 메인 스레드 작업(ms)120, 110, 13045, 48, 47120 → 47

LCP 중앙값은 500ms, 약 17.2% 줄었습니다. 변경 후에도 이미지가 올바르게 표시되는지, 상품 수·정렬·버튼 동작이 같은지 확인해야 합니다. 최대 작업이 47ms로 줄어 긴 작업 기준을 넘지 않게 되었더라도 60Hz의 한 프레임 간격 16.7ms보다 길기 때문에 스크롤이 매끄럽다는 결론은 따로 검증해야 합니다. 기록의 가장 느린 한 번만 골라 비교하지 말고 반복값과 편차도 남깁니다.

// 브라우저 Console 또는 Node.js에서 실행하는 계산 예제
function median3(values) {
    return [...values].sort((a, b) => a - b)[1];
}

const before = median3([2800, 3000, 2900]);
const after = median3([2300, 2400, 2500]);
console.log(before, after, before - after); // 2900 2400 500

직접 판정할 문제: 같은 조건의 로딩 기록에서 메인 스레드 작업이 40ms, 70ms, 120ms였습니다. 각 작업의 50ms 초과분과 그 합은 얼마인가요? 이 합만으로 실제 방문의 INP가 200ms 이하라고 판정할 수 있을까요?

풀이 확인

초과분은 max(0, 작업 시간 - 50)이므로 각각 0ms, 20ms, 70ms, 합은 90ms입니다. 이는 주어진 작업의 초과분 계산이며 Lighthouse의 TBT 값이라고 부르려면 해당 도구의 집계 구간과 대상 작업 조건까지 맞아야 합니다. INP에는 입력이 처리되기까지의 대기, 이벤트 처리, 다음 화면 표시까지의 지연이 포함됩니다. 로딩 작업의 합만으로 사용자 상호작용의 INP를 판정할 수 없으며 실제 입력 시나리오와 현장 데이터를 확인해야 합니다(TBT 정의, INP 정의).


성능 프로파일링 정리

마지막 점검에서는 측정 지표를 고정한 상태에서 병목 후보를 하나씩 줄여 나가는 절차를 권장합니다.

이번 장에서는 웹 애플리케이션의 속도와 효율성을 최적화하기 위한 필수적인 과정인 성능 프로파일링(Performance Profiling)에 대해 심도 있게 학습했습니다.

이번 절에서는 Performance 탭으로 JavaScript 실행, 렌더링, 네트워크 활동을 기록하고 Flame Chart와 Long Task를 기준으로 병목을 찾는 방법을 정리했습니다.

Lighthouse와 Core Web Vitals는 자동 진단 결과와 사용자 경험 지표를 함께 확인하는 보조 도구입니다.

성능 프로파일링은 개발 주기 동안 반복해야 하며, 측정 결과를 기준으로 병목을 하나씩 개선해야 합니다.

개선 전후의 수치를 함께 기록해야 실제 효과를 확인할 수 있습니다.

성능 문제는 지표와 증거를 함께 확인하고, 측정 결과가 구체적인 수정과 재검증으로 이어지도록 정리해야 합니다.

성능 프로파일링은 느리다는 느낌을 로딩, 스크립트 실행, 렌더링, 상호작용 지연 같은 측정 가능한 구간으로 바꾸는 과정입니다.