웹 폰트

웹에서 제공되는 정보의 95% 이상은 문어(written language)의 형태입니다. 좋은 타이포그래피는 사용자의 가독성, 접근성, 사용성 등을 사용자 경험을 향상시킬 수 있습니다. 이처럼 웹에서 타이포그래피는 중요합니다.웹 폰트(Web Font)는 디자이너가 원하는 타이포그래피를 사용자가 폰트를 설치하지 않아도 웹 페이지에 구현할 수 있게 하는 기술입니다.

사용 방법

웹 폰트는 아래처럼 CSS의 @font-face 규칙을 사용해 적용합니다.

@font-face {
  font-family: 'Awesome Font';
  src: local('Awesome Font'),
       url('/fonts/awesome.woff2') format('woff2'),
       url('/fonts/awesome.woff') format('woff'),
       url('/fonts/awesome.ttf') format('truetype'),
       url('/fonts/awesome.eot') format('embedded-opentype');
}

.title {
	font-family: 'Awesome Font', AppleSDGothicNeo, sans-serif;
}

@font-face 규칙에는 두 가지 주요 속성이 있습니다. font-family 속성은 웹 폰트의 이름을 지정합니다. src 속성은 폰트 파일의 경로와 형식을 지정합니다. src 속성을 통해 글꼴 파일의 경로를 지정하는 방식은 위의 예시처럼 두 가지가 존재합니다.

local() 지시문을 사용하면 로컬에 설치된 글꼴을 사용할 수 있으며, url() 지시문을 사용하면 외부 글꼴을 사용할 수 있습니다. 이때 format() 지시문을 통해 형식 힌트를 선택적으로 명시할 수 있으나 명시하는 것이 권장되는 방법입니다. 그 이유는 형식 힌트가 존재하면 브라우저는 다운로드를 시작하기 전에 힌트를 통해 이 형식을 브라우저가 지원하는지 확인하기 때문입니다. 해당 형식을 지원하지 않을 경우엔 그 다음 항목으로 진행합니다. 하지만, 형식 힌트가 존재하지 않는다면 브라우저가 먼저 리소스를 다운로드한 뒤 그 다음 사용가능성을 확인합니다. 이 경우엔 불필요한 리소스 요청이 발생할 수 있습니다. 그리고 src 속성에서 글꼴 버전이 지정되는 순서는 중요합니다. 왜냐하면 브라우저는 첫번째 항목부터 해당 방식이 사용가능한지 확인하기 때문입니다.

문제점

웹 폰트를 사용하는 것은 결국 추가 리소스를 요청하는 것입니다. 추가적인 리소스 요청이 마무리되지 않는다면, 의도한 글꼴이 보이지 않을뿐만 아니라 요청이 마무리될 때까지 해당 글꼴이 적용된 텍스트가 보이지 않을 수도 있습니다. 따라서 웹 폰트를 사용하면서 생길 수 있는 문제점은 글꼴이 로드되는 시간동안 발생하기 때문에, 이를 해결하기 위해선 해당 글꼴 로딩 시간을 최대한 줄여야합니다.

최적화 방법들

아래는 웹 폰트 최적화 방법에 대한 소개입니다. 그러나 이 방법들은 상호배타적이지 않으니, 적절히 혼용해서 사용할 수 있습니다.

1. 파일 크기 줄이기

글꼴 파일을 로드하는 시간을 줄이는 방법 중 하나는 요청하는 리소스의 크기를 줄이는 것입니다. 이에 대해선 여러 방식이 존재합니다.

1.1 WOFF 2.0 형식 폰트

폰트의 형식은 대표적으로 4가지가 존재하며, 다음은 각 형식에 대한 정의입니다.

1. TTF/OTF (TrueType and OpenType) font
Support for the TrueType (.ttf) and OpenType (.otf) outline font formats in @font-face.

2. EOT (Embedded OpenType) font
A compact form of OpenType fonts designed by Microsoft for use as embedded fonts on web pages. They are supported only by Microsoft Internet Explorer, as opposed to competing WOFF files.

3. WOFF (Web Open Font Format)
Compressed TrueType/OpenType font that contains information about the font’s source.

4. WOFF 2.0 (Web Open Font Format 2.0)
TrueType/OpenType font that provides better compression than WOFF 1.0.

위를 보면 알 수 있듯이 형식을 WOFF2로 한다면 크기를 최대한 줄일 수 있습니다. 실제로 나눔스퀘어라운드 폰트 파일의 형식에 따른 크기를 비교한 것입니다.

위를 보면 알 수 있듯이 WOFF2 형식이 가장 작은 크기를 가지는 것을 볼 수 있습니다. 그러나 WOFF2 형식은 모든 브라우저에서 지원하지 않습니다. 그리고 폰트 형식 마다 브라우저 지원 범위가 다릅니다. 다음은 브라우저 별 형식 지원 표입니다.

Font formatIEChromeFirefoxSafariOpera
TTF/OTF9.0*4.03.53.110.0
EOT6.0xxxx
WOFF9.05.03.65.111.5
WOFF2x36.039.010.0*23.0

이런 특징을 활용하여 웹 폰트를 사용할 때, WOFF 2.0 - WOFF - TTF/OTF - EOT 순으로 폰트 형식 지원여부를 확인하여 요청할 폰트 파일의 크기를 줄일 수 있습니다.

1.2. 파일 압축해서 제공하기

폰트 형식 중 EOT 혹은 TTF/OTF 인 파일은 기본적으로 압축되지 않은 파일입니다. 만약 해당 형식 파일을 서버가 제공해야 한다면, 제공 시 GZIP 압축을 적용하는 것으로도 전송할 파일의 크기를 줄일 수 있습니다. 이 링크에서는 WOFF2 형식의 성능을 보여주지만, 역으로는 GZIP 압축을 통해 파일 크기를 크게 줄일 수 있다는 것 또한 보여줍니다. 그러나 WOFF, WOFF2인 경우는 이미 압축이 되어있기 때문에, 오히려 한번 더 압축한다면 파일의 크기가 늘어날 수 있으므로 압축하지 않는 것이 좋습니다.

1.3. 서브세팅(Subsetting)

서브세팅은 폰트 파일에서 사용할 글꼴 범위만 지정해 요청하는 것입니다. 이는 CSS의 @font-face 규칙에서 unicode-range 속성에 사용할 글꼴의 범위를 유니코드 범위 설명자를 이용하여 표현하여 사용할 수 있습니다. 범위 설정은 3가지 형식이 존재합니다.

  1. 단일 코드 포인트(예: U+416)
  2. 간격 범위(예: U+400-4ff): 범위의 시작 및 끝 코드 포인트를 나타냅니다.
  3. 와일드 카드 범위(예: U+4??): ? 문자는 임의의 16진수를 나타냅니다.

또한 ,로 여러 범위를 설정할 수 있습니다. 만약 웹 폰트를 한글에서만 사용한다면 범위를 U+AC00-D7AF로 설정하면 됩니다.

@font-face {
  font-family: 'Awesome Font';
  src: local('Awesome Font'),
       url('/fonts/awesome.woff2') format('woff2'),
       url('/fonts/awesome.woff') format('woff'),
       url('/fonts/awesome.ttf') format('truetype'),
       url('/fonts/awesome.eot') format('embedded-opentype');
  unicode-range: U+000-5FF, U+AC00-D7AF; /* Latin + Korean */
}

하지만 일부 브라우저는 이러한 설정을 지원하지 않을 수 있습니다. 이 때는 사용할 글꼴만 존재하는 폰트 파일 직접 만들면 됩니다. 이는 응용 프로그램 혹은 라이브러리(예를 들어, サブセットフォントメーカー: 서브셋 폰트 메이커)을 이용하면 가능합니다.

2. preload 옵션으로 미리 요청하기

일반적인 브라우저 렌더링 과정은 다음과 같습니다.

  1. 브라우저가 HTML 파일을 요청합니다.
  2. 브라우저가 HTML 응답 파싱과 DOM(Document Object Model) 구성을 시작합니다.
  3. 브라우저가 CSS, JS 및 기타 리소스를 발견하고 요청합니다.
  4. 브라우저가 모든 CSS 콘텐츠가 수신되면, CSSOM(CSS Object Model)을 생성합니다. 생성 후 DOM 트리와 결합하여 렌더링 트리를 생성합니다.
  5. 브라우저가 레이아웃(Layout)을 수행하고 콘텐츠를 화면에 페인팅(Paint)합니다.

여기서 웹 폰트에 대한 리소스 요청은 CSSOM을 생성하는 과정에서 발생합니다. 그런데 브라우저가 페인팅하는 과정에서 해당 폰트를 아직 사용할 수 없다면(로드가 완료되지 않았다면) 해당 폰트가 사용된 텍스트가 보이지 않을 수 있습니다.

하지만 만약 사용자의 브라우저를 예측할 수 있다면, 원하는 형식의 폰트 파일을 CSSOM 생성을 기다리지 않고 요청할 수 있습니다. 그 방법은 바로 HTML <head> 내부에서 <link rel="preload"> 태그를 사용하는 것입니다. 이 방법을 통해 웹 폰트 요청을 통해 텍스트 렌더링이 지연되는 현상을 최대한 방지할 수 있습니다. 다음은 사용 예시입니다.

<head>
  <!-- Other tags... —->
  <link rel="preload" href="/fonts/awesome-l.woff2" as="font">
</head>

그러나 모든 브라우저가 이 방법을 지원하지는 않습니다. 하지만 이 방법이 지원되는 브라우저라면 반드시 사용하길 권장합니다. 왜냐하면 이 방법이 지원된다면 WOFF2 형식의 폰트도 지원가능하기 때문입니다. 추가로 <link rel="preload">에 관련한 내용은 이 링크에서 확인할 수 있습니다.

3. 텍스트 항상 보여주기

웹 폰트 파일의 크기를 줄이고 미리 요청하더라도 텍스트 렌더링이 지연되는 현상이 발생할 가능성은 존재합니다. 그 경우 해당 텍스트의 글꼴은 폴백(fallback) 폰트로 대체되지만, 대체된 폰트로 텍스트가 화면에 렌더링되는 방식은 브라우저마다 상이합니다. 하지만 CSS의 @font-facefont-display속성을 통해 렌더링 방식을 일치시킬 수 있습니다. 그리고 속성값은 auto, block, swap, fallback, optional로 총 5가지가 존재합니다.

  1. auto: 각 브라우저의 기본 설정값으로 실행됩니다.
  2. block: 웹 폰트 로딩이 완료될 때까지 텍스트를 렌더링하지 않습니다. 단, 로딩이 3초를 넘어가면 폴백 폰트로 렌더링하고, 로딩이 완료되면 해당 폰트로 스왑합니다.
  3. swap: 웹 폰트 로딩이 완료될 때까지 폴백 폰트로 글자를 렌더링합니다. 로딩이 완료되면 해당 폰트로 스왑합니다.
  4. fallback: 웹 폰트 요청 후 100ms 동안은 텍스트를 렌더링하지 않습니다. 이후 3초 간 웹 폰트 로딩이 완료될 때까지 폴백 폰트로 렌더링하며, 로딩 완료되면 해당 폰트로 스왑합니다. 하지만 3초가 지난다면 해당 폰트가 로딩이 완료되어도 스왑하지 않습니다.
  5. optional: 웹 폰트 요청 후 100ms 동안은 텍스트를 렌더링하지 않습니다. 그러나 직후 해당 폰트가 로딩이 완료되어있지 않다면, 폴백 폰트로만 렌더링하며 해당 폰트가 추후 로딩 완료되어도 스왑하지 않습니다.

적절한 속성 값을 설정한다면, 텍스트 렌더링 지연 현상을 대처할 수 있을 것입니다. 그러나 font-display 속성도 일부 브라우저에선 적용되지 않을 수 있습니다.

결론

웹 폰트에 대한 최적화 방법은 다양하게 존재하며, 위 방법들은 상호배타적인 방법들이 아니므로 적절히 조합하여 사용할 수 있습니다. 또한 폰트 파일은 변화가 적은 파일이므로 이에 대한 캐싱 정책 고려할 필요가 있습니다. 그리고 이와 별개로 주의해야하는 것은 페이지에 너무 많은 글꼴을 사용하지 않는 것입니다. 즉, 사용할 글꼴의 수를 최적화하는 것도 웹 폰트 최적화 중 하나라 생각합니다.

참고

profile
개념 정리 + 호기심 해결용 블로그

0개의 댓글