웹폰트는 디자인의 완성도를 높이지만, 잘못 사용하면 페이지 로딩 속도와 사용자 경험에 큰 영향을 줍니다. 이 글에서는 폰트 로딩의 원리와 최적화 방법을 단계별로 정리합니다.

FOUT와 FOIT 이해하기

브라우저가 웹폰트를 불러오는 동안 텍스트를 어떻게 처리하느냐에 따라 두 가지 현상이 발생합니다.

현상설명문제점
FOUT
Flash Of Unstyled Text
기본 폰트로 텍스트를 먼저 보여준 뒤 웹폰트로 교체 텍스트가 갑자기 바뀌며 레이아웃 이동 발생
FOIT
Flash Of Invisible Text
웹폰트 로드 전까지 텍스트 숨김 텍스트가 늦게 나타나 콘텐츠 인식 지연

font-display 속성으로 제어하기

@font-facefont-display 속성으로 로딩 동작을 제어할 수 있습니다.

@font-face {
  font-family: 'MyFont';
  src: url('/fonts/MyFont.woff2') format('woff2');
  font-display: swap; /* 권장값 */
}
동작추천 상황
auto브라우저 기본값
block폰트 로드까지 텍스트 숨김 (FOIT)아이콘 폰트
swap기본 폰트 먼저 표시 후 교체 (FOUT)본문 텍스트 ✅
fallback100ms 숨김 후 교체, 3초 후 기본 폰트 확정중요한 텍스트
optional빠르게 로드되면 사용, 아니면 기본 폰트 유지장식 폰트

preconnect로 연결 미리 시작하기

Google Fonts 같은 외부 CDN을 사용한다면 <link rel="preconnect">로 DNS 조회와 TCP 연결을 미리 시작할 수 있습니다.

<!-- DNS + TCP + TLS 핸드셰이크를 미리 시작 -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- 그 다음 폰트 CSS 로드 -->
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swap" rel="stylesheet">
crossorigin 속성이 없으면 폰트 파일 자체의 연결(fonts.gstatic.com)에서 preconnect가 제대로 동작하지 않습니다. 반드시 추가하세요.

폰트 파일 자체를 preload하기

가장 중요한 폰트 파일을 직접 preload하면 더 빠릅니다.

<link
  rel="preload"
  href="/fonts/Pretendard-Regular.woff2"
  as="font"
  type="font/woff2"
  crossorigin
>

서브셋(Subset) 폰트 사용하기

한국어 폰트는 수천 개의 글리프를 포함하여 파일 크기가 큽니다. 실제 사용하는 글자만 추출한 서브셋을 사용하면 크기를 90% 이상 줄일 수 있습니다.

# pyftsubset으로 서브셋 생성 (fonttools 필요)
pip install fonttools

pyftsubset NotoSansKR-Regular.ttf \
  --unicodes="U+AC00-D7A3,U+0030-0039,U+0041-005A,U+0061-007A" \
  --layout-features="*" \
  --flavor=woff2 \
  --output-file="NotoSansKR-subset.woff2"

Variable Font 활용하기

여러 굵기(weight)의 폰트를 각각 불러오는 대신, Variable Font 하나로 모든 굵기를 사용할 수 있습니다.

@font-face {
  font-family: 'Pretendard Variable';
  src: url('/fonts/PretendardVariable.woff2') format('woff2-variations');
  font-weight: 100 900; /* 전체 weight 범위 지원 */
  font-display: swap;
}

/* 이제 어떤 weight도 자유롭게 */
h1 { font-weight: 800; }
p  { font-weight: 400; }
small { font-weight: 300; }
폰트 최적화 체크리스트
font-display: swap 사용
✅ 외부 CDN에 preconnect 추가
✅ 중요 폰트 파일 preload
woff2 형식만 사용 (최신 브라우저 100% 지원)
✅ 서브셋 또는 Variable Font 적용