[웹성능 최적화] font 최적화

gigi·2023년 5월 5일
0

최적화 전

최적화 후

포트폴리오 첫 화면에 텍스트를 넣게되면서 구글폰트를 사용하게 됐는데 캐싱되기전에 기본 폰트상태로 노출되는 상태를 확인했다.

먼저 FOUT 와 FOIT에 대해 알아야하는데

FOUT는 Flash Of Unstyled Text의 약자로 먼저 텍스트를 보여주고 폰트의 다운이 완료되면 폰트를 적용해 보여준다.

FOIT는 Flash Of Invisible Text의 약자로 폰트의 다운이 완료될때까지 텍스트를 노출하지 않다가 다운이 완료되면 폰트를 적용하고 보여준다.

폰트 적용시점

먼저 import 하는 구글폰트를 확인해보자

잘 보면 폰트의 diplay 속성이 swap 이다. css속성으로 폰트의 적용시점을 컨트롤 할 수 있는데 여러가지 속성이있다.

  • auto : 브라우저 기본 동작(IE, edge = FOUT, chorme, safari = FOIT)
  • block : FOIT (timeout = 3s)
  • swap : FOUT
  • fallback : FOIT(timeout=0.1s) 3초 후에도 불러오지 못했을 시 기분 폰트로 유지, 이후 캐시
  • optional : FOIT(timeout=0.1s) 이후 네트워크 상태에 따라 기본폰트로 유지할지 웹폰트를 적용할지 결정, 이후 캐시

display 속성이 swap이라서 FOUT방식으로 동작하고 있었기 때문에 display 속성block으로만 해도 상당히 개선된 모습을 보일것이다. 하지만 개발자도구 network탭에서 slow 3g 환경으로 낮추고 페이지를 로드하면 폰트 리소스 다운이 3초를 넘겨 기본폰트가 잠깐 노출되는 경우도 있다.

폰트 파일 크기 줄이기

폰트의 파일이 큰 경우 사이즈를 줄여 리소스 다운 시간을 줄일 수 있다. 보통 ttf > woff > woff2 순으로 파일의 크기 차이가 있다. 일단 나는 woff2로 변환해서 preload까지 해보려고한다.

ttf확장자의 폰트를 woff2로 변환하는 방법은 https://cloudconvert.com/ 해당 사이트에서 가능하다.

폰트를 변환후에 프로젝트에 넣고 font-face로 설정을 해주면 사용이 가능하다.

/* app.css */

@font-face {
  font-family: Oswald;
  src: url('./assets/fonts/Oswald-Bold.woff2');
  font-weight: 700;
  font-display: block;  
}

여기까지만해도 파일 크기가 큰 ttf 폰트를 사용중이었다면 눈에띄는 효과가 있다.

이외에도 몇가지 방법이 더 있는데

  • 몇종류의 글자만 사용하는경우 예를들어 portfoilo 라는 텍스트에만 폰트를 적용한다고 하면 폰트파일에서 p, o, r, t, f, i, l 만 추출해서 파일 사이즈를 줄이는 subset 방법
  • font-face의 unicode-range 속성으로 텍스트 코드를 지정해 해당 텍스트가 없는 경우 폰트 리소스를 불러오지않도록 설정하는 방법
  • base64 encode를 통해 data-uri로 변환하여 css에 직접 넣고 css 리소스에 포함하여 불러올 수 있는 방법
    위 내용에 대해서는 https://transfonter.org/ 사용방법을 알아보자

preload

<!DOCTYPE html>
<html lang="en">
  <head>
    <link
      rel="preload"
      href="Oswald-Bold.woff2"
      as="font"
      type="font/woff2"
      crossorigin
    />
  </head>
  <body>
  </body>
</html>

index.html의 헤더에 link태그로 위와같이 설정을 해주면 되는데(href와 type만 수정하면 된다.)
이후에 build를 해보면

폰트가 리소스이기 때문에 그대로 가져다 쓰는게 아니라 폰트 이름에 해시값이 붙는다.

그렇기 때문에 build된 index.html 안에 href 경로를 수정해줘야한다.

<link
  rel="preload"
  href="./static/media/Oswald-Bold.e7fa7e72b7c318133311.woff2"
  as="font"
  type="font/woff2"
  crossorigin
/>

이후 개발자도구 performance탭에서 새로고침을 해보면

html파일이 불리고 js파일보다도 먼저 font가 불리는것을 확인 할 수 있다.

여기서 중요한것은 html 파일에 link 태그만 넣어도 호출은 하는데 폰트의 경로와 파일이름이 일치해야 한다는것이다. 그런데 build 할때마다 index.html 파일을 수정해주는것은 무리가 있기 때문에 웹팩 설정을 통해 font를 preload 하도록 구성 해줄 수 있는 방법이 있는데

현재 CRA를 사용하기 때문에 웹팩을 직접 커스텀 할 수 없어 웹팩을 커스텀 할 수 있는 react-wired 라는 라이브러리를 설치 하여 웹팩 설정을 override 할 수 있는 환경을 구성하고 preload를 할 수 있게 도와주는 preload-webpack-plugin을 설치하여 세팅해주는 방법이 있다.

(해당 방법은 추후에 업데이트 예정. 포트폴리오에 설치한 라이브러리중 하나와 react-wired가 충돌을 일으켜서 설정을 아직 못했다.)

1개의 댓글

comment-user-thumbnail
2023년 5월 8일

저기요 잠수타시고 블로그는 열심히 하시면 다입니까 몇달간 걱정했는데요 ㅡㅡ

답글 달기