본문 바로가기
카테고리 없음

지연 시간 없이 웹 폰트 서빙하기 (feat. 사용자에게 버벅이는 순간 없애기)

by klm hyeon woo 2023. 11. 11.

목차

· 어라, 왜 버벅이지?

· 부드러운 폰트 서빙을 위한 여러가지 방법들

  1) 꼭 필요한 Glyph 만을 포함하는 폰트 파일 사용

  2) Critical Request Depth 줄이기

· 레퍼런스


어라, 왜 버벅이지?

멋쟁이사자처럼 메인 코어 페이지를 제작하던 도중, 배포된 페이지를 방문하던 도중 폰트가 버벅이는 현상을 발견했다. 웹 폰트를 사용하다보니 사용하는 폰트들의 로드 시간이 소요되었고, 사용자가 보는 도중 로드를 마치는 원인 때문에 사용자에게 버벅이는 현상이 제공되었다. 현재 멋쟁이사자처럼 코어 페이지에서는 Pretendard 폰트를 사용하고 있기 때문에, 관련 깃허브에서 용량에 관련된 부분이나 다양한 웹 서핑을 통해 웹 폰트를 부드럽게 서빙하는 방법을 찾을 수 있었다.

font-display: block을 사용하면 브라우저는 폰트가 다운로드 되기 전까지 투명한 폰트를 사용하여 페이지를 렌더링한다. 하지만 이 경우에도 사용자는 좋지 못한 경험을 느낄 수 있기 때문에 마냥 좋은 방법은 아니다.

 

따라서 좋은 사용자 경험을 위해 브라우저가 최대한 빨리 폰트를 가져올 수 있도록 동작을 시켜야한다. 

부드러운 폰트 서빙을 위한 여러가지 방법들

1) 꼭 필요한 Glyph 만을 포함하는 폰트 파일 사용

가장 먼저 웹 페이지에서 노출될 일이 없는 글리프(Glyph) 삭제를 통해 비교적 용량이 적은 폰트 파일을 제공할 수 있다.

Glyph란?
자체의 문자 코드에서 뜻과 소리를 지니지 않는 도형 기호 (구두점, 괄호, 공백 등)의 추상화를 포함한다.

 

영문 폰트틑 대소문자를 포함해 72개의 글리프(Glyph)만 있으면 된다. 하지만 한글의 경우 자모음의 조합으로 글리프(Glyph)가 구성되기 때문에 가능한 모든 조합을 계산하면 11,172개의 글리프(Glyph)가 필요하다. 따라서 한글이 포함된 폰트는 용량이 커지게 된다.

 

하지만 우리가 웹 페이지에서 11,172개의 글자가 모두 필요할까?

 

Pretendard 폰트의 경우, 위와 같은 글리프(Glyph) 폰트를 모두 가지고 있는 것을 확인할 수 있다. 미사용 글리프(Glyph)를 삭제하면 폰트 용량을 많이 줄일 수 있다. Pretendard 에서는 해당 내용에 대하여 서브셋 폰트를 제공하고 있으며, Pretendard 페이지에서 서브셋 폰트를 통해 보다 경량화된 폰트 사용을 할 수 있다.

2) Critical Request Depth 줄이기

서브셋 폰트를 통해 폰트의 크기를 줄일 수 있었으나 최대한 빨리라는 관점에서 몇 가지 더 개선할 점이 있다. 웹 폰트를 다운로드 받기 전에는 어떤 font request를 날려야하는지 알 수 없고, initial request가 완료되기 전까지 어떤 CSS 파일이 필요한지 알 수 없다. 여기서 Critical Request Depth를 설명할 수 있다.

CSS 로드 후, 폰트를 가져오기 까지 5초 이상이 지연된다.

  1. 브라우저는 URL에 GET을 요청한다.
  2. 브라우저가 웹 폰트가 필요함을 확인하고 GET을 요청한다.
  3. 브라우저가 웹 폰트를 읽고 font request를 발생한다.
  4. 브라우저가 폰트 정보를 획득한다.

위와 같이 폰트 데이터를 가져오기 위해 동기적으로 여러가지 요청을 발생시킨다. 이러한 문제를 Critical Request Depth 라고 부른다. 더욱 빠른 페이지를 위해 우리는 CRD를 줄여야한다. 이럴 경우 어떻게 줄일 수 있을까?

 

우리는 폰트에 대한 데이터를 얻기 위해 정확히 어느 URL로 font request를 전송해야 할 지 알고 있다. 웹 폰트를 작성하는 시점에 알고 있기 때문에 최초 로드 후 최대한 빨리 가져와야하는 리소스를 대상으로 preload link를 사용할 수 있다.

// _document.tsx
export const BanksaladDocument = () => {
  return (
    <Html lang="ko">
      <Head>
        {/* Preload woff2 fonts */}
        <link
          rel="preload"
          as="font"
          type="font/woff2"
          crossOrigin=""
          href={`${CDN_BASE_URL}/font/pretendard/Pretendard-Regular.subset.woff2`}
        />
        {/* Request font.css */}
        <link
          rel="stylesheet"
          type="text/css"
          href={`${CDN_BASE_URL}/font.css`}
        />
      </Head>
      ...
    </Html>
  );
};

CSS와 폰트를 병렬적으로 가져오는 것을 확인할 수 있다.

위와 같은 방법으로 도큐먼트 상단에 선언해줌으로서 CSS와 폰트 데이터를 병렬로 다운로드 하여 CRD 해결할 수 있다. 위와 같은 방법을 통해 Network waterfall이 조금 더 빠르게 개선될 수 있으며, 사용자에게는 버벅이는 현상을 방지할 수 있다. 다만 여기서 주의할 점은 정말 필요한 부분에 대해서만 preload를 요청해야한다는 점이다. 랜딩 화면에서 보여지지 않는 부분까지 preload를 진행하게 되면 초기에 브라우저에서 요청하는 값들이 많아지기 때문에 네트워크 부하가 발생할 수 있다.

(좌) 프리로드를 적용한 폰트 / (우) 프리로드 미적용 폰트

정리를 해보자면 아래와 같이 정리를 할 수 있다.

· 웹 폰트를 적용할 때 서브셋 폰트를 사용하여 용량을 줄일 수 있다.

· 폰트, 스크린 상단에 표시되는 이미지 등 최대한 빨리 가져와야하는 리소스는 preload link를 사용할 수 있다.

· 자주 사용하는 CDN 등 최초 연결 이후 10초 이내에 요청할 가능성이 높은 도메인에 대하여 preconnect link를 사용할 수 있다.

프리로드를 시켜 사용자에게 자연스러운 폰트 서빙을 가져다 줄 수 있다.


레퍼런스

 

지연 시간 없이 웹폰트 서빙하기 - Feat. Safari & Edge functions | 뱅크샐러드

안녕하세요 뱅크샐러드 Web Front-End Engineer 민찬기입니다. 여러분들은 운영하시는 서비스의 폰트를 바꾸신 적이 있으신가요? 바꾸시는 과정에서 어떤 어려움을 겪으셨나요? 눈썰미가 남다르신 분

blog.banksalad.com

 

웹 폰트(WebFont)가 궁금하다

웹 페이지 성능에 영향을 주는 웹 폰트

harris91.vercel.app

 

댓글