당신의 코드가 느린 이유:
프론트엔드 성능 최적화 전략
서다미 프론트엔드 엔지니어 | 강사

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

1

특강 목차

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

2

1교시
Lighthouse 제대로 활용하기
성능 최적화의 비즈니스 가치와 정확한 측정 환경 세팅법

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

3

1교시: Lighthouse 제대로 활용하기
왜 우리는
'웹 성능 엔지니어'가 되어야 할까?
건물이 무너지기 전에 미리 금 간 곳을 찾아 보수하는 정기 검진과 같습니다.
핵심 성능 지표
  • Retention (유지율): 고객이 우리 서비스에 계속 머무르는 힘.
  • Bounce Rate (이탈률): 로딩이 3초만 늦어도 사용자 50%는 '뒤로 가기'를 누릅니다.
  • SEO (검색 엔진 최적화): 구글은 '빠른 사이트'를 맨 위에 보여줍니다.
기업 통계 사례
  • Google: 로딩 속도가 0.4초 늦어지면 검색량이 25% 감소합니다.
  • Amazon: 로딩이 0.1초 지연될 때마다 매출이 1%씩 줄어듭니다.
  • Pinterest: 로딩 시간을 40% 단축했더니 가입자 수가 15% 증가했습니다.

성능은 기술적 만족이 아니라, 비즈니스 매출과 직결됩니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

4

1교시: Lighthouse 제대로 활용하기
정확한 측정을 위한
'실험실' 세팅
왜 이렇게 세팅해야 할까?
시크릿 모드 사용: 내가 설치한 확장 프로그램(광고 차단 등)이 성능 점수 측정 결과에 왜곡을 유발하는 요소를 방지합니다.
Mobile 기기 기준: 저사양 환경에서 진짜 병목 현상이 가장 잘 드러나기 때문입니다.
성능 제한(Throttling): 모든 사용자가 최신형 컴퓨터를 쓰지 않습니다. 고의로 속도를 늦춰 사용자 체감 성능 저하를 시뮬레이션합니다.
따라 하기 (Step-by-Step)
  1. 크롬 우측 상단 ⋮
    클릭 → [새 시크릿 창] 열기
  1. 내 프로젝트 주소 접속 후
    F12(개발자 도구) 실행
  1. 상단 탭에서 [Lighthouse] 선택
  1. 설정값 확인:
  • Mode: Navigation
  • Device: Mobile
  • Categories: Performance 체크

정확한 성능 진단이 올바른 솔루션을 만듭니다. 반드시 시크릿 모드 + Mobile 세팅을 확인하세요!

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

5

1교시: Lighthouse 제대로 활용하기
리포트 분석법 :
점수보다 중요한 '개선 방안'
"Lighthouse 리포트는 우리 앱의 '성능 진단 보고서'와 같습니다"
어떻게 분석해야 할까?
  1. Metrics (지표): 위험 신호가 있는 지표의 이름을 확인합니다. (예: LCP)
  1. Insights (통찰): 성능을 향상시키기 위해 '무엇을' 해야 하는지 라이트하우스가 제안하는 핵심 요약입니다. (구 Opportunities)
  1. Diagnostics (진단): 우리 코드의 '병목 지점'이 어디인지 구체적인 기술적 근거를 보여줍니다.
  1. Passed Audits: 이미 잘 최적화된 항목들입니다. (여기 있는 항목은 추가적인 개입이 필요하지 않습니다!)
* Largest Contentful Paint: 페이지 내에서 주요 콘텐츠가 렌더링되는 시각입니다. 이 수치가 길어지면 사용자 경험 저하를 초래합니다.

점수는 결과일 뿐입니다. 성능 개선은 하단의 '인사이트(Insights)' 섹션의 분석부터 시작됩니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

6

1교시: Lighthouse 제대로 활용하기
분석의 핵심:
원인 역추적하기
어떻게 내 코드와 연결할까?
지표 식별: "LCP 점수가 왜 낮지?" 하고 보니, 옆에 LCP 태그가 붙은 Render blocking requests가 원인 요소로 지목됨.
원인 연결: INSIGHTS 섹션의 해당 항목을 클릭하여 상세 내용을 펼칩니다.
데이터 확인: 클릭하니 Google Fonts1,000ms 동안 로딩되며
화면을 막고 있는 것을 발견!

*LCP(Largest Contentful Paint): 페이지 내에서 가장 큰 콘텐츠가 렌더링되는 시각입니다.

리포트는 '무엇이 느린지'를 알려주고, 코드는 '왜 느린지'를 알려줍니다. 둘을 연결하는 것이 진짜 디버깅입니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

7

1교시: Lighthouse 제대로 활용하기
[가이드]
이런 문구가 뜨면 '관련 코드'를 확인하세요!

리포트 문구를 암기할 필요는 없습니다. '특정 지표가 발생하면 해당 코드 요소를 파악한다'는 연관성 이해가 목표입니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

8

2교시
웹 성능 지표(CWV)의 내부 동작 원리
LCP, CLS, INP의 성능 저하를 유발하는 실제 코드 사례와 해결 원리

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

9

2교시: 웹 성능 지표(CWV)의 이면
지표와 코드의 연관성
🎯 2교시 목표: 성능 진단 및 최적화
1
지표의 본질 이해: 단순 암기가 아닌 브라우저 내부 동작 원리로 이해하기
2
원인 요소(성능 병목) 코드 식별: 리포트 점수를 저하시키는 '병목 지점 코드' 찾기
3
DevTools 활용: 데이터(Network, Performance 탭) 기반 문제 분석
4
검증된 최적화 적용: 개선 후 초록색 점수(90점+) 달성.

Core Web Vitals는 단순한 숫자가 아닙니다. 우리가 작성한 코드의 '성능 평가'이자 '개선 방안'을 제시하는 가이드입니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

10

2교시: 웹 성능 지표(CWV)의 내부 동작 원리
Core Web Vitals(CWV)
웹 성능의 핵심 지표
사용자가 느끼는 '좋은 웹사이트'의 3가지 조건
Core Web Vitals: 구글이 웹 페이지의 사용자 경험을 측정하기 위해 선정한 가장 핵심적인 3가지 지표입니다.
"단순히 로딩이 빠른 것이 아니라, 보고(LCP), 누르고(INP), 레이아웃 이동이 없는(CLS) 쾌적함을 목표로 합니다."

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

11

2교시: 웹 성능 지표(CWV)의 이면
LCP의 주요 원인: 대용량 이미지와 렌더링 지연 폰트 ①
📸 데이터 기반 현상 분석
Waterfall 캡처
Lighthouse LCP 섹션
🔍 원리 이해
브라우저는 HTML을 읽다가 폰트를 만나면 '해당 리소스가 모두 로드될 때까지 텍스트 렌더링을 보류할게'라고 동작합니다. 이것이 바로 렌더 블로킹(Render Blocking)입니다.
💼 현업 포인트
이미지를 WebP로 최적화하고 Preload를 적용하는 것만으로도 LCP 점수는 1~2초 단축됩니다. 이는 효율성이 높은 최적화 방안입니다.
🔴 문제: @import 폰트 + 비최적화 이미지 → 렌더 블로킹 발생
🟢 해결: &display=swap + WebP preload → LCP 1~2초 단축

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

12

2교시: 웹 성능 지표(CWV)의 이면
LCP의 주요 원인:
대용량 이미지와 렌더링 지연 폰트 ②
페이지에서 가장 큰 이미지나 텍스트가 화면에 나타나는 시점입니다.
핵심 원인: 배송(Network)이 너무 늦거나, 다른 파일이 길을 막고(Blocking) 있을 때 발생합니다.
🔴 나쁜 코드 (원인 요소)
// 1. 무거운 폰트 호출 (차단 발생) @import url( 'https://fonts.googleapis.com/...all-weights' ); // 2. 최적화 없는 이미지 <img src="/huge-hero.png" />
🟢 개선 코드 (Hero)
// 1. 폰트 차단 해제 &display=swap // 2. 이미지 우선순위 상향 및 포맷 변경 <link rel="preload" as="image" href="/hero.webp" /> <img src="/hero.webp" width="1200" height="600" loading="eager" />

LCP를 개선하려면 '무엇이 가장 먼저 보여야 하는가'를 결정하고, 그것의 배송 경로를 최우선으로 열어주면 됩니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

13

2교시: 웹 성능 지표(CWV)의 이면
CLS 원인 요소: 예측 불가능한 레이아웃 이동 콘텐츠 ①
화면 레이아웃 불안정성 식별
🔍 진단 가이드
현상 : 이미지가 지연 로드되면서 하단 콘텐츠의 레이아웃 이동을 유발합니다.
지표: CLS (Cumulative Layout Shift)
레이아웃이 이동하는 정도를 측정한 수치. 0.1 이하가 Good, 0.25 이상은 Poor입니다.
진단 포인트
Lighthouse에서 Layout shift culprits 항목을 클릭해 보세요. 레이아웃 이동을 유발한 이미지 파일이 명시되어 있습니다.

CLS를 방지하려면 이미지에 width와 height 속성을 명시하거나, aspect-ratio CSS를 미리 지정하여 공간을 미리 확보하면 됩니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

14

2교시: 웹 성능 지표(CWV)의 이면
CLS 원인 요소: 레이아웃 이동 콘텐츠 ②
[솔루션]'레이아웃 공간 확보'로 화면 흔들림 방지
🔴 비효율적인 코드 (원인 요소)
// 크기 지정이 없어 로딩 후 화면 레이아웃 불안정 발생 <img src="/ad-banner.png" />
🟢 최적화 코드
// 방법 1: HTML에서 직접 크기 지정 <img src="/ad-banner.png" width="800" height="400" /> // 방법 2: CSS aspect-ratio 사용 (권장) img { aspect-ratio: 16 / 9; width: 100%; }
💡 핵심 개념: '레이아웃 공간 확보 (Aspect Ratio)'
이미지 로드 전에 브라우저에 미리 렌더링 공간을 할당하여, 이미지가 로드된 후에도 주변 요소의 위치 안정성을 유지합니다.
🔴 문제: 크기 미지정 → 이미지 로드 후 레이아웃 불안정 (CLS 증가)
🟢 해결: width/height 또는 aspect-ratio 지정 → 공간 선점 → CLS 0

Layout 단계에서 공간을 미리 확보하면 브라우저는 레이아웃 재계산을 방지합니다. 이것이 CLS를 0으로 만드는 핵심 원리입니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

15

2교시: 웹 성능 지표(CWV)의 이면
INP 문제 요인: 응답 지연 화면 ①
[진단] Main Thread의 과부하 증상 확인
1
현상 (What's happening?)
버튼을 클릭했는데 화면 응답이 지연됩니다. 사용자는 응답 지연이 발생했다고 인지하거나 사이트를 이탈하게 됩니다.
2
지표 (The Metric)
INP (Interaction to Next Paint) — 클릭 후 다음 화면이 렌더링될 때까지의 반응 속도이며, 200ms(0.2초) 이내가 합격 기준입니다.
3
진단 포인트 (문제 요인 식별)
Performance 탭에서 빨간색 빗금으로 표시된 'Long Task'를 찾으세요. Main Thread가 50ms 이상의 고부하 작업을 처리하느라 클릭 이벤트를 처리하지 못하고 있는 구간입니다.

Main Thread는 브라우저의 핵심 처리 스레드입니다. 이 스레드가 고부하 작업에 할당되어 있으면, 사용자의 상호작용은 처리 대기 상태에 놓이게 됩니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

16

2교시: 웹 성능 지표(CWV)의 이면
INP 원인 요소: 클릭 시 응답 지연 화면
[솔루션] 무거운 업무는 '쪼개서' 시키기
🔴 비효율적인 코드 (원인 요소)
// 메인 스레드를 꽉 잡고 놓지 않는 반복문 button.onclick = () => { for (let i = 0; i < 100000000; i++) { // 브라우저를 멈추게 하는 무거운 연산 } };
🟢 최적화 코드 (해결 방안)
// 작업을 쪼개서 메인 스레드에게 쉴 틈 주기 button.onclick = () => { setTimeout(() => { // 비동기로 분리하여 클릭 반응성 확보 }, 0); };
최적화 원리
자바스크립트 엔진은 한 번에 하나의 작업만 수행하는 싱글 스레드입니다.
최적화 전략
거대한 작업 하나를 수행하는 대신, 작은 단위로 쪼개어 실행하면 그 틈새로 브라우저가 사용자의 클릭을 감지할 수 있습니다.

성능 최적화의 핵심은 메인 스레드의 점유 시간을 최소화하는 것입니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

17

2교시: 웹 성능 지표(CWV)의 이면
[요약]
한눈에 보는 성능 정비 지도
"성능은 운이 아니라 설계입니다"
렌더링 파이프라인
지표별 솔루션 요약

이제 여러분은 단순히 숫자를 올리는 사람이 아니라, 브라우저가 동작하는 원리를 이해하고 코드를 개선하는 '성능 전문가'가 될 수 있습니다!

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

18

3교시
브라우저 정밀 진단 (Network & Performance)
네트워크 Waterfall 읽기 및 CPU 병목(Long Task) 지점 탐색

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

19

3교시: 브라우저 정밀 진단 (Network & Performance)
브라우저 심층 분석
"점수 측정은 끝! 이제 실제 성능 저하의 근본 원인을 규명할 시간입니다."
2교시에서 학습한 CWV 지표들을 실제 어떤 진단 도구로 심층 분석할 것인지 소개합니다.
Network 탭
리소스 로딩 경로를 추적합니다. 지연되는 리소스 로드를 폭포수(Waterfall)로 시각화하여 확인합니다.
Performance 탭
메인 스레드의 실행 프로파일을 기록합니다. Long Task 및 렌더링 병목 지점을 시각적으로 식별합니다.
Lighthouse vs DevTools
Lighthouse는 '문제 발생 지점'을 알려주고, DevTools는 '문제의 근본 원인'을 분석하는 정보를 제공합니다.

도구는 수단입니다. 중요한 것은 데이터를 기반으로 '이 리소스가 병목 지점이다'라고 확신할 수 있는 전문적인 통찰력을 기르는 것입니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

20

3교시: 브라우저 정밀 진단 (Network & Performance)
Network 탭: Waterfall 차트 분석 ①
리소스 로딩 순서와 각 단계별 색상 의미를 분석합니다.
개념 (Waterfall 그래프)
모든 리소스는 각자의 '타임라인'을 가집니다. 계단식으로 표현되어 Waterfall 차트라고 불립니다.
지표 (색상별 의미)
  • ⚪️ 연회색(Queuing): 요청 대기 상태
  • 🟠/🟢 주황/녹(TTFB): 서버 응답 시간
  • 🔵 파란색(Content Download): 실제 리소스 다운로드 시간
진단 포인트 (성능 저하 요인)
  • 주황색 바가 길다 → 서버 응답 지연 또는 데이터베이스 부하가 원인 요소!
  • 파란색 바가 길다 → 대용량 이미지/파일 전송 시간이 원인 요소!

Network 탭은 브라우저와 서버 간의 리소스 요청/응답 흐름을 보여줍니다. 리소스 요청 대기 지점, 서버 응답 지연 여부, 그리고 리소스 전송 용량 관련 병목 지점을 여기서 파악할 수 있습니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

21

3교시: 브라우저 정밀 진단 (Network & Performance)
Network탭:
Waterfall 분석 심화 ②
📊 Waterfall 단계별 정의
  • Queuing이 길다 → 동시 연결 수 초과 또는 우선순위 낮음
  • TTFB가 길다서버 응답 지연 (백엔드/CDN 성능 저하)
  • Content Download가 길다과도한 파일 크기 (압축/최적화 필요)
Network탭 Waterfall 예시

Waterfall에서 가장 긴 막대를 찾으세요. 그것이 바로 페이지 로딩을 가장 많이 지연시키는 '병목 리소스'입니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

22

3교시: 브라우저 정밀 진단 (Network & Performance)
Network탭:
병목 지점 식별 ①
성능 저하 지표 (The Evidence)
특정 리소스(이미지 등)가 화면에 표시되기까지 총 2.34초가 소요되었습니다. 이 시간 동안 브라우저는 어떤 상태였을까요?
데이터 분석 (Data Breakdown)
• Waiting (TTFB): 2.18초 — 전체 시간의 약 93% 차지
• Content Download: 0.1초 — 파일 크기는 문제의 원인이 아닙니다.

'느리다'라고만 말하는 개발자와 'TTFB가 2.18초나 소요되어 서버 응답이 병목입니다'라고 말하는 개발자는 전문성에서 큰 차이를 보입니다.
서버가 요청을 처리하기까지 2초 이상 지연된 상황 — 이 수치는 여러분의 성능 문제 진단에 대한 논리적인 근거가 됩니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

23

3교시: 브라우저 정밀 진단 (Network & Performance)
Network탭:
성능 병목 원인 분석 ②
⚖️ 진단 결과 (Analysis Outcome)
2.18초
Waiting (TTFB)
전체 시간의 93% 차지
0.1초
Content Download
파일 용량은 문제 없음
→ 원인 요소는 파일이 아니라 서버 응답 지연 시간입니다.
파일 용량이 과다해서 지연되는 것이 아닙니다. 서버 응답 지연 시간이 3초 이상 발생하고 있습니다.
🔍 주요 성능 분석 관점 3가지
리소스 응답 시간 과다
TTFB 문제 → 서버/DB 최적화 또는 CDN 도입
연쇄적 리소스 로딩 지연
의존성 문제 → 리소스 우선순위 재조정 또는 preload 활용
전송 데이터 용량 과다
파일 크기 문제 → 압축 또는 캐싱 적용

"Waterfall 차트의 종속성 구조는 '한 리소스의 완료가 다음 리소스 시작에 선행된다는' 의존성을 보여줍니다. 이 종속성을 최소화하는 것이 병렬 처리 최적화의 목표입니다."

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

24

3교시: 브라우저 정밀 진단 (Network & Performance)
Performance탭: 브라우저 실행 프로파일 분석
🎬 3단계 분석법
기록 시작 (Recording)
성능 저하가 의심되는 동작(예: 버튼 클릭) 직전에 '녹화' 버튼을 누르고 동작 수행 후 '정지'를 누르면 브라우저의 모든 활동이 타임라인에 기록됩니다.
메인 스레드(Main Thread) 탐색
수많은 행 중에서 'Main'이라고 적힌 행을 찾으세요. 자바스크립트 실행 및 화면 렌더링 등 브라우저의 핵심 작업이 처리되는 곳입니다. → Main 스레드에서 모든 JS가 실행!
빨간색 빗금(Long Task) 식별 🔴
막대기 윗부분에 빨간색 삼각형 빗금이 있다면? 50ms가 넘는 장시간 작업(Long Task)이 사용자 상호작용을 저해하고 있다는 핵심 지표입니다. → INP(Interaction to Next Paint) 저해의 주요 원인!

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

25

3교시: 브라우저 정밀 진단 (Network & Performance)
Performance탭: 브라우저 실행 프로파일 분석
🔗 Main Thread란?
렌더링 파이프라인 제어
HTML → CSS → Layout → Paint 전 과정을 Main Thread가 순서대로 처리합니다. 이 지점에서 병목 현상 발생 시 모든 처리가 중단됩니다.
Long Task = 응답성 저하 🔴
50ms 이상 걸리는 작업이 생기면 Main Thread는 사용자 상호작용 처리에 응답하지 않습니다. 이것이 바로 INP 점수 저하의 주요 원인입니다.
Performance 탭 = 상세 실행 기록 분석 도구
성능 저하(지연) 발생 지점을 시간대별로 정확히 추적할 수 있습니다. 빨간 빗금만 찾으면 문제 진단의 상당 부분을 해결할 수 있습니다.
📊 Main Thread 해석법
💡 Long Task를 클릭하면 어떤 JS 함수가 주요 원인인지 정확히 식별할 수 있습니다.

'Main Thread의 과부하 = 사용자 체감 지연 발생.' 이 핵심 개념을 이해하면 Performance 탭의 모든 데이터를 해석할 수 있습니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

26

3교시: 브라우저 정밀 진단 (Network & Performance)
Performance탭: 함수 단위로 병목 지점 식별
🔍 진단 도구: 3가지 탭
Summary 탭
전체 실행 시간 중 가장 많은 시간을 차지한 작업 유형을 파이 차트로 보여줍니다. 'Scripting'이 크다면 JS가 주요 원인 요소입니다.
Bottom-Up 탭 (추천)
가장 많은 시간을 소비한 함수를 역순으로 보여줍니다. 맨 위에 있는 함수가 가장 주된 원인 요소입니다.
Call Tree 탭
함수 호출 흐름을 트리 구조로 보여줍니다. 어떤 함수가 어떤 함수를 불러서 느려졌는지 추적할 수 있습니다.

Main Thread에 과부하가 발생했을 때, 실제로 작업을 지연시킨 주요 원인 요소를 식별하는 것이 Bottom-Up 탭입니다. '이 함수가 500ms 걸려서 INP가 깨집니다'라고 말할 수 있는 개발자가 협업에서 신뢰를 얻습니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

27

3교시: 브라우저 정밀 진단 (Network & Performance)
Performance탭: 함수 단위로 병목 지점 식별
📋 병목 지점 식별 순서
Long Task 클릭
Performance 타임라인에서 빨간 삼각형이 있는 막대를 클릭합니다.
Bottom-Up 탭 선택
하단 패널에서 Bottom-Up 탭을 클릭합니다. 가장 많은 처리 시간을 소비하는 함수가 맨 위에 표시됩니다.
함수명 확인
함수 이름 옆 파란색 링크(예: main.js:123)를 클릭하면 브라우저가 즉시 Sources 탭으로 이동하여 소스코드의 정확한 파일명과 줄 번호로 이동합니다. → 거기에서 원인 요소를 확인할 수 있습니다!

Bottom-Up 탭의 맨 위 함수 = 주요 성능 저하 요소. 파란 링크 클릭 한 번으로 소스코드 몇 번째 줄인지 바로 확인할 수 있습니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

28

3교시: 브라우저 정밀 진단 (Network & Performance)
Performance탭: 주요 로딩 이벤트 이해하기
🚩 주요 마일스톤 (Flags) 및 브라우저 파싱 지표
FCP (First Contentful Paint)
브라우저가 첫 번째 글자나 이미지를 그리기 시작한 순간입니다. 사용자가 시각적 콘텐츠를 처음 인지하는 시점.
LCP (Largest Contentful Paint)
가장 큰 메인 콘텐츠가 화면에 나타난 최종 로딩 순간입니다. 2.5초 이하가 Good 기준.
DCL (DOMContentLoaded)
HTML 뼈대 구성이 완료된 시점. JS 실행 가능 상태.
L (Onload)
이미지, 스타일시트 등 모든 리소스가 완전히 로드된 시점.
🔍 사용 방법
LCP 마커 위치 확인
타임라인 상단에서 LCP 마커가 기록된 시점을 찾으세요. 이 지점이 사용자가 메인 콘텐츠를 인지한 순간입니다.
LCP 마커 이전 구간 분석
LCP 마커 이전에 어떤 네트워크 요청이나 JS 실행이 집중되어 있는지 확인하세요. 그것이 바로 성능 개선 포인트입니다.
DCL vs L 이벤트 간격 확인
DCL(DOMContentLoaded)과 L(Onload) 이벤트 사이 간격이 크다면? 대용량 이미지나 외부 리소스가 로딩 성능 저하의 주요 원인이 됩니다.
2.5s
LCP 권장 기준
이하면 권장 기준 충족
FCP → LCP
핵심 구간
이 사이를 줄이는 것이 목표

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

29

3교시: 브라우저 정밀 진단 (Network & Performance)
[요약]
진단 도구 활용 체크리스트 ①
🌐 Network 탭 핵심
Waterfall의 '색상' 분석
TTFB(주황/녹색)가 길면 → 서버 응답 지연 문제
Content Download(파란색)가 길면 → 리소스 용량 문제
'종속성' 최적화
리소스가 계단식으로 밀린다면 요청 우선순위(Preload)나 의존성 정비가 필요합니다.
진단 체크리스트
1
TTFB 확인
Network 탭에서 주황/녹색 바가 비정상적으로 긴 리소스를 식별했는가?
2
Waterfall 종속성 확인
리소스들이 병렬로 로딩되고 있는가? 계단식 의존성은 없는가?

진단 도구는 수단입니다. '네트워크 지연 색상 → Waterfall 종속성 → 장기 실행 작업 → 하향식 분석 → 핵심 지표 간 간격' 이 5가지 순서로 분석하면 어떤 앱이든 병목 지점 식별이 가능합니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

30

3교시: 브라우저 정밀 진단 (Network & Performance)
[요약]
진단 도구 활용 체크리스트 ②
Performance 탭 핵심
'빨간색 빗금' 구간을 식별하라
Main 스레드의 Long Task 구간이 사용자 반응(INP)을 저해하는 원인 요소입니다.
'Bottom-Up'으로 병목 지점을 식별하라
Self Time이 높은 함수 → 파일명:줄번호로 소스코드 역추적하세요.
'깃발' 사이의 간격을 단축하라
FCP → LCP 사이 간격을 줄이는 것이 UX 최적화의 핵심입니다.
진단 체크리스트
1
Long Task 구간 확인
Performance 탭에서 빨간 삼각형 빗금 구간을 찾아 클릭했는가?
2
Bottom-Up 병목 지점 식별
Self Time 최상단 함수의 파일명:줄번호를 확인했는가?
3
FCP → LCP 간격 측정
두 깃발 사이 간격이 1초 이내인가? 그 사이 병목 리소스는 없는가?

도구는 수단입니다. '색상 → 계단 → 빨간 빗금 → Bottom-Up → 깃발 간격' 이 5가지 순서로 보면 어떤 앱이든 병목 지점을 식별할 수 있습니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

31

4교시
리액트 정밀 진단 (React Profiler)
재렌더링의 원리 이해 및 프로파일러를 통한 불필요한 렌더링 개선

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

32

4교시: 리액트 정밀 진단 (React Profiler)
[개요]
리액트의 내부 동작 원리를 분석하는 법
3교시 복습
🌐 브라우저 성능 진단
관점: 결과 중심 (Output)
무엇을 분석하는가?
화면이 그려진 뒤(Paint) 얼마나 느리게 동작하는가? Network/Performance 탭으로 측정합니다.
한계
어떤 컴포넌트가 다시 렌더링되었는지는 알 수 없습니다. 결과물만 파악할 뿐, 내부 동작의 불투명성이 존재합니다.
4교시 예고
⚛️ 리액트 정밀 진단
관점: 과정 중심 (Process)
무엇을 분석하는가?
어떤 컴포넌트가 '왜' 다시 렌더링되었는가? 컴포넌트 단위로 렌더링 시간을 추적합니다.
핵심
불필요한 렌더링(Re-render)의 원인 요소를 컴포넌트 단위로 식별합니다. 이것이 INP 개선의 핵심입니다.

브라우저는 사용자 화면의 성능 결과를, 리액트 프로파일러는 컴포넌트 내부 동작 과정을 분석합니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

33

4교시: 리액트 정밀 진단 (React Profiler)
React Profiler 설치 및 준비 ①
⚙️ 3단계 설치 가이드
1. 확장 프로그램 설치
크롬 웹스토어에서 'React Developer Tools'를 검색하여 설치합니다.
2. Profiler 탭 접속
개발자 도구(F12) 실행 후 상단 메뉴에서 [Profiler] 탭을 선택합니다. (Components 탭 옆에 위치)
3. 렌더링 사유 기록 설정 (필수 ⚠️)
Profiler 설정(톱니바퀴 아이콘)에서 "Record why each component rendered while profiling" 항목을 반드시 체크합니다. 이 설정이 활성화되어야 재렌더링의 구체적인 원인을 확인할 수 있습니다.

설치 완료 후 리액트로 만든 페이지에서 F12를 누르면 Components와 Profiler 탭이 새로 생깁니다. 일반 HTML 페이지에서는 나타나지 않습니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

34

4교시: 리액트 정밀 진단 (React Profiler)
React Profiler 설치 및 준비 ②
📸 설정 화면

이 옵션을 활성화하지 않으면 컴포넌트 재렌더링의 구체적인 원인 요소를 파악할 수 없습니다. 반드시 먼저 확인하세요!

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

35

4교시: 리액트 정밀 진단 (React Profiler)
리액트의 핵심: 리렌더링(Re-render) 이해하기
리렌더링이란? 컴포넌트의 상태가 변하여 함수가 다시 호출되고, 가상 DOM을 새로 만드는 과정입니다.
리렌더링을 일으키는 4가지 원인
1. State 변경
컴포넌트 내부의 useState 등이 변했을 때. 가장 기본적인 리렌더링 원인입니다.
2. Props 변경
부모로부터 전달받은 값이 변했을 때. 새로운 값이 내려오면 컴포넌트가 다시 렌더링됩니다.
3. 부모 컴포넌트 렌더링 ⚠️ (가장 중요)
자신의 Props가 변하지 않아도 부모가 리렌더링되면 자식은 무조건 다시 렌더링됩니다. 불필요한 렌더링의 주요 원인 요소!
4. Context/Reducer 변경
구독하고 있는 전역 상태가 변했을 때. 해당 Context를 사용하는 모든 컴포넌트가 리렌더링됩니다.
🎯 최적화의 핵심
화면 변화와 상관없는 3번(부모 영향) 케이스를 식별하고 제어하는 것이 성능 최적화의 첫걸음입니다.
3번
가장 흔한 이슈
부모 렌더링에 의한
불필요한 재렌더링
React.memo
1차 솔루션
Props가 같으면
렌더링을 건너뜁니다
🔴 문제: 부모가 바뀔 때마다 자식 전체가 다시 렌더링됨
🟢 해결: React.memo로 Props 비교 후 불필요한 렌더링 차단

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

36

4교시: 리액트 정밀 진단 (React Profiler)
Flame Graph(플레임 차트)
Profiler 탭 내 Flame Graph 위치 찾기
플레임 차트란? 프로파일링 기간 동안 어떤 컴포넌트가 어떤 순서로, 얼마나 오래 실행되었는지 보여주는 막대그래프입니다.
Profiler 탭 진입
리액트 개발자 도구의 상단 메뉴에서 [Profiler]를 누릅니다.
데이터 기록
왼쪽 상단의 파란색 동그라미(Record)를 누르고 화면에서 동작을 수행한 뒤, 다시 눌러 중지합니다.
차트 선택 — Flame Graph
기록 후 상단에 두 아이콘이 뜹니다. 첫 번째 아이콘(불꽃 모양)이 Flamegraph Chart입니다. (기본 설정)
차트 선택 — Ranked Chart
두 번째 아이콘(막대그래프 모양)은 Ranked Chart입니다. 시간순이 아니라 '오래 걸린 순'으로 정렬해서 보여줍니다.
🔍 Flame Graph 활용 목적
병목 지점 식별
전체 렌더링 시간 중 특정 컴포넌트가 차지하는 비중을 시각적으로 확인합니다.
계층 구조 분석
부모-자식 관계를 유지하며 보여주기 때문에, 어떤 부모 컴포넌트로 인해 하위 컴포넌트들이 불필요하게 리렌더링되는지 한눈에 파악할 수 있습니다.
⏱️ 활용 시점
  • 특정 동작(클릭, 입력 등) 후에 화면 응답 지연이 눈에 띄게 발생할 때
  • 컴포넌트 구조가 복잡하여 렌더링 시작점을 추적하기 어려울 때

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

37

4교시: 리액트 정밀 진단 (React Profiler)
Flame Graph(플레임 차트)분석
위치 확인 및 병목 식별 ①

"Flame Graph에서 가장 넓고 노란 막대를 찾으세요. 그 컴포넌트가 전체 렌더링 시간을 가장 많이 차지하는 '주요 성능 병목 지점'입니다."
📊 Flame Graph 읽는 법
렌더링 안 됨
최적화 성공 신호
렌더링 됨
시간이 길수록 최적화 필요

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

38

4교시: 리액트 정밀 진단 (React Profiler)
Flame Graph(플레임 차트)분석
위치 확인 및 병목 지점 식별 ②
📊 분석 포인트
막대의 길이 (Duration)
가로 길이 = 해당 컴포넌트와 하위 컴포넌트들이 렌더링을 완료하는 데 걸린 총 합산 시간 (Total Time)
막대가 가장 길다고 해서 무조건 최적화
1순위인 것은 아닙니다. (성능 저하의 주요 원인 지점)
막대의 색상 (Heatmap)
🟡 노란색/주황색:
컴포넌트 '자신'이 렌더링하는 데 오래 걸린 성능 저하 구간 (Self Time). 최우선 병목 타겟.
🟢/🔵 초록색/파란색:
효율적으로 처리된 컴포넌트
⚪️ 회색:
이번 시점에 다시 렌더링되지 않은 컴포넌트
계층 구조 (Hierarchy)
막대가 위아래로 쌓인 구조는 부모→자식 렌더링 순서를 나타냅니다.
상위에서 하위로 렌더링이 전파됩니다.
→ 색깔로 병목 지점을 식별하고, 가장 긴 막대(부모)에서 성능 개선을 진행하는 것이 중요합니다!

노란색 막대를 클릭하면 해당 컴포넌트의 '렌더링 원인'이 우측 패널에 표시됩니다.
이것이 앞서 설정한 'Record why each component rendered' 옵션의 결과입니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

39

4교시: 리액트 정밀 진단 (React Profiler)
Flamegraph Chart(플레임 차트)분석
"왜 다시 그려졌나?"- 원인 분석 ①
📋 주요 원인 4가지 (Case Study)
1
Props changed
부모로부터 전달받은 값(객체, 배열, 함수 포함)이 변했을 때. 참조값이 바뀌면 내용이 같아도 변경으로 인식합니다.
2
State changed
컴포넌트 자체의 상태(useState 등)가 업데이트되었을 때. 가장 기본적인 리렌더링 원인입니다.
3
Parent rendered ⚠️ (핵심)
자신은 아무 변화가 없으나, 부모가 렌더링되어 리액트 기본 메커니즘에 의해 함께 다시 그려진 경우. 불필요한 렌더링의 주요 원인 요소!
4
Hook changed
useContext 등 사용 중인 훅의 값이 변했을 때. 구독 중인 전역 상태가 바뀌면 해당 컴포넌트 전체가 리렌더링됩니다.

이제 추측은 끝났습니다. 리액트가 직접 알려주는 '원인'을 읽으세요. 특히 'Parent rendered'라고 적혀 있다면,
그것은 자식 컴포넌트의 문제가 아니라 부모 컴포넌트의 렌더링이 자식에게까지 전파된 상황입니다. 이 병목 지점을 식별하는 것이 4교시의 핵심 목표입니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

40

4교시: 리액트 정밀 진단 (React Profiler)
Flamegraph Chart(플레임 차트)분석
"왜 다시 그려졌나?"- 원인 분석 ②
📸 Why did this render? 화면
🔍 분석 방법: 우측 상세 정보창 확인
Flamegraph Chart에서 분석할 컴포넌트를 클릭하면 우측 사이드바에 상세 데이터가 나타납니다.
[Why did this render?] 섹션에 적힌 텍스트가 리액트가 판단한 재렌더링의 직접적인 이유입니다.

이 메시지를 읽어야 5교시에서 어떤 최적화 기법(memo, useCallback 등)을 적용할지 결정할 수 있습니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

41

4교시: 리액트 정밀 진단 (React Profiler)
[마무리]
리액트 진단 체크리스트
핵심 포인트 : 진단 도구는 수단일 뿐입니다. 중요한 것은 데이터 뒤에 숨겨진 '불필요한 리렌더링 흐름의 패턴을 식별하는 역량'입니다.
01
Flame Graph 분석
노란색/주황색 막대를 찾아 렌더링 병목 지점을 특정합니다.
02
커밋(Commit) 확인
상단 막대그래프를 통해 어떤 시점에 렌더링이 집중되었는지 파악합니다.
03
원인 해석
'Why did this render?' 메시지를 통해 Props, State, 부모 렌더링 중 무엇이 문제인지 확정합니다.
진단 결과 분류
의도된 렌더링 — 화면 변화에 꼭 필요한 경우 (정상)
낭비되는 렌더링 — 데이터 변화가 없는데 부모 등의 영향으로 다시 그려지는 경우

이제 어디가 병목 부분인지 확인은 끝났습니다. 5교시에는 오전 이론을 총정리하고, 실제 코드를 최적화하는 '성능 최적화 실습'을 준비해 봅시다!

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

42

5교시
오전 이론 총정리 및 실습 환경 세팅
핵심 개념 리마인드 및 실습용 '성능 문제 유발 앱' 프로젝트 구동 확인

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

43

5교시: 오전 이론 총정리 및 실습 환경 세팅
[오전 수업 요약]
우리는 무엇을 분석했는가?
1~4교시에서 학습한 파편화된 지식을 '성능 개선의 논리적 흐름'으로 연결해봅시다.
1단계: 성능 문제 식별 (What)
📍핵심: 웹 성능 지표 (CWV)
LCP, CLS, INP 수치를 통해
"성능 저하 지점"을
객관적인 지표로 확인했습니다.
2단계: 원인 분석 (Why)
📍핵심: 브라우저 & 리액트 렌더링 원리
사용자 경험 저하가
코드의 어떤 로직(불필요한 리렌더링 등)에서 발생하는지 이해했습니다.
3단계: 최적화 대상 확정 (Where)
📍핵심: 진단 도구 (Lighthouse, Profiler)
추측이 아닌 데이터를 통해
실제 "개선이 필요한 성능 병목 구간"
(프로파일러의 비효율적인 활동 구간)을 지목했습니다.

성능 최적화는 '직관'이 아니라 '데이터'에 근거한 의사결정의 연속입니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

44

5교시: 오전 이론 총정리 및 실습 환경 세팅
최적화의 3단계 원칙: Measure → Fix → Verify
"측정 없이 고치지 말고, 고친 뒤엔 반드시 증명하라"
Step 1. Measure (측정)
행동: Profiler와 Lighthouse를 사용하여 현재 상태를 기록합니다.
목적: "어디가, 얼마나 느린가?"를 객관적인 수치로 확보합니다.
Step 2. Fix (수정)
행동: 진단 결과에 맞는 최적화 도구(memo, useMemo, useCallback 등)를 적용합니다.
목적: 병목 지점을 제거하고 렌더링 효율을 높입니다.
Step 3. Verify (검증)
행동: 수정 후 다시 측정하여 이전 데이터와 비교합니다.
목적: "실제로 빨라졌는가?"를 증명하고 사이드 이펙트가 없는지 확인합니다.

"If you can't measure it, you can't improve it."
(측정할 수 없으면 개선할 수 없다. — 피터 드러커)

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

45

5교시: 오전 이론 총정리 및 실습 환경 세팅
실습 프로젝트: 병목 구간 분석 및 최적화 대상 식별
🏥 The Heavy List App — 대규모 데이터 렌더링 시 발생하는 성능 저하 케이스
📁 컴포넌트 구조
App └── SearchBar └── FilterPanel └── HeavyList └── ListItem (× 수천 개) └── ExpensiveCalculation
수천 개의 데이터를 렌더링하고, 매번 무거운 연산을 수행하는 구조입니다.
🔴 주요 최적화 대상 (Bottleneck Points)
1. 🔁 전체 리스트 리렌더링
아이템 하나만 바뀌어도 수천 개가 리렌더링되는 비효율적인 구조
2. ⚙️ 고비용 필터링 연산
메모이제이션 없이 매번 실행되는 무거운 계산 로직
3. 📦 불필요한 Props 전달
하위 컴포넌트로 과도하게 전파되는 데이터 흐름

안내: 본 프로젝트는 성능 최적화 실습을 위해 의도적인 렌더링 지연이 포함되어 있습니다. Profiler로 분석한 결과를 바탕으로 병목 지점을 해결하고 지표를 개선해 봅시다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

46

5교시: 오전 이론 총정리 및 실습 환경 세팅
실습 환경 세팅: 지금 바로 시작합니다
🛠️ 준비 단계 안내
배포해 드린 저장소 주소에서 소스코드를 클론(Clone)받고, 필요한 의존성 패키지를 설치해 주세요. npm run dev 명령어로 로컬 서버가 정상적으로 구동되는지 확인하시기 바랍니다.
git clone https://github.com/becover/the-heavy-list-app.git cd the-heavy-list-app npm install npm run dev
🔍 진단 도구 최종 점검
브라우저 개발자 도구의 Profiler 탭이 정상적으로 활성화되었는지 확인해 주세요.
  • git clone 및 npm install 완료
  • localhost 접속 및 화면 렌더링 확인
  • React DevTools → Profiler → Settings 진입
  • 'Record why each component rendered' 옵션 활성화

오류 대응: 패키지 설치 과정에서 충돌이 발생하거나 서버 실행이 안 되는 분들은 지금 바로 말씀해 주세요.

실무 환경과 동일한 세팅을 통해 측정 데이터의 신뢰도를 확보하는 것이 목적입니다. 모든 분의 환경 세팅이 완료되는 대로,
첫 번째 최적화 대상인 컴포넌트 구조 분석으로 넘어가겠습니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

47

5교시: 오전 이론 총정리 및 실습 환경 세팅
[마무리] 5교시 핵심 정리
📊 오전 세션 복습
성능 지표 확인(CWV) → Profiler 병목 지점 특정까지의 전체 흐름을 정리했습니다.
🔄 작업 원칙 수립
무분별한 코드 수정이 아닌 Measure → Fix → Verify 프로세스를 확립했습니다.
🛠️ 환경 구축 완료
실습용 프로젝트(Heavy List App) 구조 파악 및 개발 환경 세팅을 완료했습니다.

🏁 준비는 끝났습니다. 이제 실제 코드를 통해 성능 지표를 개선해 보겠습니다。

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

48

5교시: 오전 이론 총정리 및 실습 환경 세팅
[마무리] 6교시 & 7교시 예고
🚀 6교시 예고: 에셋 및 네트워크 최적화 (LCP/CLS 개선)
🎯 첫 번째 과제
이미지 및 폰트 용량 최적화
— 대용량 이미지를 WebP로 전환하고, 폰트 로딩 방식을 개선하여 초기 로딩 속도를 향상시킵니다.
🔧 핵심 도구
WebP 변환기, Lighthouse, font-display
— 브라우저가 리소스를 더 빠르게 가져오고, 레이아웃 이동 없이 안정적으로 렌더링되도록 설정합니다.
🚀 7교시 예고: 컴포넌트 렌더링 최적화
🎯 두 번째 과제
불필요한 리렌더링 방지
— 아이템 하나가 변경되어도 수천 개가 불필요하게 다시 그려지는 문제를 해결합니다.
🔧 핵심 도구
React.memo
— 컴포넌트 메모이제이션을 활용해 렌더링 효율을 극대화합니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

49

6교시
[실습1] 에셋 및 네트워크 최적화
이미지 용량 최적화, 폰트 로딩 개선 및 점수 변화 확인

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

50

6교시: 에셋 및 네트워크 최적화
[실습 개요] 개선 대상 분석
목표: 현재 서비스의 시각적 로딩 성능(LCP, CLS) 저하 원인 요소를 특정합니다.
진단 데이터를 바탕으로, 성능에 악영향을 주는 외부 리소스부터 최적화하기
🔴 성능 저하 원인 요소 3가지
🖼️ LCP 저하
메인 배너 이미지(PNG/JPG)의 대용량으로 인한 렌더링 지연.
→ 최적화 기법: 이미지 포맷 변환(WebP) + 압축
📐 CLS 발생
이미지 로딩 전 공간 미확보로 인한 레이아웃 흔들림 현상.
→ 최적화 기법: width/height 속성 명시 + aspect-ratio 고정
🔤 폰트 렌더링 이슈 (FOIT/FOUT)
웹 폰트 로딩 중 글자가 보이지 않거나 기본 폰트가 노출되는 현상.
→ 최적화 기법: font-display: swap + preload
📊 진단 데이터 요약
49.9s
LCP
→ 목표: 2.5s 이하
0.204
CLS
→ 목표: 0.1 이하
1.2s
폰트 지연 (FOIT)
→ 목표: 0s

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

51

6교시: 에셋 및 네트워크 최적화
[퀘스트 1-1] 이미지 최적화 (LCP 개선) ①
브라우저가 핵심 리소스를 우선적으로 로드하도록 명시적인 지시를 내리는 과정
🔧 작업할 내용
🖼️ 포맷 변환
고용량 PNG/JPG → WebP/AVIF 변환
용량 최대 80% 절감 효과
우선순위 제어
핵심 이미지에 fetchpriority="high" 또는 link rel="preload" 적용
브라우저가 핵심 리소스를 먼저 로드하도록 명시적 지시
🎯 LCP 개선 목표
Before: LCP 49.9s 🔴
After: LCP 2.5s 이하 🟢

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

52

6교시: 에셋 및 네트워크 최적화
[퀘스트 1-1] 이미지 최적화 (LCP 개선) ②
📝 코드 예시
📊 용량 절감 효과
-60%
PNG → WebP
평균 용량
-40%
JPG → WebP
평균 용량
-80%
PNG → AVIF
평균 용량

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

53

6교시: 에셋 및 네트워크 최적화
차세대 이미지 포맷: WebP & AVIF
🛠️ 추천 변환 도구 https://squoosh.app
구글이 만든 무료 이미지 압축 도구.
WebP·AVIF 변환, 화질 미리보기, 용량 비교까지 브라우저에서 바로 가능.
사용 팁
`picture` 태그로 AVIF → WebP → 원본 순서로 fallback 처리하면 브라우저 호환성과 최적 압축률을 동시에 확보할 수 있음
<picture> <source srcset="image.avif" type="image/avif" /> <source srcset="image.webp" type="image/webp" /> <img src="image.jpg" alt="..." /> </picture>

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

54

6교시: 에셋 및 네트워크 최적화
[퀘스트 1-2] 웹 폰트와 레이아웃 (CLS 개선) ①
🔧 작업할 내용
1
🔤 폰트 로딩 전략
CSS @font-face에 font-display: swap; 설정
→ 폰트 로딩 중에도 기본 폰트로 텍스트를 즉시 표시합니다.
2
📐 레이아웃 안정화
이미지 태그에 aspect-ratio 또는 고정 크기 값 지정
→ 리소스 로드 전부터 영역을 확보하여 레이아웃 이동을 방지합니다.

💡리소스가 로드되기 전부터 영역을 확보하여 사용자 경험(UX)의 레이아웃 이동을 방지합니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

55

6교시: 에셋 및 네트워크 최적화
[퀘스트 1-2] 웹 폰트와 레이아웃 (CLS 개선) ②
📝 코드 예시
📊 CLS 개선 효과
CLS 점수
Before 0.204 🔴 → After 0.05 🟢
FOIT/FOUT 지연
Before 1.2s → After 0s
적용 전/후 비교
🔴 Before:
이미지 로드 시 레이아웃 불안정 발생, 폰트 깜빡임(FOUT) 노출
🟢 After:
영역 사전 확보로 레이아웃 안정화, 기본 폰트로 즉시 텍스트 표시

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

56

6교시: 에셋 및 네트워크 최적화
[검증] 네트워크 탭 및 Lighthouse 점수 확인 ①
🌐 네트워크 탭 확인 포인트
Transferred Size 감소폭 확인
PNG → WebP 변환 후 용량 비교
Waterfall 리소스 로딩 순서 개선 여부
🔦 Lighthouse 확인 포인트
CLS 시각적 안정성 점수 변화
LCP 로딩 시간 단축 수치
Performance 종합 점수 전/후 비교

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

57

6교시: 에셋 및 네트워크 최적화
[검증] 네트워크 탭 및 Lighthouse 점수 확인 ②
에셋 최적화를 통해 레이아웃 시프트(CLS)는 0으로 해결했으나, 과도한 컴포넌트 렌더링 연산이 메인 스레드를 장시간 점유(TBT 상승)하여 전체 LCP 지연의 근본 원인이 되고 있습니다.
현재의 LCP 지연은 자산 로딩 속도가 아닌, 렌더링 블로킹(Rendering Blocking)에 의한 병목 현상입니다. 병목 지점을 찾기 위해 React Profiler를 활용한 컴포넌트 최적화가 필요합니다.
📊 최적화 전/후 핵심 지표 비교 예시

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

58

7교시
[실습2] 렌더링 및 번들 최적화
React.memo 적용 및 코드 스플리팅을 통한 렌더링 차단 해결

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

59

7교시: 렌더링 및 번들 최적화
⚠️ React Profiler 시연 전 필수 확인사항
🚫 프로덕션(Build) 모드에서는 Profiler가 비활성화됩니다
React는 npm run build 시 번들 최적화를 위해 Profiler 측정 코드와 컴포넌트 displayName 등 디버깅 관련 코드를 모두 제거합니다. npm run preview(배포 버전)에서 React DevTools Profiler를 실행하면 측정이 불가능하거나 "프로파일링을 지원하지 않는 빌드입니다" 경고가 표시됩니다.
🔍 개발 모드에서만 "왜 리렌더링됐는지" 원인을 확인할 수 있습니다
npm run dev 상태에서 Profiler를 실행하고, 설정에서 "Record why each component rendered while profiling" 옵션을 활성화하세요. 컴포넌트 막대에 마우스를 올리면 "props.keyword 변경으로 인한 리렌더링" 등 구체적인 원인이 표시됩니다. 이 기능은 개발 모드 전용입니다.
시연 환경 체크리스트
npm run dev 실행 확인 (npm run preview )
React DevTools 확장 프로그램 설치 및 Profiler 탭 접근 확인
Profiler 설정 → "Record why each component rendered while profiling" 체크

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

60

7교시: 렌더링 및 번들 최적화
[퀘스트 2-1] 불필요한 리렌더링 제거 ① React.memo (INP 개선) -1
목표: 부모 컴포넌트 렌더링 시 자식 컴포넌트의 불필요한 리렌더링을 방지합니다.
🧠 컴포넌트 메모이제이션이란?

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

61

7교시: 렌더링 및 번들 최적화
[퀘스트 2-1] 불필요한 리렌더링 제거 ① React.memo (INP 개선) -2
목표: 부모 렌더링 시 자식 컴포넌트가 무분별하게 다시 그려지는 현상을 차단합니다.
🧠 컴포넌트 메모이제이션이란?
📌 원리
React.memo는 컴포넌트를 감싸 이전 Props와 현재 Props를 얕은 비교(Shallow Compare)합니다.
효과
Props가 변하지 않으면 렌더링 함수 자체를 실행하지 않고 이전 결과를 재사용합니다.
🎯 적용 대상
Profiler Flame Chart에서 노란색/주황색으로 표시된 자식 컴포넌트에 우선 적용합니다.

주의: React.memo는 Props의 참조값을 비교합니다. 함수형 Props는 매 렌더링마다 새 참조가 생성되므로, 다음 파트에서 useCallback으로 반드시 고정해야 합니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

62

7교시: 렌더링 및 번들 최적화
[퀘스트 2-1] 불필요한 리렌더링 제거 ② useCallback (INP 개선) - 코드 예시
🔴 Before: handleDelete 새 참조 → memo 무력화 → 전체 리렌더링
🟢 After: handleDelete 동일 참조 → memo 정상 작동 → 렌더링 생략

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

63

7교시: 렌더링 및 번들 최적화
[퀘스트 2-2] 코드 스플리팅 ① React.lazy (TBT/LCP 개선)
목표: 초기 로딩 시 필요한 코드만 전송하여 실행 시간을 단축합니다.
🧩 페이지 단위 분리란?
🔴 문제: 모든 페이지가 한 번에 로드
초기 접속 시 사용자가 보지도 않는 페이지 코드까지 전부 다운로드 → 번들 비대화
🔧 해결: React.lazy로 라우트 분리
현재 보이는 페이지만 로드하고, 나머지는 사용자가 이동할 때 로드합니다.
효과
초기 번들 크기 대폭 감소 → LCP 단축, 메인 스레드 점유 시간(TBT) 감소

Route-based Splitting은 가장 기본적이고 효과가 큰 코드 스플리팅 전략입니다. 라우터가 있는 모든 앱에 즉시 적용 가능합니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

64

7교시: 렌더링 및 번들 최적화
[퀘스트 2-2] 코드 스플리팅 ① React.lazy (TBT/LCP 개선) - 코드 예시

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

65

7교시: 렌더링 및 번들 최적화
[퀘스트 2-2] 코드 스플리팅 ① Dynamic Import (TBT/LCP 개선)
목표: 초기 로딩 시 필요한 코드만 전송하여 실행 시간을 단축합니다.
🧩 페이지 단위 분리란?
🔴 문제: 모든 페이지가 한 번에 로드
초기 접속 시 사용자가 보지도 않는 페이지 코드까지 전부 다운로드 → 번들 비대화
🔧 해결: React.lazy로 라우트 분리
현재 보이는 페이지만 로드하고, 나머지는 사용자가 이동할 때 로드합니다.
효과
초기 번들 크기 대폭 감소 → LCP 단축, 메인 스레드 점유 시간(TBT) 감소

Route-based Splitting은 가장 기본적이고 효과가 큰 코드 스플리팅 전략입니다. 라우터가 있는 모든 앱에 즉시 적용 가능합니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

66

7교시: 렌더링 및 번들 최적화
[퀘스트 2-2] 코드 스플리팅 ② Dynamic Import (TBT/LCP 개선) - 코드예시

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

67

7교시: 렌더링 및 번들 최적화
[퀘스트 2-3] 데이터 렌더링 최적화 (초기 병목 해결)
한 번에 모든 데이터를 그리지 않고, 필요한 만큼만 분할하여 렌더링합니다.
🧩 1,000개 렌더링의 함정?
🔴 문제: 아무리 React.memo로 리렌더링을 막아도, 최초 화면이 열릴 때 1,000개의 컴포넌트(DOM)를 억지로 그려야 하는 "초기 렌더링 물리적 병목" 발생. 메인 스레드 기절!
🔧 해결: 한 번에 보여줄 수 있는 단위(예: 20개)로 데이터를 잘라서 보여주는 페이지네이션(Pagination) 또는 눈에 보이는 영역만 그리는 가상화 렌더링(Virtualization) 도입
효과: 브라우저 연산량 1/50 감소 → TBT(총 블로킹 시간) 소멸, 쾌적한 화면 스크롤 확보
📌 실무 핵심 포인트
Pagination | 페이지네이션은 프론트엔드 단독 처리보다 백엔드(API)와 협의하여 필요한 데이터만 서버에서 가져오는 것이 실무의 정석
Virtualization | react-window, react-virtual 등 라이브러리를 활용해 뷰포트 내 보이는 항목만 DOM에 마운트하여 렌더링 비용 최소화

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

68

7교시: 렌더링 및 번들 최적화
[검증] Profiler 재측정 ① Before vs After
최적화 효과를 Flame Graph로 직접 확인합니다.
🔴 Before: 최적화 전
🟡 전체 리스트 노란색/주황색으로 강조
부모 상태 변경 시 ListItem 수천 개 동시 리렌더링
⏱️ 렌더링 소요 시간: 340ms
단순 클릭 한 번에 메인 스레드 완전 점유
🔁 리렌더링 횟수: 수천 회
변경된 아이템과 무관한 컴포넌트까지 전부 실행
🟢 After: 최적화 후
최적화된 컴포넌트 회색(Did not render) 유지
변경된 컴포넌트만 선택적으로 렌더링
⏱️ 렌더링 소요 시간: 12ms
340ms → 12ms, 리액트 내부 연산 완전 생략 증명
🔁 불필요 리렌더링: 0회
React.memo + useCallback 적용으로 완전 차단

"플레임 차트가 회색으로 변하는 것은 리액트 내부 연산이 완전히 생략되었음을 증명하는 가장 확실한 지표입니다." (INP

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

69

7교시: 렌더링 및 번들 최적화
[검증] Profiler 재측정 ② 수치 데이터 기록
최적화 결과를 객관적인 수치로 기록하여 성과 리포트에 반영합니다.
▼98.5%
렌더링 시간
413ms → 6ms
▼100%
불필요 리렌더링
수천 회 → 0회
▼99%
INP
353.5ms → 4.2ms
▲207%
Lighthouse 점수
29점 → 89점
📋 수치 기록 방법
Profiler 녹화 후 각 커밋의 렌더링 시간(ms) 스크린샷 저장
최적화 전/후 동일한 인터랙션으로 측정 (조건 통일)
렌더링 횟수 및 'Did not render' 컴포넌트 수 기록
🎯 다음 단계
📋 8교시: 수집한 수치 데이터를 성과 리포트로 구조화
💼 포트폴리오: P-A-A-R 프레임워크로 면접 답변 완성

측정 없이 시작했고, 측정으로 끝냅니다. Measure → Fix → Verify 사이클이 완성되었습니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

70

7교시: 렌더링 및 번들 최적화
[재검증] 네트워크 탭 및 Lighthouse 점수 재확인
최적화가 끝났는데 100점이 아닌 이유는 왜일까요? 첫번째는 우리가 네트워크 지연으로 일부러 넣어둔 setTimeout과 진짜 서버가 아닌 localhost에서 측정했기 때문이에요. 실무 환경에 배포하면 CDN압축과 캐싱이 자동으로 붙어 무조건 90점 이상~후반대의 초록불을 보게 될거에요!
📊 최적화 전/후 핵심 지표 재비교 예시

최적화 결과는 반드시 객관적인 수치로 기록하여 개선 효과를 증명해야 합니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

71

8교시
성과 리포트 작성 및 커리어 가이드
최종 성능 개선 지표 정리 및 기술 면접 대비 성과 데이터 수치화 전략

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

72

8교시: 성과 리포트 작성 및 커리어 가이드
[성과 리포트] 성능 개선 결과 데이터 요약
6~7교시 실습 데이터를 바탕으로 핵심 지표 변화를 정리합니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

73

8교시: 성과 리포트 작성 및 커리어 가이드
[성과 리포트] 성능 개선 결과 데이터 요약
6~7교시 실습 데이터를 바탕으로 핵심 지표 변화를 정리합니다.
▼91%
LCP 개선
49.9s → 4.7s
▼100%
CLS 개선
0.204 → 0.0
▼99%
INP 개선
353.5ms → 4.2ms
▼99%
JS 번들 용량 감소
3.36MB → 19KB

성능 개선은 객관적인 숫자로 증명되기에, 포트폴리오에서 가장 강력한 설득력을 갖는 소재가 됩니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

74

8교시: 성과 리포트 작성 및 커리어 가이드
[면접 전략] ① 이렇게 답하면 탈락합니다
추상적인 표현은 면접관에게 신뢰를 주지 못합니다.
🔴 Bad: 피해야 할 모호한 답변 유형
"이미지 최적화를 해서 로딩 속도를 많이 올렸습니다."
얼마나? 어떤 방법으로? 수치 없음
"React 성능을 개선해서 앱이 빨라졌습니다."
어떤 지표? 얼마나 빨라졌는지 불명확
"불필요한 리렌더링을 줄였습니다."
어디서? 어떤 도구로? 개선폭 없음
"코드 스플리팅을 적용해서 최적화했습니다."
어떤 번들이? 결과 수치가 없음

면접관은 "열심히 했다"는 인상보다 "데이터로 나타낸 증거"를 원합니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

75

8교시: 성과 리포트 작성 및 커리어 가이드
[면접 전략] ② 이렇게 답하면 합격합니다
[도구/지표] + [원인] + [해결책] + [개선 결과] 공식을 사용합니다.

📐 답변 공식: [도구/지표] + [원인] + [해결책] + [개선 결과]
🟢 Good: 수치 기반 모범 답변
"Lighthouse 분석 결과 LCP가 49.9s로 측정되어, WebP 전환과 fetchpriority 적용을 통해 4.7s로 91% 단축했습니다."
도구(Lighthouse) + 수치(49.9s) + 기술(WebP, fetchpriority) + 결과(91% 단축)
"React Profiler Flame Chart에서 ListItem 컴포넌트의 불필요한 리렌더링을 확인하고, React.memo와 useCallback 적용으로 INP를 353.3ms에서 4.2ms로 99% 개선했습니다."
도구(Profiler) + 원인(리렌더링) + 기술(memo, useCallback) + 결과(99% 개선)
"React.lazy와 Dynamic Import로 초기 번들을 3.36MB에서 19KB로 99% 줄여 TBT를 595ms에서 4.2ms로 단축했습니다."
기술(lazy, Dynamic Import) + 수치(3.36MB→19KB) + 결과(TBT 98.8% 단축)

면접관은 정성적인 노력보다 데이터로 상황을 통제하고 설득하는 능력을 높게 평가합니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

76

8교시: 성과 리포트 작성 및 커리어 가이드
[커리어 가이드] 성능 최적화 경험의 자산화
Troubleshooting 프레임워크: P-A-A-R
01
🔴 P — Problem (문제)
어떤 지표가 성능 기준 미달이었는가?
예: "Lighthouse 측정 결과 LCP 49.9s, CLS 0.204로 Google 권장 기준 초과"
02
🔍 A — Analysis (분석)
Profiler나 Lighthouse로 포착한 구체적인 병목 지점은 어디인가?
예: "React Profiler Flame Graph에서 ListItem 컴포넌트 수천 개 동시 리렌더링 확인"
03
🔧 A — Action (해결)
왜 해당 기술을 최적의 대안으로 선택했는가?
예: "React.memo + useCallback으로 Props 변화 없는 컴포넌트 렌더링 차단, WebP 전환으로 이미지 용량 94% 절감"
04
🟢 R — Result (결과)
최종적으로 어떤 수치 변화와 사용자 경험 개선을 이끌어냈는가?
예: "LCP 49.9s → 4.7s (▼98.5%), INP 353.3ms → 4.2ms (▼99%), Lighthouse 29점 → 89점"

이 논리적인 과정 자체가 여러분만의 독보적인 기술적 자산이자 실력의 증거가 됩니다.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

77

8교시: 성과 리포트 작성 및 커리어 가이드
[마무리] 전체 과정 복기
1교시 🔦 Lighthouse 활용
성능 최적화의 비즈니스 가치 + 정확한 측정 환경 세팅
2교시 📊 CWV 지표 이해
LCP, CLS, INP를 저하시키는 실제 코드 사례와 해결 원리
3교시 🌐 브라우저 정밀 진단
Network Waterfall 분석 + CPU 병목(Long Task) 탐색
4교시 ⚛️ React Profiler
재렌더링 원리 이해 + Flame Chart 병목 지점 특정
5교시 🗂️ 이론 총정리
Measure → Fix → Verify 원칙 + 실습 환경 세팅
6교시 🖼️ 에셋 최적화 실습
이미지 WebP 전환 + 폰트 로딩 개선 (LCP/CLS 개선)
7교시 렌더링 최적화 실습
React.memo + 코드 스플리팅 (INP/TBT 개선)
8교시 📋 성과 증명
데이터 기반 리포트 작성 + 면접 답변 전략

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

78

8교시: 성과 리포트 작성 및 커리어 가이드
[마무리] Q&A
💬 Q&A
실무 적용 시 발생할 수 있는 변수나 개별 궁금증을 자유롭게 질문해 주세요.

막연하게 '느린 것 같다'고 느끼던 것을, 이제는 숫자로 설명할 수 있게 됐습니다.
완벽하지 않아도 괜찮습니다. 오늘처럼 데이터를 보는 눈을 꾸준히 키워보세요.

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

79

마치며.
이제 여러분의 무기는 '열심히'뿐만이 아닌 '데이터를 보는 눈'입니다.
오늘 기록한 수치 하나하나가 여러분의 커리어 증거이자 몸값입니다.
수치가 있는 경험은, 그 자체로 가장 강력한 자기소개서 이기 때문입니다.
그리고 기억하세요.
성능을 개선한다는 것은 결국 사용자에게 더 나은 시간을 선물하는 일입니다.
앞으로 여러분이 만드는 모든 서비스가 누군가에게 '기분 좋은 경험'이 되길 바랍니다.
감사합니다. 🙏

당신의 웹이 느린 이유: 프론트엔드 성능 구출 작전

COPYRIGHT© DAMISEO All rights reserved.

80