IT/HTML & CSS

웹 폰트(Web Font) 최적화 하기

라임웨일 2022. 1. 18. 11:26
반응형

 

요즘은 워낙 다양한 웹 폰트가 있고 각 회사마다 자신들의 회사에 맞는 아이덴티티를 갖는 폰트도 직접 제작해서 사용하는 회사도 생기고 있습니다. 가장 대표적인 예가 현대카드입니다. 동일한 사이트라도 폰트의 적용 여부만 다르게 해도 사이트의 느낌과 톤 앤 매너, 콘텐츠의 가독성이 변한다는 것을 쉽게 알 수 있습니다. 

💡 웹 폰트란?

정확히 무엇일까요? 방문자의 로컬 컴퓨터에 폰트 설치 여부와 상관없이 온라인의 특정 서버에 위치한 폰트 파일을 다운로드하여 화면에 표시해주는 웹 전용 폰트입니다.

 

✔ typeface와 font 구분하기

typeface: 한글로는 서체라고 하며 공통 디자인을 공유하는 글꼴 전체를 의미합니다. 이 서체에는 굵기나 스타일 등이 포함될 수 있습니다. 예를 들어 Helvetica는 서체의 한 종류이며 서체는 일종의 폰트 패밀리로 보면 됩니다.

 

font: 한글로는 글꼴이라고 합니다. 서체의 단일 굵기와 스타일이며 글꼴은 특정 크기, 굵기 및 스타일을 포함하여 제공됩니다. (예: 10 포인트 Helvetica 볼드 이태릭체) 벡터 기반의 최신 디지털 글꼴 디자인은 단일 글꼴을 무한히 확장하거나 축소할 수 있지만, 각 굵기와 스타일에 대해 별도의 파일이 필요합니다.

 

✔ 웹 폰트의 장, 단점

장점: 웹 폰트를 사용한다면 사용자에게 해당 폰트가 없더라도 디자이너가 의도한 대로 원하는 디자인을 모두에게 동일하게 제공할 수 있다는 장점이 있습니다. 

 

단점: 웹 폰트는 자체가 워낙 용량이 무겁고 웹에서 폰트를 불러와서 적용시키는 것이기 때문에 웹에 전반적인 속도 저하를 가져온다는 것입니다. 더욱이 속도가 느린 사용자는 처음 기본 시스템 폰트에서 웹 폰트로 화면이 변하는 과정도 눈으로 보이는 현상이 발생하게 됩니다. 그렇기에 웹 폰트를 사용할 경우 최적화 과정을 통해서 속도 이슈를 방지하여야 합니다.

 

아래 이미지는 2016년에 미국의 상원 의원인 Mitt Romney에 관한 기사에서 웹 폰트가 로딩되기 전과 로딩된 후의 화면을 비교한 그림입니다. 단어 "Not"을 웹 폰트로 지정해서 의미를 강조하려 했지만 웹 폰트의 로딩이 늦어져 "Not"이 없는 상태로 사용자에게 기사가 노출되었고 "Not"이 없이 노출된 시간은 불과 몇 초였지만 원래 의미와 정반대의 내용이 사용자들에게 전달되었습니다. 이 사건으로 인해 한때 미국에서 웹 폰트가 이슈가 되었습니다.

 

Mitt Romney 기사에서 웹 폰트 로딩 전후 비교

 

💡 웹폰트 확장자 종류

  • 주로 4가지 형식이 쓰임.
  • EOT: IE8 이하일 경우
  • TTF: 구형 안드로이드 버전(4.4)에서 필요.
  • WOFF: 대부분의 모던 브라우저에서 지원
  • WOFF2: WOFF보다 압축률이 30% 정도 더 좋음

 

 

💡 웹 폰트 최적화 방법

1. 모던 파일 포맷을 사용

Web Open Font Format 2.0은, 현재 기준 가장 작고 효율적인 웹 폰트 파일 형태로 CSS에서 @font-face룰을 사용할

때, woff2 글꼴이 ttf와 같은 오래된 구식의 덜 효율적인 폰트보다 더 앞서서 선언되어 있게 해야 합니다.

브라우저는 더 큰 파일이라 할지라도, 먼저 선언되어 있는 글꼴을 인식하여 사용하게 됩니다.

 

2. 웹 폰트 확장자는 순서에 맞게 적용

  1. woff2를 가장 앞에 적용합니다. 브라우저는 선언된 순서대로 지원 가능한 파일 형식을 다운로드하기 때문에 압축률이 가장 좋은 woff2를 먼저 선언합니다.
  2. format()은 반드시 써야 합니다. 쓰지 않으면 브라우저는 지원 가능한 파일 형식이 나올 때까지 순서대로 다운을 받게 됩니다.
  3. IE8이하를 지원해야 할 경우 eot가 가장 먼저 선언되어야 합니다. IE는 format을 읽지 못하기 때문에 가장 앞에 선언되어야 합니다.
@font-face {
  font-family: 'Typefesse';
  src: url(/static_fonts/NanumGothic-Regular.eot), 
       url(/static_fonts/NanumGothic-Regular.woff2) format("woff2"), 
       url(/static_fonts/NanumGothic-Regular.woff) format("woff"),
       url(/static_fonts/NanumGothic-Regular.ttf) format("truetype");
}

IE8 지원을 할 것이 아니라면, WOFF2나 WOF 보다 더 오래된 폰트 형식을 사용할 필요가 없고 IE 11 지원을 배제한다면, WOFF2만 사용하면 됩니다.

만약 TTF 파일만 가지고 있다면, https://onlinefontconverter.com/ 와 같은 사이트를 방문해서 변환하는 것이 좋습니다.

3.  local 문법 사용

위처럼 설명한 것처럼 CSS에 폰트를 선언하게 되면 시스템에 폰트 유무와 관계없이 무조건 폰트를 다운로드하게 되어 불필요한 리소스를 요청합니다. 이를 방지하기 위해 local 문법을 앞에 선언해주면 시스템에 설치되어 있다면 리소스를 요청하지 않습니다.

src: local('Nanum-Gothic'), 
     url(/static_fonts/NanumGothic-Regular.woff2) format("woff2"), 
     url(/static_fonts/NanumGothic-Regular.woff) format("woff");

 

4.  같은 폰트라면 font-family로 구분

모든 범위의 서체를 쪼갤 필요는 없고 자신이 필요한 굵기와 스타일의 폰트만 다운로드하여 사용합니다.

@font-face {
    font-family: 'Nanum Gothic'; 
    font-style: normal;
    font-weight: 400;
    src: url(/static_fonts/NanumGothic-Regular.woff2) format("woff2"), 
        url(/static_fonts/NanumGothic-Regular.woff) format("woff"),
        url(/static_fonts/NanumGothic-Regular.ttf) format("truetype");
}

@font-face {
    font-family: 'Nanum Gothic'; /* Nanum Gothic Bold x */
    font-style: normal;
    font-weight: 700;
    src: url(/static_fonts/NanumGothic-Bold.woff2) format("woff2"),
        url(/static_fonts/NanumGothic-Bold.woff) format("woff"), 
        url(/static_fonts/NanumGothic-Bold.ttf) format("truetype");
}

@font-face {
    font-family: 'Nanum Gothic'; /* Nanum Gothic ExtraBold x */
    font-style: normal;
    font-weight: 800;
    src: url(/static_fonts/NanumGothic-ExtraBold.woff2) format("woff2"), 
        url(/static_fonts/NanumGothic-ExtraBold.woff) format("woff"), 
        url(/static_fonts/NanumGothic-ExtraBold.ttf) format("truetype");
}

@font-face {
    font-family: 'Nanum Gothic'; /* Nanum Gothic italic x */
    font-style: italic;
    font-weight: 400;
    src: url(/static_fonts/NanumGothic-Regular-italic.woff2) format("woff2"), 
        url(/static_fonts/NanumGothic-Regular-italic.woff) format("woff"), 
        url(/static_fonts/NanumGothic-Regular-italic.ttf) format("truetype");
}

 

5.  서브셋 폰트 사용

서브셋 폰트(subset font)는 폰트 파일에서 불필요한 글자를 제거하고 사용할 글자만 남겨둔 폰트입니다.

영어는 26개 알파벳으로 이루어져 있고 영문 폰트에는 대소문자를 포함해 총 72자의 글자가 필요하지만 한글은

자음, 모음의 조합으로 구성되어 있기 때문에 모든 경우를 조합하면 한글의 글자 수는 11,172자나 됩니다. 그래서 한글 폰트 파일은 영문 폰트 파일보다 용량이 크게 됩니다. 

 

나눔바른고딕 폰트의 일부분

 

나눔바른고딕 폰트의 글자에서 노란색으로 표시한 글자는 실생활에서 거의 사용하지 않는 글자들입니다. 이러한 불필요한 글자를 폰트에서 제거하고 사용할 글자만 남겨 둔 폰트가 서브셋 폰트입니다. 글자의 개수가 줄었기 때문에 서브셋 폰트는 용량이 적습니다.

한글 폰트에서 어떤 글자를 삭제할지는 국가 표준(KS)인 "정보 교환용 부호계(한글 및 한자)"를 참고해 판단할 수 있습니다.  나눔바른고딕 폰트의 서브셋 폰트는 한글 글자를 11,172자에서 2,350자로 줄었고 용량 또한 2.4MB에서 서브셋 폰트의 용량은 586KB로 줄었습니다.

 

6.  텍스트가 항상 보이게 하기

브라우저는 웹 페이지를 렌더링 하는 과정에서 웹 폰트가 다운로드되지 않았으면 해당 텍스트의 렌더링을 차단하게 됩니다. 렌더링을 차단했을 때의 동작은 브라우저마다 다른데 Mitt Romney 기사 사례와 같이 텍스트가 보이지 않는 문제를 해결하려면 브라우저의 렌더링 방식을 이해해야 합니다.

 

- 브라우저의 렌더링 차단 처리 방식

렌더링 방식은 Internet Explorer 계열 브라우저의 처리 방식과 그 외 최근 브라우저의 처리 방식으로 나눌 수 있습니다. Internet Explorer 계열 브라우저는 FOUT 방식(Flash Of Unstyled Text)으로 렌더링 차단을 처리하고, 그 외의 브라우저는 FOIT 방식(Flash Of Invisible Text)으로 렌더링 차단을 처리합니다.

웹 폰트가 적용될 때는 텍스트의 번쩍임(flash of text)이 일어나게 됩니다. 웹 폰트가 적용되지 않은 폴백 폰트 상태(unstyled)에서 폰트가 바뀌면서 텍스트 번쩍임이 일어나느냐(FOUT 방식), 웹 폰트가 적용되지 않은 텍스트가 보이지 않는 상태(invisible)에서 폰트가 바뀌면서 텍스트 번쩍임이 일어나느냐(FOIT 방식)로 처리 방식을 나누었다고 생각하면 됩니다.  두 현상 모두 폰트 리소스를 받는 시점이 글꼴을 렌더링 하는 시점과 경합이 일어나기 때문에 발생합니다.

 

✔ FOIT (Flash of Invisible Text)

  • 웹폰트가 로드될 때까지 텍스트를 렌더링 하지 않다가 로드가 된 이후에 텍스트를 보여주는 동작입니다.
  • 폰트가 로딩되지 않으면 웹페이지의 블락을 가져옵니다.
  • 모던 브라우저의 경우는 기다리는 제한 시간이 있습니다.. 3초 동안 기다리고 그 후에는 시스템 기본 폰트를 보여줍니다.

 FOUT (Flash of Unstyled Text)

  • 웹폰트가 로드될 때까지 시스템의 기본 폰트를 보여주고 이후 reflow 해서 글꼴을 대체하는 방식입니다.
  • 흔히 말하는 브라우저의 깜빡임입니다.
  • 폰트에 따라 자간, 높이에 따라 레이아웃이 변경될 수 있는데 이럴 경우 사용자는 불편한 경험을 겪게 됩니다. 그럴 땐 font-size-adjust 속성이나 letter-spacing, line-height 등을 조정하여 최대한 적게 변해 보이도록 바꿔야 한다.
  •  

 

 FOUT 방식의 Internet Explorer 계열 브라우저

Internet Explorer는 웹 폰트가 로딩될 때까지 우선 폴백 폰트로 텍스트를 렌더링 한 게 되는데 웹 폰트 로딩이 완료되면 텍스트를 웹 폰트로 전환합니다. 이 방식은 웹 폰트 로딩 여부에 관계없이 텍스트가 항상 보이는 장점이 있지만 글꼴의 자간, 높이 등 서식이 달라 웹 폰트 적용 전과 후에 레이아웃이 변경될 수 있습니다.

 

 FOIT 방식의 브라우저

Firefox와 Chrome 등의 브라우저는 웹 폰트가 로딩되기 전까지 해당 텍스트를 화면에 보여 주지 않습니다. 웹 폰트 로딩이 완료되면 텍스트를 웹 폰트로 전환하게 되는데 한 번에 웹 폰트를 보여줄 수 있다는 장점이 있지만, 웹 폰트의 로딩이 늦으면 Mitt Romney 기사의 사례처럼 빈 텍스트가 노출되는 문제점이 있습니다.

웹 폰트가 로딩되지 않은 상태로 3초가 지나면 폴백 폰트로 우선 렌더링 해서 브라우저 자체적으로 웹 폰트의 로딩 시간이 과도하게 오래 걸리는 상황에 대비합니다.

 

 FOUT 방식을 사용한 최적화

FOIT 방식은 Mitt Romney 사례와 같이 텍스트가 보이지 않는 문제가 있기 때문에 UX 관점에서 좋지 않습니다. 그러므로 모든 브라우저에서 FOIT 방식이 아닌 FOUT 방식으로 작동하게 한다면 텍스트가 보이지 않는 문제를 해결할 수 있습니다.

 

7. font-display 속성을 사용

CSS의 font-display 속성을 사용하면 외부 라이브러리를 사용하지 않아도 웹 폰트의 로딩 상태에 따른 동작을 설정할 수 있습니다.

font-display 속성은 다음과 같이 auto, block, swap, fallback, optional의 5가지 옵션이 있다

  • auto 옵션은 브라우저의 기본 동작에 맡기는 방식입니다.
  • block 옵션은 FOIT와 동일하게 작동하는 옵션이다. 웹 폰트가 로딩되지 않았을 때는 텍스트를 렌더링 하지 않습니다(최대 3초). 웹 폰트 로딩이 완료되면 웹 폰트를 적용합니다.
  • swap 옵션은 FOUT와 동일하게 작동하는 옵션으로 우선 폴백 폰트로 글자를 렌더링 하고, 웹 폰트 로딩이 완료되면 웹 폰트를 적용합니다. 웹 폰트 로딩 여부와 관계없이 항상 텍스트가 보입니다.
  • fallback 옵션을 사용하면 우선 100ms 동안 텍스트가 보이지 않고, 그 후 폴백 폰트로 렌더링 합니다. 특이한 점은 약 2초의 전환(swap) 시간이 있다는 점인데 이 시간 안에 로딩이 완료되면 웹 폰트로 전환합니다. 하지만 이 시간이 지나면 웹 폰트 다운로드가 완료되어도 웹 폰트로 전환하지 않고 폴백 폰트를 유지합니다. 전환 시간 이후에 다운로드된 웹 폰트는 웹 페이지에 적용되지는 않지만 캐시에는 저장됩니다. 그래서 추후에 사용자가 다시 방문했을 때 바로 웹 폰트가 적용된다는 장점이 있습니다.
  • optional 옵션은 fallback 옵션과 비슷하지만 다르게 작동하는 옵션입니다. 우선 100ms 동안 텍스트가 보이지 않고 그 후 폴백 폰트로 전환합니다. 웹 폰트를 다운로드하지만 브라우저가 네트워크 상태를 파악해 웹 폰트 전환 여부를 결정한다는 점이 이 옵션의 특이한 점으로 예를 들어 네트워크의 연결 상태가 안 좋으면 웹 폰트의 다운로드가 완료되어도 캐시에 저장만 하고 전환은 하지 않습니다.

 

8. preload 옵션으로 먼저 로딩하기

<link> 태그의 rel 속성에 preload 옵션을 사용하면 해당 리소스를 다른 리소스보다 빨리 로딩합니다. 주로 폰트 파일, 이미지 파일, 스크립트 파일, 비디오 파일 등 페이지에서 중요도가 높은 자원을 의도적으로 먼저 로딩할 때 preload 옵션을 사용합니다.

<link rel="preload" href="./nanumGothic.woff2" as="font" type="font/woff2" crossorigin="anonymous">

 

웹 폰트 파일에 preload 옵션을 사용하면 다음 그림과 같이 CSS 파일보다 먼저 웹 폰트 파일의 다운로드를 시작합니다. 동일한 환경에서는 렌더링도 더 빨리 끝나는데 로딩이 빠르기 때문에 렌더링 차단 시간 역시 줄어듭니다.

preload 옵션은 아직 Chrome과 Safari만 지원하고 Internet Explorer와 Edge, Firefox는 지원하지 않습니다.

 

 

참고 :

반응형
광고차단(애드블록)프로그램이나 브라우저를 사용중이시면 프로그램을 비활성화이나 블로그 주소를 예외 처리 해주시면 광고가 노출됩니다. 귀찮고 번거롭겠지만 광고 클릭은 저에게는 큰 힘이 됩니다. 🙇🏻‍♂️🙇🏻‍♀️
제 블로그의 모든 글은 제가 직접 작성 하고 다른 글을 참고할 때는 이전 글보다 읽기 편하게 수정해서 작성하고 있습니다. 커피 한잔 사먹고 더 열심히 좋은글로 보답하겠습니다.
오늘도 제 블로그에 와 주셔서 감사합니다. :)
//