TIL

[2024.05.02] 웹 폰트 최적화(가볍게 정리만)

_자몽 2024. 5. 2. 23:58

팀 프로젝트 + 팀 프로젝트에 적용할 개인 공부 + 스터디 모집 마감 일정을 한 번에 처리하려니 진짜 하루가 부족했다..! 내 시간 어디로 사라진 거지? 

그러게...?


※ 웹 폰트 적용하기

매번 구글 폰트나 다른 cdn을 사용해서 웹폰트를 다운로드하는 형태로 웹 폰트를 사용했는데, 이번 프로젝트에서는 local에서 서버로 웹 폰트를 올리는 @font-face를 사용해 웹폰트 최적화를 사용하였다. 한 번 최적화에 대해 고민하게 되니, 더욱더 많은 자료를 찾아보게 되었고 가장 도움이 되었던 건 'FE.CONF 2018' 컨퍼런스에서 발표된 웹폰트 최적화 발표 자료였다. 오늘은 자세히 포스팅할 시간이 없어 해당 내용 정리한 것만 기재해 두고, 프로젝트 마감 후 제대로 올려봐야겠다.

 

아래 내용은 'FE CONF 2018 웹폰트 사용과 최적화' 세션을 듣고 정리한 내용입니다.

I . 용량 줄이기

1. 용량을 줄이기 위한 여러 방법들
 1.1 woff2 포맷
 1-2. subset 폰트(한글 전체 11722자 -> 2350자, ks x 1001 한국 산업 규격에 맞춰 추출함)
 1-3. unicode-range 속성

2. FOIT & FOUT
 2.1 FOIT
  - 모던 브라우저(크롬, 사파리, 파이어폭스)에서 사용
  - 웹폰트가 다운로드될 때까지 텍스트를 렌더링 하지 않다가, 로딩이 된 이후에 텍스트를 보여줌
  - 웹폰트가 로딩이 되지 않을 때, 해당 텍스트 "rendering block"(화면에 나타나지 않게 막음)
  - 기다리는 제한시간 3s가 있다. 3초 지나면 fallback 시키고, 웹폰트 다운로드가 이루어지면 해당 웹폰트로 swap시킴.
 2.2 FOUT
  - 웹폰트가 다운로드될 때까지 fallback 폰트를 보여주고, 로드가 되면 웹 폰트로 swap 하는 방식
  - 웹폰트와 관계없이 텍스트는 항상 보임
  - 글꼴의 자간, 높이에 따라 '레이아웃'이 변경될 수 있으며, 이 때문에 레이아웃이 틀어져서 이상해 보일 수 있다.

=> UX관점으로는 차라리 폰트가 보이는 FOUT가 나음(안 보이면 어떤 문제가 초래될지 모르기에)


II. 텍스트가 항상 보이게

1. FontLoader 라이브러리
 - FontFaceObserver, Google Webfont Loader, npm/webfonts-loader 등 다양함
※ FontFaceObserver 소개: 용량이 적어 가볍고, 빠르게 동작하는 장점
 - 웹 폰트 파일의 로딩상태를 추적함. 그에 따라 맞춰서 사용하는 형태
 → 의도적 FOUT 만들기: 웹 폰트 없는 상태를 정의하고, 웹 폰트 적용 된 CSS도 만들어 둠. JS에서 웹 폰트를 추적하는 객체를 만들고, 웹 폰트 로드가 끝났을 때, 폰트를 적용하려는 객체에 className을 설정해서 css가 적용되도록 하는 방식.

2. css의 font-display 속성을 이용해 텍스트가 항상 보이게
 - font-display 속성: auto/block/swap/fallback/optional 속성을 가짐
 - auto: 브라우저별 기본값
 - block: FOIT과 동일하게 동작
 - swap: FOUT와 동일하게 동작
 - fallback: 아주 짧은 시간(100ms) 동안 rendering block(안 보이게)을 하고, fallback(대체 폰트)을 렌더링함. swap기간(2초) 내 웹폰트 로드 완료 시 웹폰트를 렌더링 하고, 그렇지 않으면 계속 fallback 폰트로 유지함. 
   장점: 웹폰트의 다운로드는 일어나기 때문에 캐싱은 되어있는 상태, 사용자가 새로고침 등의 방법으로 페이지 리렌더링이 일어나면 웹폰트로 수정되어 보임
  - optional: 아주 짧은 시간(100ms) 동안 block 후, 대체 폰트 렌더링. 그 짧은 시간 속에 네트워크 상태를 파악하여, 네트워크가 충분히 빠르면 웹폰트를 다운로드하여 렌더링 하고, 그렇지 못하면 웹폰트를 다운은 받아놓은 상태에서 대체 폰트를 사용함.
   장점: 읽는 도중 번쩍이며 폰트가 바뀌지 않으니, 사용성 측면에서 좋음

=> 때문에 항상 텍스트가 보이게 하려면: swap, fallback, optional 중 하나를 사용하면 된다(fallback, optional의 경우 0.1s동안 block 되지만 사실상 무시해도 될 정도의 시간)

III. 폰트 간 차이 줄이기

 - 폰트마다 스타일(자간, 높이 등)이 다름
 - 'Font style matcher': 웹폰트와 fallback 폰트의 스타일 차이를 최대한 줄일 수 있게 함.
 - 이걸 이용해서 로드 전 css에 fallback 폰트 스타일을 넣고, 로드 후 css에 웹폰트 스타일을 넣으면 글자가 깨지는 것을 방지할 수 있음.

IV. 먼저 다운로드하기: preload 옵션

 - <link>에 preload 옵션을 줘 다른 리소스보다 빨리 받아 올 수 있음
  => preload를 쓰면서 as/crossorigin 속성을 사용하지 않으면 두 번 css를 다운로드하음으로 꼭 쓰기. 단, preload가 많아지면 첫 번째 painting까지 시간이 오래 걸리기에 신중하게 사용하기.

 

※ 출처
FE.CONF 2018 웹폰트 최적화 발표영상: https://www.youtube.com/watch?v=4YCBBoSg2fk
네이버 기술 블로그: https://d2.naver.com/helloworld/4969726
https://wit.nts-corp.com/2017/02/13/4258