Web Performance

웹 폰트는 여전히 대부분의 사이트에서 가장 쉬운 성능 개선책입니다

variable fonts가 출시된 지 5년, WOFF2가 보편화된 지 10년이 지났지만, 평균적인 사이트는 여전히 폰트를 잘못 로드하고 있습니다. 올바르게 처리하는 방법의 짧은 요약입니다.

The Wux Webtools Team The Wux Webtools Team 5 읽기 최소 시간
Editorial illustration of a single bold letter glyph with subtle weight axis lines, soft green palette
목차
  1. 계속 반복되는 패턴
  2. 여섯 개의 static font 대신 하나의 variable font를 사용하세요
  3. 합리적인 `font-display`를 설정하세요
  4. fallback metrics를 맞추세요
  5. Self-host하세요
  6. custom font를 완전히 건너뛸 때
  7. 솔직한 요약

계속 반복되는 패턴

오늘 무작위로 운영 중인 웹사이트 열 곳을 감사해 보면, 대부분에서 거의 같은 폰트 상황을 발견하게 됩니다:

  • 홈 페이지에서 여섯 개에서 열 개의 폰트 파일을 로드함
  • 모두 WOFF2인 점은 좋지만, font-display 전략이 없음
  • 페이지 어디에서도 사용하지 않는 여러 굵기와 스타일이 포함됨
  • 전체 스택을 서드파티 도메인(대개 Google Fonts)에서 제공해 DNS, TLS, 개인정보 비용이 모두 따라옴
  • unicode-range 서브세팅이 없어, 페이지가 영어여도 모든 방문자가 키릴 문자와 그리스 문자 glyph까지 다운로드함

이는 작은 사이트만의 문제가 아닙니다. 충분한 예산이 있는 마케팅 페이지도 첫 문단을 그릴 수 있기 전에 600 KB의 폰트를 로드하는 경우가 많습니다. 이 패턴이 보이기 시작하면 더는 보지 않을 수 없습니다.

해결책은 특별하지 않습니다. 수년 전부터 브라우저에 존재해 온, 잘 알려진 기법 몇 가지입니다.

여섯 개의 static font 대신 하나의 variable font를 사용하세요

Inter Regular, Inter Medium, Inter SemiBold, Inter Bold 그리고 각각의 italic을 로드하고 있다면, 필요한 것보다 대략 여섯 배 많은 바이트를 다운로드하는 셈입니다. 하나의 Inter variable font는 전체 weight axis(일부 빌드에서는 slant까지)를 하나의 파일로 다루며, 크기는 static weight 두 개보다 약간 큰 정도에 그칩니다.

브라우저 지원 이야기는 이미 오래전에 정리되었습니다 — variable fonts는 중요한 모든 환경에서 동작합니다. 남아 있는 망설임은 대부분 static-font 시대의 관성입니다.

실용적인 기준은 이렇습니다: script별, family별로 variable font 파일 하나. Latin은 하나의 파일, Cyrillic은 다른 파일, Greek은 세 번째 파일로 두고, unicode-range로 조건부 로드합니다. 그게 전부입니다.

합리적인 font-display를 설정하세요

custom font가 아직 로딩 중일 때의 기본 동작은 최대 3초 동안 아무것도 보여주지 않는 것입니다 — 보이지 않는 텍스트입니다. 이는 가능한 최악의 기본값입니다. 사용자는 빈 페이지를 보고 무언가 고장 났다고 생각합니다.

모든 @font-face 규칙에 다음을 추가하세요:

@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-var.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-display: swap;
}

swap은 fallback font를 즉시 보여주고, custom font가 로드되면 교체합니다. 사용자는 0밀리초 시점부터 페이지를 읽을 수 있습니다. 절충점은 교체가 일어날 때 짧은 layout shift가 생긴다는 것인데, 다음 기법으로 완화할 수 있습니다.

fallback metrics를 맞추세요

unstyled text의 flash가 거슬리게 느껴지는 경우는 fallback과 custom font의 metrics가 크게 다를 때뿐입니다. 현대 CSS는 size-adjust, ascent-override 등으로 이를 해결합니다:

@font-face {
  font-family: 'Inter Fallback';
  src: local('Arial');
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

fallback metrics를 조정하면 교체는 거의 감지되지 않습니다 — custom font가 도착하기 전후로 단어가 같은 가로 공간을 차지합니다.

Google의 --allow-fallback-font-metrics 작업은 이제 baseline browser support가 되었고, 올바른 값을 몇 초 안에 계산해 주는 tooling pipeline(fontaine library 및 유사 도구)도 있습니다.

Self-host하세요

Four-step self-hosted font pipeline: get WOFF2 variable file, subset by script, serve from same origin with immutable cache, preload critical weight
InfographicSelf-hosting web fonts: the simple delivery pipeline — A same-origin font pipeline cuts extra origin cost and removes the privacy question

Google Fonts는 편리하고 무료지만, 두 가지 실제 비용을 동반합니다:

  1. 두 번째 TLS handshake. HTTP/3와 connection coalescing이 있어도 추가 origin은 거의 무료가 아닙니다.
  2. 개인정보 및 컴플라이언스 문제. 여러 유럽 법원은 fonts.gstatic.com에서 Google Fonts를 로드하는 것이 개인 데이터(IP 주소)를 제3자에게 전송하는 행위에 해당한다고 판단했습니다. Self-hosting은 이 문제를 완전히 제거합니다.

다운로드 후 호스팅하는 pipeline은 다음과 같습니다:

  1. WOFF2 파일을 받습니다(variable build가 있으면 그것을 사용)
  2. 실제 audience가 사용하는 script로 서브셋합니다
  3. 사이트의 나머지 리소스와 같은 origin에서 제공하고, 긴 Cache-Control: max-age=31536000, immutable을 설정합니다
  4. 가장 중요한 weight를 preload합니다: <link rel="preload" as="font" type="font/woff2" href="/fonts/inter-var.woff2" crossorigin>

이것이 전체 pipeline입니다. 기존 사이트에도 오후 한나절이면 적용할 수 있고, 한 번 적용하면 거의 되돌아가지 않습니다.

custom font를 완전히 건너뛸 때

분명히 말할 가치가 있습니다. 모든 사이트에 custom font가 필요한 것은 아닙니다. system font stack은 이제 모든 운영체제에서 충분히 아름답습니다:

font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Inter, sans-serif;

weight는 적절하고, metrics도 맞으며, rendering은 기기에 맞게 조정되어 있고, 전송되는 바이트 비용은 정확히 0입니다. 도구 사이트, 내부 앱, 콘텐츠를 우선하는 포트폴리오, 느린 네트워크 사용자를 대상으로 하는 모든 것에는 system stack이 올바른 답입니다.

<!-- tool-cta:start -->

💡 시도해 보세요: Webfont Generator를 사용하여 TTF 또는 OTF 파일을 게시물에서 권장하는 형식 전환인 바로 사용할 수 있는 CSS가 포함된 최신 WOFF2로 변환하세요.

<!-- tool-cta:end -->

솔직한 요약

일반적인 소규모 사이트라면, 네 단계로 web-font 성능 이야기를 모두 다룰 수 있습니다:

  1. family별 script별 하나의 variable font
  2. matched fallback metrics와 함께 font-display: swap
  3. 긴 cache header와 critical weight에 대한 preload를 갖춘 Self-hosting
  4. 또는 폰트를 완전히 건너뛰고 system stack 사용

이 작업을 한 번 해두면 홈 페이지에서 수백 킬로바이트를 되찾고, 체감 성능에서 수백 밀리초를 얻으며, 그 과정에서 서드파티 의존성도 제거할 수 있습니다. 노력 대비 효과가 더 좋은 변경은 많지 않습니다.

Four-step checklist for faster web fonts: variable font, font-display swap with matched fallback metrics, self-host with cache and preload, or use system stack
InfographicThe 4-step web font performance fix — A compact playbook for reclaiming several hundred kilobytes and improving perceived performance
Comparison of six static font files versus one variable font file with script-based subsetting for Latin, Cyrillic, and Greek
InfographicFrom six static font files to one variable font — One variable file can replace a pile of weights and italics with far fewer bytes

자주 묻는 질문

variable fonts는 어디서나 지원되나요?
네 — 중요한 모든 브라우저는 수년 전부터 variable font 지원을 제공해 왔습니다. 가끔 들리는 망설임은 static-font 시대의 관성일 뿐이며, 2026년에 실제 호환성 문제는 아닙니다.
폰트를 수동으로 서브셋해야 하나요?
Latin-only 사이트라면 그렇습니다 — Latin subset은 전체 multilingual 파일의 대략 절반 크기입니다. multilingual 사이트라면 `unicode-range`를 사용해 각 script를 별도 파일로 로드하세요. 그러면 방문자는 콘텐츠에 실제로 필요한 것만 다운로드합니다.
font-display: swap이 가끔 보기 싫은 flash를 만드는 이유는 무엇인가요?
fallback font의 metrics가 custom font와 달라서, 교체가 일어날 때 단어가 다시 배치되기 때문입니다. fallback에 `size-adjust`, `ascent-override`, `descent-override`를 사용해 custom font의 metrics와 맞추세요 — flash는 거의 보이지 않게 됩니다.
Google Fonts가 정말 개인정보 문제인가요?
여러 유럽 법원 판결은 `fonts.gstatic.com`에서 로드하는 행위가 방문자의 IP를 동의 없이 제3자에게 전송하며, 일부 해석에서는 GDPR 위반이라고 보았습니다. Self-hosting은 이 문제를 완전히 제거하고, 대개 더 빠르기도 합니다.

출처 및 추가 읽기

  1. MDN — `@font-face` and `font-display`
  2. MDN — Variable fonts guide
  3. web.dev — Reduce web font size
저자에 대하여
The Wux Webtools Team

마지막 업데이트:

계속 읽기