Pretendard 웹폰트
웹에서 한글 폰트를 적용하는 건 영문 폰트보다 훨씬 까다롭다. 영문은 글리프가 100개 남짓이라 폰트 파일이 수십 KB 수준이지만, 한글은 조합 가능한 음절만 11,172자여서 폰트 파일이 수 MB에 달한다. 사용자가 페이지를 열었을 때 이 무거운 파일을 통째로 내려받으면 첫 렌더링이 눈에 띄게 느려진다.
Pretendard는 이 문제를 정면으로 해결하면서도 디자인 품질을 타협하지 않은 한글 웹폰트다. Inter 폰트의 라틴 글리프 품질을 유지하면서 한글/일본어 글리프를 추가한 구조이고, 특히 웹 환경에 최적화된 배포 방식을 제공한다.
왜 시스템 폰트가 아닌 커스텀 폰트인가
시스템 폰트 스택(system-ui, -apple-system 등)을 쓰면 추가 다운로드 없이 빠르게 렌더링된다. 하지만 OS마다 기본 폰트가 다르다.
| OS | 기본 한글 폰트 | 특징 |
|---|---|---|
| macOS/iOS | Apple SD Gothic Neo | 둥글고 부드러운 느낌 |
| Windows | Malgun Gothic(맑은 고딕) | 직선적이고 각진 느낌 |
| Android | Noto Sans CJK | Google 스타일, 중립적 |
같은 디자인이 OS마다 미묘하게 달라 보이는 것이다. 브랜딩이나 디자인 시스템이 중요한 프로젝트에서는 이 차이가 크다. Pretendard는 모든 플랫폼에서 동일한 렌더링을 보장한다.
Pretendard의 특징
Inter 기반 라틴 글리프
Pretendard는 Inter 폰트의 라틴 글리프를 그대로 사용한다. Inter는 화면 가독성에 최적화된 산세리프 폰트로, 작은 크기에서도 글자가 뭉개지지 않는다. 한영 혼용이 많은 개발 관련 콘텐츠에서 특히 유리하다.
가변 폰트(Variable Font)
전통적인 웹폰트는 weight별로 별도 파일이 필요하다.
fonts/pretendard-regular.woff2 /* 400 */
fonts/pretendard-medium.woff2 /* 500 */
fonts/pretendard-semibold.woff2 /* 600 */
fonts/pretendard-bold.woff2 /* 700 */
4개 weight만 써도 파일 4개를 내려받아야 한다. 가변 폰트는 하나의 파일에 모든 weight(100~900)가 포함되어 있다.
fonts/pretendard-regular.woff2 /* 400 */
fonts/pretendard-medium.woff2 /* 500 */
fonts/pretendard-semibold.woff2 /* 600 */
fonts/pretendard-bold.woff2 /* 700 */
가변 폰트 하나의 용량이 개별 파일 4개 합산보다 작은 경우가 많아서, 여러 weight를 쓸수록 용량 이점이 커진다.
Dynamic Subset
한글 웹폰트 최적화의 핵심이다. 전체 글리프를 한 번에 보내는 대신, 사용 빈도와 유니코드 범위에 따라 잘게 쪼개 놓고 브라우저가 필요한 조각만 내려받게 하는 기술이다.
원리는 CSS의 unicode-range 디스크립터를 활용한다.
@font-face {
font-family: 'Pretendard Variable';
font-weight: 100 900;
src: url('/fonts/PretendardVariable.woff2') format('woff2');
}
/* 이제 어떤 weight든 자유롭게 사용 */
h1 { font-weight: 750; } /* 전통 폰트에서는 불가능한 중간값 */
p { font-weight: 400; }
브라우저는 페이지에 실제로 사용된 글자의 유니코드를 확인하고, 해당 범위를 포함하는 @font-face의 파일만 다운로드한다. "안녕하세요"만 표시하는 페이지라면 전체 파일의 극히 일부만 받으면 되는 것이다.
Pretendard는 이 서브셋 CSS를 미리 생성해서 CDN으로 배포하기 때문에, 개발자가 직접 서브셋팅 작업을 할 필요가 없다.
CDN으로 적용하기
가장 간편한 방법은 jsDelivr CDN에서 제공하는 CSS를 링크하는 것이다.
/* 자주 쓰는 한글 음절 (가, 나, 다...) */
@font-face {
font-family: 'Pretendard Variable';
src: url('/subset-1.woff2') format('woff2');
unicode-range: U+AC00-AD0B;
}
/* 덜 쓰는 한글 음절 */
@font-face {
font-family: 'Pretendard Variable';
src: url('/subset-2.woff2') format('woff2');
unicode-range: U+AD0C-AE00;
}
/* 라틴 글리프 */
@font-face {
font-family: 'Pretendard Variable';
src: url('/subset-latin.woff2') format('woff2');
unicode-range: U+0020-007E;
}
URL 구조를 분해해 보면:
orioncactus/pretendard— GitHub 저장소@v1.3.9— 버전 고정 (캐시 안정성)dist/web/variable/— 가변 폰트 웹 배포판pretendardvariable-dynamic-subset.min.css— 다이나믹 서브셋 + 가변 폰트 조합
이 CSS 파일 안에 수십 개의 @font-face 규칙이 unicode-range별로 정의되어 있고, 각각이 서브셋된 woff2 파일을 가리킨다.
as="style"과 crossorigin 속성
<link
rel="stylesheet"
as="style"
crossorigin=""
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css"
/>
as="style"— 브라우저에게 이 리소스가 스타일시트임을 미리 알려서 우선순위를 높인다crossorigin=""— CDN에서 폰트를 받을 때 CORS 요청을 보낸다. 이게 없으면 브라우저가 폰트 파일을 두 번 다운로드하는 버그가 발생할 수 있다 (한 번은 anonymous 모드, 한 번은 CORS 모드)
CSS에서 폰트 스택 설정
CDN 링크를 추가한 뒤, CSS에서 폰트 패밀리를 지정한다.
<link rel="stylesheet" as="style" crossorigin="" href="..." />
폴백 순서가 중요하다.
- Pretendard Variable — 로딩 완료 시 사용
- -apple-system — macOS/iOS에서 Pretendard 로딩 전 사용
- BlinkMacSystemFont — Chrome on macOS 구버전 호환
- system-ui — 나머지 OS의 시스템 폰트
- sans-serif — 최후의 폴백
이 순서 덕분에 Pretendard가 로딩되기 전에도 시스템 폰트로 텍스트가 바로 보인다.
Next.js에서의 적용
Next.js에서는 next/font를 통해 폰트를 최적화하는 것이 권장되지만, Pretendard처럼 CDN 기반 다이나믹 서브셋을 사용하는 경우에는 <link> 태그로 직접 로딩하는 방식이 더 적합하다.
:root {
--font-family-main: 'Pretendard Variable', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
}
html {
font-family: var(--font-family-main);
}
여기서 next/font의 Inter와 CDN Pretendard를 동시에 사용하는 이유가 있다. next/font로 로딩한 Inter는 CSS 변수(--font-inter)로 등록되어 라틴 전용 컨텍스트에서 선택적으로 사용할 수 있고, Pretendard는 전체 UI의 기본 폰트로 동작한다.
Tailwind CSS 연동
Tailwind에서 Pretendard를 기본 sans-serif 폰트로 설정하려면 CSS 변수를 활용한다.
// app/layout.tsx
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
variable: '--font-inter',
});
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ko">
<head>
<link
rel="stylesheet"
as="style"
crossOrigin=""
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css"
/>
</head>
<body className={`${inter.variable} font-pretendard`}>
{children}
</body>
</html>
);
}
/* globals.css */
:root {
--font-sans: 'Pretendard Variable', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
}
이제 font-pretendard 클래스로 어디서든 적용할 수 있다.
font-display 전략
웹폰트 로딩 중 텍스트를 어떻게 처리할지 결정하는 font-display 속성이 있다.
| 값 | 동작 |
|---|---|
auto | 브라우저 기본 동작 (보통 block) |
block | 폰트 로딩될 때까지 텍스트 숨김 (FOIT) |
swap | 시스템 폰트로 즉시 표시 → 로딩 후 교체 (FOUT) |
fallback | 짧은 block → 짧은 swap → 이후 로딩 안 되면 폴백 유지 |
optional | 짧은 block → 캐시에 있으면 사용, 없으면 폴백 유지 |
Pretendard의 CDN CSS는 font-display: swap을 사용한다. 즉, 폰트가 로딩되기 전에는 시스템 폰트로 텍스트를 먼저 보여주고, 로딩이 완료되면 Pretendard로 교체한다.
이 방식의 장점은 사용자가 빈 화면을 보지 않는다는 것이다. 단점은 폰트 교체 시 텍스트가 살짝 깜빡이는 FOUT(Flash of Unstyled Text)가 발생할 수 있다는 것인데, 다이나믹 서브셋으로 파일 크기가 작아서 실제로는 거의 눈에 띄지 않는다.
셀프 호스팅 vs CDN
CDN이 아닌 자체 서버에서 폰트를 호스팅할 수도 있다.
CDN 방식의 장점:
- 설정이 간단 (link 태그 한 줄)
- jsDelivr의 글로벌 엣지 서버 활용
- 다이나믹 서브셋 CSS가 이미 생성되어 있음
셀프 호스팅의 장점:
- 외부 CDN 의존성 제거
- 서비스 워커 캐시 완전 제어
- CSP(Content Security Policy) 설정이 단순
셀프 호스팅 시에는 Pretendard 저장소의 dist/web/variable/ 폴더를 통째로 가져와서 public/fonts/에 넣으면 된다. 다만 서브셋 CSS의 URL을 자신의 도메인으로 수정해야 하므로 빌드 스크립트가 필요할 수 있다.
성능 최적화 팁
preconnect로 DNS 시간 단축
CDN을 사용한다면 DNS 조회와 TLS 핸드셰이크를 미리 수행해서 실제 폰트 요청 시 대기 시간을 줄일 수 있다.
// tailwind.config.js
module.exports = {
theme: {
extend: {
fontFamily: {
pretendard: ['var(--font-sans)'],
},
},
},
};
핵심 weight만 preload
모든 서브셋을 preload하는 건 역효과지만, 가장 많이 쓰는 weight의 라틴 서브셋 정도는 preload할 가치가 있다.
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
단, preload는 반드시 사용할 리소스에만 적용해야 한다. 안 쓰는 파일을 preload하면 오히려 대역폭 낭비다.
정리
Pretendard 웹폰트의 핵심은 세 가지다.
- 가변 폰트 — 하나의 파일로 모든 weight를 커버해서 HTTP 요청과 총 용량을 줄인다
- 다이나믹 서브셋 —
unicode-range로 필요한 글리프만 다운로드해서 한글 폰트의 고질적인 용량 문제를 해결한다 - CDN 배포 — 복잡한 서브셋팅과
@font-face설정을 미리 해두어서 link 태그 하나로 적용할 수 있다
한글 웹 프로젝트에서 디자인 일관성과 성능을 동시에 잡으려면, 현재로서는 Pretendard + 다이나믹 서브셋 CDN 조합이 가장 실용적인 선택이다.