당신은 폰트를 잘못 로드하고 있습니다 (그리고 이것이 성능을 저해하고 있습니다)
(jonoalderson.com)- 웹폰트는 웹사이트의 시각적 요소로, 브랜드와 사용자 경험을 형성하며, 성능과 접근성에 직접적인 영향을 미침
- 잘못된 폰트 로딩 방식은 FOUT(스타일 없는 텍스트 깜빡임) 또는 FOIT(보이지 않는 텍스트 깜빡임) 문제를 일으키며, 이는 Core Web Vitals에 부정적인 영향을 끼침
- WOFF2 형식은 현대적이고 효율적인 폰트 포맷으로, 대부분의 최신 브라우저에서 지원되며, 불필요한 레거시 포맷을 제거해 성능을 개선
- 폰트 서브셋팅과 preload 전략은 불필요한 데이터 전송을 줄이고, 페이지 로딩 속도를 높이는 데 필수적
- 시스템 폰트 스택과 CSS 디스크립터를 활용해 폰트 로딩 시 레이아웃 이동(CLS)을 최소화하고 안정적인 사용자 경험을 제공
웹폰트의 간략한 역사
웹폰트는 웹 디자인과 사용자 경험의 핵심 요소로, 그 중요성에도 불구하고 많은 사람들이 잘못된 방식으로 사용하고 있음. 아래는 웹폰트의 발전 과정을 정리.
-
"웹 세이프" 시대
- 초기 웹에서는 Arial, Times New Roman 같은 웹 세이프 폰트만 사용 가능했으며, 커스텀 폰트는 이미지로 대체
- 브라우저마다 폰트 렌더링이 달라 일관된 디자인이 어려웠음
-
@font-face 이전의 해킹: sIFR과 Cufón
- sIFR: Flash를 사용해 텍스트를 동적으로 렌더링했으나 무겁고 접근성이 떨어짐
- Cufón: JavaScript로 폰트를 벡터 그래픽으로 변환해 삽입했지만 느리고 접근성 문제 유지
-
@font-face의 등장
- @font-face는 CSS로 커스텀 폰트를 삽입할 수 있게 했으나, 브라우저마다 다른 포맷(EOT, SVG 폰트, TTF/OTF)을 요구해 복잡
- 폰트 라이선스 문제와 불법 복제가 만연했음
-
상용 서비스: Typekit과 동료들
- Typekit(현 Adobe Fonts)은 라이선스와 호환성 문제를 해결한 구독 기반 서비스로, JavaScript 스니펫을 통해 폰트를 제공
- 제3자 스크립트에 의존하는 패턴이 오늘날까지 이어짐
-
호환성 해킹과 우회 방법
- 여러 포맷을 호스팅하거나, FOUT와 FOIT를 해결하기 위한 JavaScript 수정이 필요했음
- 아이콘 폰트를 사용해 글리프 부족 문제를 해결하려는 시도가 있었음
-
Google Fonts와 "무료 폰트" 붐
- Google Fonts는 무료로 제공되는 오픈 라이선스 폰트를 통해 폰트 로딩의 편리함을 제공했으나, GDPR 위반 문제와 느린 로딩 속도로 인해 새로운 문제를 야기
- 라이선스 제한으로 인해 최적화가 어려운 상용 폰트와 달리, Google Fonts는 자유로운 사용이 가능했음
폰트의 작동 방식 (기본)
폰트는 단순한 CSS 설정이 아니라, 브라우저의 렌더링 파이프라인에 깊이 관여하는 복잡한 요소임.
-
포맷: TTF에서 WOFF2까지
- TTF/OTF: 데스크톱 중심의 무거운 포맷
- WOFF2: Brotli 압축을 사용한 현대적이고 효율적인 웹폰트 포맷으로, 대부분의 프로젝트에 적합
-
렌더링 파이프라인
- 폰트 로딩은 등록, 스타일 해결, 폰트 매칭, 글리프 커버리지, 요청, 디스플레이 단계, 디코딩 및 셰이핑의 단계를 거침
- font-display 설정(swap, block, fallback, optional)은 텍스트 표시 방식을 결정
-
메트릭
- Ascent, descent, line gap 같은 메트릭은 폰트의 높이와 간격을 정의
- 폰트 교체 시 메트릭 불일치로 레이아웃 이동(CLS)이 발생할 수 있음
-
합성 스타일
- 브라우저가 요청한 폰트 웨이트나 스타일을 찾지 못하면, 가짜 굵기나 이탤릭을 생성해 품질이 저하
- font-synthesis: none; 으로 가짜 스타일 생성을 방지 가능
-
글리프 커버리지
- 폰트는 모든 문자를 포함하지 않으며, 누락된 글리프는 대체 폰트로 렌더링되어 일관성 문제 발생
- unicode-range를 사용해 필요한 글리프만 로드하도록 설정
성능 및 전략 기초
폰트는 핵심 렌더링 경로에 영향을 미치며, 잘못된 관리로 인해 성능이 저하될 수 있음.
-
파일 크기
- 단일 폰트 패밀리는 최대 800KB에 달할 수 있으며, 불필요한 글리프 포함으로 데이터 낭비 발생
- 폰트 서브셋팅으로 필요한 글리프만 전송해 크기 최적화
-
레이아웃 이동
- 대체 폰트와 커스텀 폰트의 메트릭 차이로 인해 CLS 발생
- size-adjust, ascent-override 같은 CSS 디스크립터로 레이아웃 안정화
-
현대적 CSS 디스크립터
- font-display: swap; 은 대체 폰트를 즉시 표시해 안정적인 렌더링 제공
- unicode-range를 통해 특정 스크립트에 필요한 글리프만 로드
가변 폰트: 약속 대 현실
가변 폰트는 하나의 파일로 다양한 스타일과 웨이트를 지원해 효율성을 높일 수 있음.
-
약속
- 여러 정적 파일을 단일 파일로 통합
- 뷰포트 크기에 따라 동적으로 조정 가능한 반응형 타이포그래피
-
현실
- 필요한 웨이트가 적다면 가변 폰트가 더 무거울 수 있음
- 브라우저 지원이 일부 축에서 제한적이며, 라이선스 문제가 발생 가능
-
성능 전략
- 필요한 축만 선택하고, 스크립트별 서브셋팅으로 파일 크기 최적화
- 정적 폰트와 비교해 실제 이점이 있는지 확인
-
CSS에서 가변 폰트 축 사용 예시
@font-face { font-family: "Acme Variable"; src: url("/fonts/acme-variable.woff2") format("woff2-variations"); font-weight: 100 900; font-display: swap; } h1 { font-family: "Acme Variable", system-ui, sans-serif; font-weight: 700; }
시스템 스택과 CDN
커스텀 폰트 없이 시스템 폰트 스택을 사용하면 즉각적인 로딩과 친숙한 경험 제공.
-
시스템 폰트 스택
- -apple-system, Segoe UI 같은 폰트로 구성된 스택은 모든 플랫폼에서 일관성 유지
- 이모지 렌더링에서 시스템 폰트가 더 나은 성능 제공
-
CDN과 제3자 호스팅
- Google Fonts는 데이터 유출로 인해 GDPR 위반 가능성 있음
- 셀프 호스팅으로 DNS 조회 지연을 줄이고 캐싱 제어 가능
대체 폰트와 매칭
대체 폰트는 커스텀 폰트 로드 전 사용자 경험을 결정하며, 안정적인 설계가 필요함.
-
대체 폰트 설계
- x-height와 문자 폭을 커스텀 폰트와 유사하게 설정해 CLS 최소화
- font-size-adjust로 대체 폰트의 크기 조정
-
커스텀 및 대체 폰트 매칭
- 비슷한 비율의 폰트를 선택하고, 메트릭 조정으로 레이아웃 안정성 확보
- 플랫폼별 렌더링 차이를 고려해 안정성과 가독성 우선
프리로딩 및 로딩 전략
폰트 전달 전략은 사용자 경험에 큰 영향을 미침.
-
로딩 결과
- FOIT는 느린 네트워크에서 텍스트가 보이지 않는 문제 발생
- font-display: swap; 은 안전한 기본값으로 즉시 대체 폰트 표시
-
프리로딩
-
<link rel="preload" as="font">
를 사용해 폰트 로딩을 즉시 시작 - CORS 헤더와 정확한 URL 매칭이 필수
-
-
Early Hints (HTTP 103)
- 서버가 HTML 응답 전에 폰트를 가져오도록 지시해 로딩 시간 단축
- 크리티컬 폰트만 힌트로 지정해 대역폭 낭비 방지
-
폰트 로딩 API
- Font Loading API는 동적 사이트에서 폰트 로딩을 세밀히 제어 가능
파일 포맷: WOFF2, WOFF, TTF와 레거시 부담
WOFF2는 현대 웹에서 가장 효율적인 포맷으로, 대부분의 경우 단일 포맷으로 충분.
- WOFF2만 사용해 불필요한 포맷 제거
- base64 임베딩은 캐싱을 방해하므로 피해야 함
아이콘 폰트: Font Awesome과 큰 실수
아이콘 폰트는 접근성과 성능 문제로 인해 현대 웹에서 적합하지 않음.
- SVG 아이콘은 의미적이고 유연하며, CSS로 스타일링 가능
- 기존 아이콘 폰트 사용 시 서브셋팅과 SVG로의 전환 계획 필요
라틴을 넘어: 비라틴 스크립트, RTL 언어, 이모지
비라틴 스크립트와 RTL 언어는 복잡한 셰이핑과 메트릭을 요구.
- 서브셋팅 시 스크립트별 특성을 고려해 렌더링 오류 방지
- 이모지는 시스템 폰트를 사용해 일관성과 성능 개선
웹폰트의 미래: 진화하는 표준과 현대적 위험
새로운 CSS 속성과 가변 폰트, 컬러 폰트가 웹 타이포그래피를 발전시킴.
- 폰트 로딩 API와 Early Hints로 SPA에서의 지연 문제 해결
- 폰트를 인프라로 간주하고, 성능과 접근성을 우선시해야 함
도구와 감사
폰트 성능은 DevTools, Lighthouse, Glyphhanger 같은 도구로 측정 가능.
- 폰트 서브셋팅 도구로 불필요한 글리프 제거
- Font Style Matcher로 대체 폰트 메트릭 조정
폰트를 올바르게 다루기 위한 선언
폰트는 단순한 장식이 아니라 사용자 경험과 성능의 핵심 요소임.
- 시스템 우선: 견고한 시스템 폰트 스택으로 시작
- 지능적 서브셋팅: 필요한 글리프만 전송
- WOFF2 전용: 레거시 포맷 제거
- 글로벌 스크립트 존중: 다양한 언어와 이모지 지원
- 테스트 중요: 다양한 네트워크와 디바이스에서 테스트
폰트를 콘텐츠이자 브랜드로 간주하고, 성능과 접근성에 대한 엄격한 관리를 적용해야 함