프론트엔드 개발

웹 폰트 경량화 및 최적화 본문

Browser/성능 최적화

웹 폰트 경량화 및 최적화

태나미 2021. 6. 23. 12:38

웹 폰트를 무작정 가지고 올 때는 CDN을 이용하여 폰트를 가져오고 있었습니다.

매번 폰트를 가져오기 위해서 CDN 네트워크 통신을 하게 되는 점과, 웹 폰트를 가져올 때의 UX를 개선시킬 수 있을까 하는 고민을 했습니다.

  • 이용하는 cdn 서버가 가깝지 않다면?
  • 처음 웹에 들어갔을 때 폰트가 없어졌다가 생기는 것과같이 불편하게 보여진다면?

cdn 서버가 멀게 되면 폰트를 직접 다운로드하여서 사용하면 네트워크 비용을 줄일 수 있지 않을까?라는 생각을 했고,

브라우저에서 렌더링 차단 처리 방식을 이해하여 웹 폰트 최적화하는 방법을 알고 적용시키고자 합니다.

웹 폰트의 사용 방법

naver D2의 글에서는, 웹폰트의 기본 사용방법을 설명합니다.

 

 CSS의 @font-face 규칙

  • font-family: 사용할 웹 폰트의 이름을 지정한다.
  • src: 폰트 파일의 경로와 폰트의 형식을 지정한다. url에 폰트 파일의 경로를 설정하고, format에 폰트 파일의 형식을 설정한다.

@font-face 규칙을 설정한 다음 웹 폰트가 필요한 선택자(selector)의 font-family 속성에서 사용할 웹 폰트의 이름을 호출해 사용합니다. 만약 웹 폰트 로딩이 실패하면 다음에 선언된 폰트가 렌더링 된다. 이 폰트를 폴백 폰트(fallback font)라고 합니다.

 

저는 구글에서 폰트에서 NotoSansKR을 다운받고, 해당 프로젝트에 fonts 폴더를 만들고 아래 폰트들을 넣었습니다.

 

NanumSquareB

NotoSansKr

웹폰트 확장자 종류

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

폰트 형식에 따른 브라우저 지원 범위

(before)

@font-face {
    font-family: 'Noto Sans KR';
    font-style: normal;
    font-weight: 100;
    src: url(//fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Thin.woff) format('woff'),
    url(//fonts.gstatic.com/ea/notosanskr/v2/NotoSansKR-Thin.otf) format('opentype');
}

(after)

@font-face {
    font-family: 'Noto Sans KR';
    font-style: normal;
    font-weight: 100;
    src: url(/fonts/NotoSansKR-Thin.woff) format('woff'),
    url(/fonts/NotoSansKR-Thin.woff2) format("woff2"), 
}

현재 맡고 있는 프로젝트에서 주로 사용하는 폰트는 NotoSans KR입니다. 브라우저 지원 범위를 따졌을 때 NotoSansKR의 woff를 쓰고,

서브 폰트는 NanumSquare가 종종 들어가는데 그 부분은 woff보다 woff2가 압축률이 더 좋기 때문에, 쓰려고 합니다.

local function 사용

local fonts를 사용하면 불필요한 요청 및 다운로드를 방지할 때 쓰이는데 local을 앞에 선언만 해주면, 폰트가 내 컴퓨터에 설치가 되어 있다면 리소스를 요청하지 않습니다. 사용하는 방법은 다음과 같습니다.

@font-face {
    font-family: 'Noto Sans KR';
    font-style: normal;
    font-weight: 100;
    src: local('Noto Sans KR'), url(/fonts/NotoSansKR-Thin.woff) format('woff'),
    local('Noto Sans KR'), url(/fonts/NotoSansKR-Thin.woff2) format('woff2');
}

FOIT / FOUT

FOIT (Flash of Invisible Text)

  • 웹 폰트가 로드되기 전까지 보이지 않고 완료되면 보이는 방식
  • 네트워크가 지연될 때 웹 폰트의 로딩이 늦으면 빈 텍스트가 노출되는 문제점이 있다
  • chrome, safari, firefox에서 발생

FOUT (Flash of Unstyled Text)

  • 웹 폰트가 로드되기 전까지 폴백 폰트로 보여지고, 웹 폰트 로드가 완료되면 웹폰트로 바뀌는 방식
  • 웹 폰트 적용 전과 후에 글꼴의 자간, 높이 등 서식이 달라  reflow가 일어날 수 있다
  • IE , edge에서 발생

FOIT 방식을 이용한다면 보이지 않는 텍스트가 중요한 텍스트라면 문제가 생길 수 있습니다. 그렇기 때문에, FOUT 방식을 사용하되, reflow를 최소화하는 방식으로 가야 함을 느꼈습니다.

font-display 속성을 사용한 최적화

font-display (@font-face의 속성)

  • auto - 브라우저의 기본 동작에 맡기는 방식
  • block - FOIT 방식, 웹 폰트가 로딩되지 않았을때 텍스트를 렌더링하지 않습니다.
  • swap - FOUT 방식, 폴백 폰트를 먼저 렌더링하고, 로딩이 완료되면 적용합니다.
  • fallback - 100ms 동안 텍스트가 보이지 않고, 그 후 폴백 폰트로 렌더링. 2초의 전환(swap) 시간 안에 로딩이 완료되면 웹 폰트로 전환합니다. 이 시간이 지나면 웹 폰트 다운로드가 완료되어도 웹 폰트로 전환하지 않고 폴백 폰트를 유지합니다.
  • optional - 100ms 동안 텍스트가 보이지 않고, 그 후 폴백 폰트로 전환. 웹 폰트를 다운로드를 하는데 브라우저가 네트워크 상태를 파악해 웹 폰트 전환 여부를 결정한다는 점이 있습니다.
@font-face {
    font-family: 'Noto Sans KR';
    font-style: normal;
    font-weight: 100;
    src: local('Noto Sans KR'), url(/fonts/NotoSansKR-Thin.woff) format('woff'),
    local('Noto Sans KR'), url(/fonts/NotoSansKR-Thin.woff2) format('woff2');
    font-display: swap;
}

2021.12월 기준 font-display 지원율

 

 

출처:

https://www.holisticseo.digital/pagespeed/loading-font/

https://d2.naver.com/helloworld/4969726

https://velog.io/@vnthf/%EC%9B%B9%ED%8F%B0%ED%8A%B8-%EC%B5%9C%EC%A0%81%ED%99%94-%ED%95%98%EA%B8%B0

https://web.dev/optimize-webfont-loading/

 

'Browser > 성능 최적화' 카테고리의 다른 글

Next.JS 성능 최적화해보기  (0) 2022.01.11
Comments