[프론트엔드 최적화] 폰트 최적화 -1 (Font-face, Fontface observer)

2022. 4. 6. 12:23
반응형

FOUT (Flash of Unstyled Text)

- 텍스트를 일단 기본 글꼴로 먼저 띄우고, 폰트가 로딩되면 다시 적용한다. 

- 사용자는 '깜빡'하며 새 폰트가 적용되는 모습을 목격한다

- IE, edge 등에서 웹폰트를 보여주는 방식

 

FOIT (Flash of Invisible Text)

- 폰트가 완전히 로딩되지 않으면 아예 보여주지 않는다

- 사용자는 처음부터 폰트가 적용된 텍스트를 본다

- Chrome, safari 등에서 웹폰트를 보여주는 방식

 


 

우리는 웹폰트 최적화를 통해 FOUT, FOIT 현상 발생을 방지해야 한다.

 

- 웹폰트가 적용되는 시점을 컨트롤하는 방법 (CSS의 font-display 속성 이용)

- 웹폰트의 용량 자체를 줄이는 방법

 


 

1. 웹폰트 적용 시점 컨트롤

 

 

https://developer.mozilla.org/ko/docs/Web/CSS/@font-face/font-display

 

 

font-display - CSS: Cascading Style Sheets | MDN

font-display 설명자(descriptor)는 font face가 표시되는 방법을 결정합니다. 이는 다운로드 여부와 사용 시기에 따라 다릅니다.

developer.mozilla.org

 

auto 브라우저별 기본 동작(IE와 edge는 FOUT, chrome과 safari는 FOIT)
block FOIT 방식 - timeout 3s (적어도 3초는 기다렸다가, 그 때까지도 폰트 다운로드가 완료되지 않았으면 기본글꼴로 보여준다)
swap FOUT 방식 (기본글꼴 먼저 띄우고, 폰트가 로딩되면 깜빡거리며 적용)
fallback FOIT 방식 - timeout 0.1s (0.1초동안은 텍스트 안보이다가, 3초 후에도 폰트가 다운되지 않았을 시 계속 기본폰트를 보여준다. 만약 3초 이후에 다운로드가 완료되었다면 폰트를 캐시에 넣어둔다)
optional fallback 방식과 비슷하지만, 그 기준이 3초라는 '시간'이 아니라 네트워크에 접속 되었는지/아닌지 

 

* 구글에서 권장하는 방식은 optional

* 사용자에게 빨리 보여져야 한다거나, 내용적으로 그렇게 중요하지 않다면 block 방식 권장

 

 


 

폰트페이스 옵저버(Fontface observer)

폰트 로딩 시점을 편리하게 컨트롤할 수 있도록 돕는 외부 패키지

 

https://www.npmjs.com/package/fontfaceobserver

 

fontfaceobserver

Detect if web fonts are available. Latest version: 2.1.0, last published: 3 years ago. Start using fontfaceobserver in your project by running `npm i fontfaceobserver`. There are 449 other projects in the npm registry using fontfaceobserver.

www.npmjs.com

 

기본적인 사용법

  const font = new FontFaceObserver('BMYEONSUNG');
  font.load().then(() => {
    console.log('font loaded!');
  });

 

 

응용 (useState와 useEffect 사용, 폰트가 로딩되었을 때 투명도가 점차 옅어지며 글자가 나오도록 설정) 

import React, { useState, useEffect } from 'react';


const Main = () => {
  
  const [isFontLoaded, setIsFontLoaded] = useState(false);
  
  useEffect(() => {
    font.load().then(() => {
      setIsFontLoaded(true);
    });
  }, []);
  
  ...
  
  return (
    <div style={{ opacity: isFontLoaded ? 1 : 0, transition: 'opacity 0.5s ease' }}>타이틀</div>
  )
}

 

 

 

반응형

BELATED ARTICLES

more