Skip to content

Split View: 성능·Core Web Vitals 2025 완전 정복: LCP·CLS·INP, Real User Monitoring vs Synthetic, Critical Rendering Path, JS 번들·Image·Font 최적화, Caching·Edge·CDN·HTTP/3, Vercel Speed Insights·CrUX·PageSpeed, 한국 네트워크 특성 — Season 6 Ep 6

|

성능·Core Web Vitals 2025 완전 정복: LCP·CLS·INP, Real User Monitoring vs Synthetic, Critical Rendering Path, JS 번들·Image·Font 최적화, Caching·Edge·CDN·HTTP/3, Vercel Speed Insights·CrUX·PageSpeed, 한국 네트워크 특성 — Season 6 Ep 6

프롤로그 · 성능은 기능이 아니다

개발자들이 자주 착각하는 것: "성능 최적화는 기능 출시 후의 튜닝". 2025년 현실은 다르다.

  • Google 검색 순위에 Core Web Vitals 반영 (2021~)
  • 이커머스에서 LCP 0.1초 개선당 전환율 1%+ 연구 (Amazon, Booking)
  • 2024년 INP 정식 적용 후 반응성 최적화 경쟁
  • 한국 사용자의 지하철 5G·저전력 모드 현실

"성능은 기능이 아니다. 모든 기능의 조건이다."

좋은 AI·좋은 UX·좋은 모션도 느리면 아무 가치 없다. 이번 글은 2025년 실전 성능 가이드.

1장 · Core Web Vitals 2025 — 3대 지표

LCP (Largest Contentful Paint)

  • 가장 큰 콘텐츠가 뷰포트에 렌더된 시점
  • Good: ≤ 2.5초, Needs Improvement: ≤ 4초, Poor: > 4초
  • 보통 Hero 이미지·텍스트 블록

CLS (Cumulative Layout Shift)

  • 뷰포트 이동(레이아웃 시프트) 누적
  • Good: ≤ 0.1, Needs: ≤ 0.25, Poor: > 0.25
  • 이미지 size 미지정·광고 삽입·폰트 로드 등이 주범

INP (Interaction to Next Paint) — 2024 FID 대체

  • 사용자 상호작용 → 다음 페인트까지 걸린 시간
  • Good: ≤ 200ms, Needs: ≤ 500ms, Poor: > 500ms
  • 느린 JS·메인스레드 블록 탐지
  • FID(First Input Delay)보다 페이지 생애 전체 평가

측정 기준

  • p75 (75 백분위수) — 대부분 사용자 경험
  • Real users, 28일 rolling (CrUX)
  • Mobile·Desktop 분리 평가

보조 지표

  • FCP (First Contentful Paint): 1.8초 목표
  • TTFB (Time to First Byte): 0.8초 목표
  • TTI (Time to Interactive): 오래된 지표, INP가 대체

2장 · RUM vs Synthetic — 무엇을 측정할까

Synthetic (합성 테스트)

  • 도구가 제어된 환경에서 시뮬레이션
  • Lighthouse, WebPageTest, SpeedCurve
  • 장점: 재현성, 회귀 감지
  • 단점: 실사용자와 괴리

RUM (Real User Monitoring)

  • 실제 사용자 브라우저에서 측정
  • Vercel Speed Insights, Datadog RUM, New Relic Browser, Sentry, CrUX
  • 장점: 진짜 경험 반영
  • 단점: 노이즈, 소수 사용자 영향 큼

병행 원칙

  • CI에서 Lighthouse (회귀 감지)
  • Production에서 RUM (진짜 성능)
  • CrUX 월간 리뷰로 경쟁사 벤치마크

CrUX (Chrome User Experience Report)

  • Google이 Chrome 사용자 데이터 수집 (opt-in)
  • 익명 집계, 월 단위 업데이트
  • PageSpeed Insights가 이를 활용
  • BigQuery 공개 데이터셋

3장 · Critical Rendering Path

브라우저의 렌더 파이프라인

  1. Network: HTML 다운로드
  2. Parse HTML → DOM
  3. Parse CSS → CSSOM
  4. DOM + CSSOM → Render Tree
  5. Layout (크기·위치)
  6. Paint (픽셀)
  7. Composite (레이어 합성)

주요 병목

  • Render-Blocking CSS: 외부 CSS 로드 중 렌더 불가
  • Render-Blocking JS: <script> 파싱 중 DOM 파싱 중단
  • Font Swap Period: 폰트 로드 전 FOIT/FOUT

2025년 표준 개선 기법

(1) Critical CSS Inline

  • Above-the-fold CSS를 <style> 로 인라인
  • Next.js·Astro·Vite 플러그인 자동화

(2) defer / async JS

  • <script defer> : 문서 끝까지 실행 지연
  • <script async> : 독립 실행

(3) fetchpriority

  • <img fetchpriority="high"> 로 우선순위
  • LCP 이미지에 필수

(4) preconnect / dns-prefetch

  • 외부 도메인 핸드셰이크 미리
  • <link rel="preconnect" href="https://cdn.example.com">

(5) preload

  • 중요 리소스 미리 로드
  • 폰트·Hero 이미지 등

4장 · JS 번들 다이어트

2025년 번들의 "좋은 크기":

  • Initial: < 170kb gzipped
  • Per route: < 50kb
  • 모바일 환경에서 Parse·Execute 비용 고려

번들러 지형 2025

  • esbuild: 가장 빠른 Go 기반
  • swc: Rust 기반, Next.js 내부
  • Rollup: 라이브러리·트리셰이킹
  • Turbopack: Next.js 15 기본, Rust 기반 Webpack 후계
  • Vite: 개발 서버 최고, 번들은 Rollup
  • Rspack: Rust 기반 Webpack 호환
  • Bun: 런타임+번들러 통합

번들 분석 도구

  • Bundle Analyzer (Next.js, Vite)
  • source-map-explorer
  • Rollup visualizer
  • Bundlephobia: 패키지 크기 사전 조회

흔한 문제

(1) 무거운 라이브러리

  • momentdate-fns or dayjs
  • lodash 전체 → 개별 import
  • react-icons → svg 직접

(2) 사용 안 하는 코드

  • 트리셰이킹 안 되는 CJS 패키지
  • "sideEffects": false 명시

(3) Dynamic Import

  • 차트·모달 등 지연 로드
  • const Chart = dynamic(() => import('./Chart'))

(4) Polyfill 과잉

  • 타겟 브라우저 명확히 (Baseline 2024)
  • core-js 선택적 import

(5) CSS-in-JS 오버헤드

  • 런타임 CSS-in-JS → zero-runtime (linaria, Vanilla Extract, Pigment)
  • Tailwind·CSS Modules 대세

5장 · Image 최적화 — LCP의 핵심

포맷 선택 (2025)

포맷용도압축률지원
AVIF최신최강 (~50% vs JPEG)모던 브라우저
WebP표준JPEG 대비 30%모든 모던
JPEG사진기본100%
PNG투명·단순무손실100%
SVG벡터작음100%

2025년 권장: AVIF + WebP + JPEG 폴백

반응형 이미지

  • <img srcset="..." sizes="..."> 로 기기별 최적 이미지
  • 또는 <picture> 로 포맷별 분기

Next.js Image 컴포넌트

import Image from 'next/image';

<Image
  src="/hero.jpg"
  width={1200}
  height={600}
  priority         // LCP 후보
  alt="Hero"
  placeholder="blur"
  blurDataURL={blur}
/>
  • 자동 AVIF/WebP 변환
  • 반응형 srcset 생성
  • Lazy load 기본 (priority만 eager)
  • CLS 방지 (width·height 필수)

Astro Image / Astro Assets

  • 빌드 타임 최적화
  • getImage() API로 고급 제어

CDN 이미지 서비스

  • Cloudinary, Imgix, Bunny, Cloudflare Images
  • 실시간 변환·캐싱

주요 팁

  • 항상 width·height 지정 (CLS 0)
  • Lazy Load + priority 혼합
  • LCP 이미지는 preload + fetchpriority=high
  • Hero 이미지는 인라인 SVG·data-URL 검토

6장 · Font 최적화

핵심 이슈

  • 폰트 로드 지연 → 텍스트 보이지 않음(FOIT) 또는 전환 깜빡(FOUT)
  • CLS 발생

font-display 설정

@font-face {
  font-family: 'Pretendard';
  src: url('/fonts/pretendard.woff2') format('woff2');
  font-display: swap;  /* 기본 폰트 먼저, 로드 후 교체 */
}
  • swap: 기본 폰트 먼저 (CLS↑), 가장 빠름
  • optional: 100ms 안에 로드 안 되면 기본 폰트 유지 (CLS↓)
  • fallback: swap과 optional 중간

size-adjust·ascent-override

  • 기본 폰트와 웹폰트 메트릭 맞춤
  • CLS 대폭 감소
@font-face {
  font-family: 'Pretendard-fallback';
  src: local('Arial');
  size-adjust: 105%;
  ascent-override: 90%;
}

서브셋팅

  • 한국어 폰트는 크기가 큼 (2-3MB) → 자주 쓰는 글자만
  • 주요 자주 사용 문자 (KS X 1001 기본)
  • Subfont 도구로 자동 서브셋

Variable Font

  • 하나의 파일로 여러 굵기·너비·스타일
  • font-variation-settings
  • Pretendard Variable 공개 (국산 대표)

2025년 권장 스택

  • Pretendard Variable (한글)
  • Inter / Geist (영문)
  • Noto Sans KR (폴백)
  • font-display: swap + size-adjust

7장 · Caching 전략

HTTP 캐시

  • Cache-Control: 가장 중요한 헤더
    • public, max-age=31536000, immutable — 정적 리소스
    • no-cache — 항상 검증
    • no-store — 절대 저장 X
  • ETag / Last-Modified — 조건부 요청
  • Stale-While-Revalidate — 만료 후에도 써도 되나 백그라운드 갱신

Next.js 15 Caching (재설계)

  • Request Memoization: 동일 요청 중복 제거
  • Data Cache: 서버 fetch 응답 캐시
  • Full Route Cache: 정적 페이지 HTML
  • Router Cache: 클라이언트 라우터 캐시
  • 2025년부터 use cache 지시어로 명시적 opt-in

Service Worker

  • Offline, App-shell, Cache-first for assets
  • Workbox로 구현 편의
  • 2025년 PWA 부활 조짐 (iOS 제한 완화 움직임)

Edge Caching

  • CDN 레벨 캐시 (Vercel, Cloudflare, Fastly)
  • stale-while-revalidate 로 체감 속도↑
  • ISR (Incremental Static Regeneration) — Next.js 대표 기법

8장 · Edge·CDN·HTTP/3

CDN의 역할

  • 지리적 가까운 서버에서 응답
  • 원본 서버 부하 감소
  • TLS·HTTP/3·압축 오프로딩

2025년 주요 CDN

  • Cloudflare: 가격·기능 밸런스 최강
  • Vercel Edge Network: Next.js 친화
  • Fastly: 개발자 친화, VCL
  • AWS CloudFront: AWS 생태계 통합
  • Netlify Edge: JAMstack 친화
  • 한국: Toast KRP, 네이버 클라우드 CDN, KT 올레CDN

Edge Function

  • CDN 레벨에서 로직 실행
  • Cloudflare Workers, Vercel Edge, Deno Deploy, Fastly Compute@Edge
  • Cold Start 거의 없음 (V8 Isolate)
  • 사용 사례: A/B, 인증, Rate Limit, i18n

HTTP/3 (QUIC)

  • UDP 기반, Head-of-line Blocking 해결
  • TLS 1.3 내장, 0-RTT 연결
  • 2025년 CDN·주요 사이트 기본
  • 모바일·불안정 네트워크에서 특히 이점

한국 네트워크 특성

  • 지하철 5G: 혼잡·지연·패킷 로스
  • 공공 WiFi: 제한·광고 프록시
  • KT·SKT·LGU+ 통신사별 라우팅 차이
  • → Edge·CDN이 특히 중요

9장 · INP 최적화 — 반응성 실전

INP의 원인

  • 긴 작업(long task) >50ms 이 메인 스레드 점유
  • 상호작용 처리 지연

실전 기법

(1) Debounce / Throttle

  • 검색 input·스크롤 리스너

(2) Scheduler API (Chrome)

scheduler.postTask(() => heavyWork(), { priority: 'background' });

(3) useDeferredValue / useTransition (React 18+)

const [isPending, startTransition] = useTransition();
startTransition(() => setQuery(input));

(4) Web Workers

  • 무거운 계산·정렬을 워커로

(5) Virtualization

  • 긴 리스트에 react-window, TanStack Virtual

(6) Code Splitting

  • 필요할 때만 로드

측정

  • Chrome DevTools Performance "INP" 기록
  • Long Task API로 production 감지

10장 · Vercel Speed Insights·CrUX·PageSpeed

Vercel Speed Insights

  • Vercel 배포 프로젝트에 간단 통합
  • RUM 데이터, Web Vitals 자동
  • 페이지별·시간별 분해
  • 가격: Pro 플랜 포함

Datadog RUM / New Relic Browser

  • 엔터프라이즈 APM과 통합
  • 사용자 세션 리플레이, 에러 추적
  • 가격 비쌈

CrUX Dashboard

  • Google이 제공 무료 도구
  • site-level, origin-level 리포트
  • CrUX API·BigQuery로 자동화

PageSpeed Insights

  • Google 무료 도구
  • Lighthouse + CrUX 결합
  • SEO·Accessibility·Best Practices까지

WebPageTest

  • 가장 정교한 Synthetic
  • 다양한 위치·네트워크·디바이스
  • 워터폴 차트, 필름 스트립

11장 · 실전 체크리스트 · 성능 린터

프로젝트 초기 설정

  • Next.js/Astro Image 활용
  • font-display: swap + size-adjust
  • Critical CSS (프레임워크 기본)
  • Bundle Analyzer 설치
  • Lighthouse CI 설정 (threshold: LCP<2.5s, CLS<0.1, INP<200ms)
  • Vercel Speed Insights 또는 자체 RUM

릴리즈 전 체크

  • LCP 원인 분석 (DevTools "Performance insights")
  • INP 이벤트 핸들러 점검
  • CLS 이미지 size 확인
  • 번들 < 170kb
  • 핵심 폰트 preload
  • 3G Fast 에뮬레이션 테스트

릴리즈 후 모니터링

  • RUM 75p 추이
  • 사고 시 롤백·수정
  • 주간 Performance Review 팀 미팅

12장 · 2025년 고급 패턴

Partial Pre-Rendering (PPR)

  • Next.js 15: 정적 셸 + 동적 홀
  • LCP 극단 단축 + 개인화 공존

Islands Architecture

  • Astro: 기본 정적 + JS 섬만 하이드레이트
  • 번들 최소화

Qwik Resumability

  • 초기 JS 0에 가까움
  • 상호작용 필요 시점에 로드

Bun/Deno 런타임

  • Node.js 대비 시작·런타임 속도
  • 일부 프로덕션 도입 시작

Turbopack

  • Next.js 15 기본
  • Dev 서버·빌드 속도 혁명

Server-sent Streaming

  • RSC·Suspense로 콘텐츠 조각 전송
  • TTFB·LCP 개선

13장 · 다음 글 예고 — Season 6 Ep 7: "접근성과 국제화"

성능을 잘 만들어 놓았다면 다음은 모두가 쓸 수 있는 제품. Ep 7은 접근성(a11y)과 국제화(i18n).

  • WCAG 2.2 실전 체크리스트
  • Screen Reader 테스트 (NVDA·VoiceOver)
  • 키보드 내비게이션 설계
  • ARIA 패턴과 오남용
  • 색 대비·모션·폰트 크기
  • EU Accessibility Act 2025·ADA·한국 장애인차별금지법
  • i18n: next-intl·react-intl·vue-i18n·Format.js
  • Locale-aware 숫자·날짜·통화
  • 한국어 타이포그래피의 특수성 (조사·줄바꿈·세로 쓰기)
  • 일본·중국어·RTL(아랍어·히브리어) 지원
  • AI·LLM의 다국어 품질

"접근성은 소수의 권리가 아니다. 모두의 품질이다."

다음 글에서 만나자.

에필로그 · 체크리스트 12

  1. Core Web Vitals p75 기준을 RUM으로 추적하는가?
  2. LCP < 2.5s, CLS < 0.1, INP < 200ms 를 달성하는가?
  3. LCP 이미지에 priority + fetchpriority=high 설정되는가?
  4. 모든 이미지에 width·height 가 지정되는가?
  5. 폰트가 font-display + size-adjust 로 FOIT/CLS 방지되는가?
  6. 번들이 초기 <170kb, 라우트 <50kb 인가?
  7. Dynamic Import·Code Splitting 을 적극 활용하는가?
  8. CDN·Edge Caching 이 설정되어 있는가?
  9. HTTP/3 가 활성화되어 있는가?
  10. Lighthouse CI로 회귀 감지되는가?
  11. Vercel Speed Insights 또는 RUM 운영되는가?
  12. 한국 네트워크·모바일 실사용자 경험이 고려되는가?

"빠른 제품은 좋은 제품이다. 느린 제품은 존재하지 않는 제품이다."

— Season 6 Ep 6, Fin.

Performance & Core Web Vitals 2025 — LCP, CLS, INP, RUM, Image/Font/JS Optimization, Edge, CDN, HTTP/3 (S6 E6)

Prologue — performance is not a feature

A common misconception: "performance optimization is post-launch tuning." In 2025, reality says otherwise.

  • Google search ranking incorporates Core Web Vitals (since 2021).
  • Ecommerce research: +1% conversion per 0.1s LCP improvement (Amazon, Booking).
  • INP became an official metric in 2024, kicking off a responsiveness race.
  • Korean users live on subway 5G, low-power mode — the tail matters.

"Performance isn't a feature. It's the precondition for every feature."

Good AI, good UX, great motion — all worthless if slow. This is the 2025 frontline guide.


1. Core Web Vitals 2025 — the three numbers

LCP (Largest Contentful Paint)

  • When the largest viewport element renders.
  • Good ≤ 2.5s, Needs Improvement ≤ 4s, Poor > 4s.
  • Usually a hero image or text block.

CLS (Cumulative Layout Shift)

  • Cumulative viewport shift score.
  • Good ≤ 0.1, Needs ≤ 0.25, Poor > 0.25.
  • Usual offenders: images without dimensions, ads, font swap.

INP (Interaction to Next Paint) — replaced FID in 2024

  • From input to next paint.
  • Good ≤ 200ms, Needs ≤ 500ms, Poor > 500ms.
  • Detects slow JS and main-thread blocking; covers the entire page lifetime (unlike FID).

Measurement conventions

  • p75 percentile — matches most-user experience.
  • Real users, 28-day rolling (CrUX).
  • Mobile vs desktop split.

Supporting metrics

  • FCP target 1.8s, TTFB target 0.8s.
  • TTI is legacy — INP replaced it.

2. RUM vs synthetic — what to measure

Synthetic

  • Controlled lab (Lighthouse, WebPageTest, SpeedCurve).
  • Pros: reproducible, regression detection.
  • Cons: diverges from real users.

RUM

  • Real browsers (Vercel Speed Insights, Datadog RUM, New Relic, Sentry, CrUX).
  • Pros: truth.
  • Cons: noisy, outliers dominate small samples.

Do both

  • Lighthouse in CI for regressions.
  • RUM in production for truth.
  • CrUX monthly review for competitive benchmarking.

CrUX (Chrome UX Report)

Anonymized Chrome opt-in data, monthly aggregate. Powers PageSpeed Insights and is available in BigQuery.


3. Critical rendering path

Browser pipeline: Network → Parse HTML → CSSOM → Render Tree → Layout → Paint → Composite.

Common bottlenecks

  • Render-blocking CSS.
  • Render-blocking JS.
  • Font swap period (FOIT/FOUT).

2025 standard techniques

  1. Critical CSS inlined for above-the-fold.
  2. <script defer> / async — stop blocking HTML parse.
  3. <img fetchpriority="high"> on the LCP image.
  4. <link rel="preconnect"> for third-party origins.
  5. <link rel="preload"> for critical fonts/hero images.

4. JS bundle diet

Good sizes in 2025:

  • Initial < 170kb gzipped, per route < 50kb.
  • Mobile parse/execute cost is real.

Bundler landscape

  • esbuild (Go), swc (Rust, inside Next.js), Rollup (libraries), Turbopack (Next 15 default), Vite (Rollup underneath), Rspack (Rust, Webpack-compatible), Bun (runtime + bundler).

Usual offenders

  • momentdate-fns or dayjs.
  • lodash full → per-function import.
  • react-icons → raw SVG.
  • CommonJS packages that block tree-shaking — mark "sideEffects": false.
  • Dynamic import for heavy widgets (charts, modals).
  • Polyfill bloat — target Baseline 2024.
  • Runtime CSS-in-JS → zero-runtime (Linaria, Vanilla Extract, Pigment) or Tailwind / CSS Modules.

5. Image optimization — the LCP lever

Format

  • AVIF (best compression) + WebP + JPEG fallback. SVG for vectors.

Responsive <picture> and <img srcset sizes>

Next.js <Image>

import Image from 'next/image'
<Image src="/hero.jpg" width={1200} height={600} priority placeholder="blur" blurDataURL={blur} alt="Hero" />

Auto AVIF/WebP, responsive srcset, lazy by default (priority for LCP), prevents CLS.

Tips

  • Always specify width/height.
  • Lazy + priority combo.
  • LCP image: preload + fetchpriority="high".
  • Hero art worth inlining as SVG/data-URL for small files.

6. Font optimization

font-display

  • swap — fallback first (fast, CLS risk).
  • optional — if not loaded in 100ms, keep fallback (no CLS).
  • fallback — in between.

size-adjust + ascent-override

Match fallback metrics to web font — dramatically reduces CLS.

Subsetting

Korean/Japanese/Chinese fonts are multi-MB. Subset to KS X 1001 2,350 / JIS core / etc. Use Subfont or Glyphhanger to automate.

Variable fonts

One file, every weight/width. Pretendard Variable (Korean), Inter/Geist (Latin).

Pretendard Variable + Noto Sans KR fallback, font-display: swap, size-adjust on fallback.


7. Caching

HTTP cache

  • Cache-Control: public, max-age=31536000, immutable for hashed assets.
  • no-cache for always-validate.
  • no-store never.
  • ETag / Last-Modified for conditional requests.
  • stale-while-revalidate for smooth rotation.

Next.js 15 caching (redesigned)

Request memoization, Data Cache, Full Route Cache, Router Cache. 2025+: explicit use cache directive opts in.

Service Worker

Offline, app-shell, cache-first for assets (Workbox). PWA revival on iOS as restrictions ease.

Edge caching

CDN-level stale-while-revalidate. ISR remains the Next.js cornerstone.


8. Edge, CDN, HTTP/3

Roles

Geographic proximity, origin offload, TLS/HTTP/3/compression.

Players

Cloudflare (best balance), Vercel Edge, Fastly (VCL), AWS CloudFront, Netlify Edge. Korea: Toast KRP, NAVER Cloud CDN, KT Olleh CDN.

Edge functions

Cloudflare Workers, Vercel Edge, Deno Deploy, Fastly Compute@Edge. Minimal cold start (V8 isolates). Use for A/B, auth, rate limit, i18n routing.

HTTP/3 (QUIC)

UDP, no head-of-line blocking, 0-RTT, TLS 1.3. Default on most CDNs. Huge win on mobile and unstable networks — especially Korean subway 5G.


9. INP optimization

Long tasks (>50ms) on the main thread break responsiveness.

  1. Debounce / throttle search and scroll handlers.
  2. Scheduler API: scheduler.postTask(() => heavy(), { priority: 'background' }).
  3. useDeferredValue / useTransition in React 18+.
  4. Web Workers for heavy computation.
  5. Virtualization (react-window, TanStack Virtual) for long lists.
  6. Code splitting for features used occasionally.

Measure with Chrome DevTools Performance → INP, Long Task API in production.


10. Tooling

  • Vercel Speed Insights — zero-config RUM on Vercel.
  • Datadog RUM / New Relic — enterprise-grade.
  • CrUX Dashboard — free, origin-level.
  • PageSpeed Insights — Lighthouse + CrUX combined.
  • WebPageTest — highest-fidelity synthetic.

11. Practical checklist

Project setup

  • Framework Image component, font-display: swap + size-adjust, Critical CSS.
  • Bundle Analyzer, Lighthouse CI with thresholds (LCP<2.5s, CLS<0.1, INP<200ms).
  • RUM (Vercel Speed Insights or self-hosted).

Pre-release

  • LCP cause analysis (DevTools Performance insights), INP handler review, image dimensions, bundle under target, font preload, 3G Fast emulation.

Post-release

  • RUM p75 trends, incident rollback, weekly performance review.

12. Advanced patterns (2025)

  • Partial Pre-Rendering (PPR) — Next.js 15 static shell + dynamic holes.
  • Islands — Astro: static + JS islands only.
  • Qwik resumability — near-zero initial JS.
  • Bun / Deno — faster startup for SSR.
  • Turbopack — Next.js 15 default.
  • Server streaming with RSC + Suspense.

12-item checklist

  1. CWV p75 tracked via RUM?
  2. LCP<2.5s, CLS<0.1, INP<200ms at p75?
  3. LCP image has priority + fetchpriority="high"?
  4. All images have explicit width/height?
  5. Fonts use font-display + size-adjust?
  6. Initial bundle < 170kb, route < 50kb?
  7. Dynamic import for heavy code?
  8. CDN + edge caching configured?
  9. HTTP/3 enabled?
  10. Lighthouse CI catches regressions?
  11. RUM operated in production?
  12. Korean mobile/subway network tested?

10 anti-patterns

  1. Shipping without measuring real users.
  2. Optimizing for Lighthouse score but not p75 RUM.
  3. Unsized images (CLS bomb).
  4. font-display: block (FOIT hides content).
  5. Giant moment.js / lodash full imports.
  6. Runtime CSS-in-JS in hot paths.
  7. Forgetting <link rel="preload"> on LCP image.
  8. Treating INP like FID (single-interaction testing).
  9. Sampling RUM too low to detect tail regressions.
  10. Ignoring Asian/Korean network realities.

Next episode

Season 6 Episode 7: Accessibility & Internationalization 2025 — WCAG 2.2, EU Accessibility Act, ARIA, next-intl, Korean/Japanese typography, RTL.

"A fast product is a good product. A slow product is a non-existent product."

— End of Performance & Core Web Vitals.