웹폰트는 디자인의 완성도를 높이지만, 잘못 사용하면 페이지 로딩 속도와 사용자 경험에 큰 영향을 줍니다. 이 글에서는 폰트 로딩의 원리와 최적화 방법을 단계별로 정리합니다.
FOUT와 FOIT 이해하기
브라우저가 웹폰트를 불러오는 동안 텍스트를 어떻게 처리하느냐에 따라 두 가지 현상이 발생합니다.
| 현상 | 설명 | 문제점 |
|---|---|---|
| FOUT Flash Of Unstyled Text |
기본 폰트로 텍스트를 먼저 보여준 뒤 웹폰트로 교체 | 텍스트가 갑자기 바뀌며 레이아웃 이동 발생 |
| FOIT Flash Of Invisible Text |
웹폰트 로드 전까지 텍스트 숨김 | 텍스트가 늦게 나타나 콘텐츠 인식 지연 |
font-display 속성으로 제어하기
@font-face의 font-display 속성으로 로딩 동작을 제어할 수 있습니다.
@font-face {
font-family: 'MyFont';
src: url('/fonts/MyFont.woff2') format('woff2');
font-display: swap; /* 권장값 */
}
| 값 | 동작 | 추천 상황 |
|---|---|---|
auto | 브라우저 기본값 | — |
block | 폰트 로드까지 텍스트 숨김 (FOIT) | 아이콘 폰트 |
swap | 기본 폰트 먼저 표시 후 교체 (FOUT) | 본문 텍스트 ✅ |
fallback | 100ms 숨김 후 교체, 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; }
폰트 최적화 체크리스트
✅
✅ 외부 CDN에
✅ 중요 폰트 파일
✅
✅ 서브셋 또는 Variable Font 적용
✅
font-display: swap 사용✅ 외부 CDN에
preconnect 추가✅ 중요 폰트 파일
preload✅
woff2 형식만 사용 (최신 브라우저 100% 지원)✅ 서브셋 또는 Variable Font 적용