Skip to content
기능요금제제휴블로그도움말회사 소개문의하기
무료로 시작하기로그인
블로그로 돌아가기
guides2026-10-056 분 읽기

QR 메뉴 CDN 최적화: 약한 4G에서 0.8초 로딩

이즈미르 카라부른의 해안 레스토랑이 Cloudflare Workers, Brotli, AVIF로 LCP를 9.2초에서 0.8초로 단축했습니다.

th

thMenu Team

thmenu.com

카라부른 반도의 해산물 식당이 성수기에 문의를 보냈습니다. "메뉴가 열리지 않아 손님이 자리를 뜬다." Vodafone 4G는 1.4 Mbps, Lighthouse LCP는 9.2초였습니다. 목표는 명확했죠. LCP 1초 미만, 종업원 호출 버튼을 1.5초 안에 탭 가능하게.

엣지 스택: Workers와 HTTP/3

첫 번째 단계는 Next.js SSR로 가지 않고 Cloudflare Workers의 KV 캐시에서 렌더된 HTML을 바로 내려주는 것. TTFB 38 ms를 확보했습니다. HTTP/3(QUIC)는 4G 패킷 손실에도 재핸드셰이크 없이 유지됩니다. H/2가 1.6초 걸린 핸드셰이크를 H/3는 240 ms에 끝냅니다.

Brotli 레벨 11: HTML 22 KB → 6 KB, CSS 41 KB → 9 KB. gzip 대비 34% 적은 바이트. 오리진 응답에 content-encoding: br이 있는지 확인하세요.

이미지 파이프라인: AVIF + 지연 로드

제품 사진이 전체 용량의 72%였습니다. Image Resizing이 96, 320, 640px 세 크기를 만들고 AVIF, WebP, JPEG 순으로 협상합니다. 320px AVIF 평균 14 KB, 원본 JPEG의 6분의 1.

  • 퍼스트뷰: eager + fetchpriority="high"
  • 스크롤 아래: IntersectionObserver, rootMargin 200px
  • LQIP: 8×8 blurhash, 60바이트 미만

폰트 서브셋과 크리티컬 CSS

Inter Variable 폰트는 312 KB. glyphhanger로 터키어 U+0100-017F 범위만 남겨 28 KB WOFF2로 만들었습니다. font-display: optional로 100 ms 예산을 넘기면 시스템 폰트가 그대로 유지됩니다.

퍼스트뷰용 CSS 4 KB는 head에 인라인, 나머지는 media="print" onload 트릭으로 비동기 로딩. 렌더 차단 요청 7개에서 1개로, 최종 LCP 0.78초.

FAQ

Cache-Control 권장 값은? HTML은 s-maxage=300, stale-while-revalidate=86400, 해시 자산은 immutable, max-age=31536000.

Service Worker 가치 있나요? 네. 재방문은 180 ms 안에 열립니다. App Shell + Workbox SWR.

2G에서는? Save-Data를 존중하고 96px 이미지만, 이모지 대체, 시스템 폰트로 처리하면 LCP 2.5초 이하 유지.

도움이 되셨나요? 공유해 주세요.