Next.js 의 폰트 깜빡임을 해결해 보자

ddullgi·2024년 3월 4일
1

Next.js 프로젝트를 진행하면서 적용시킨 폰트가 페이지 랜더링 시점에 깜빡이는 현상이 발생했다.

폰트 변화

물론 깜빡이는 시간이 매우 짧기 때문에 기능상으로는 문제는 없다. 하지만 FCP(First Contentful Paint)가 빠른 SSR을 적용했는데 로딩이 생기는것 처럼 보이는 것과 자간차이로 레이아웃이 바뀌는 것이 마음에 안들어 수정해 보려고 한다.

원인

처음으로 의심해 본 것은 폰트가 늦게 로딩되는게 아닐까 하는 것이였다.

하지만 확인 결과 전체 폰트를 로드하는데 걸리는 시간은 고작 87밀리초 정도였다.

FOIT와 FOUT

폰트 로딩 속도의 문제가 아니였기에 다른 원인을 찾다 FOITFOUT라는 브라우저 랜더링 차단 처리 방식에 대해 알게 되었다.

  • FOIT: Flash of Invisible Text (보이지 않는 텍스트의 깜빡임)
  • FOUT: Flash of Unstyled Text (스타일이 지정되지 않는 텍스트의 깜빡임)

FOIT는 웹폰트가 적용되지 않은 텍스트를 최대 3초까지 숨기다 웹폰트의 다운이 완료되면 텍스트를 표시하게 된다. 만일 3초가 지나도 웹폰트의 로딩이 끝나지 않았다면 대체 폰트를 사용하여 텍스트를 출력하게 된다.

FOUT의 겨우는 웹폰트가 준비될 때 까지 대체폰트를 이용하여 텍스트를 표시하게 된다.

일반적으로 FOIT 방식은 웹폰트의 준비 전까지 사용자가 텍스트를 볼 수 없기 때문에 권장 하지 않는다.

프로젝트에 적용된 방식은 FOIT방식으로 추측되어 FOUT방식으로 적용하고자 한다. 권장하지 않는 방식이나 폰트의 로딩 속도가 100ms 보다 빠르기에 문제가 없다고 판단하였다.

font-display

이제 깜빡임이 생기는 이유를 알았으니 수정해보자.

CSS에는 font-display라는 속성이 있다. 이속성은 위에서 설명한 폰트의 랜더링 방식을 바꾸는 옵션을 제공해 준다.

  • font-display: auto
    • 브라우저의 기본 동작을 따른다.
  • font-display: block
    • 폰트의 로딩 전까지는 텍스트를 표시하지 않는다.
  • font-display: swap
    • 폰트의 로딩 전까지 시스템 폰트를 사용하다 로딩 완료시 폰트를 교체한다.
  • font-display: fallback
    • 100밀리초 동안 텍스트를 숨기고, 이후 텍스트를 표시한다.
    • 폰트의 로딩 전까지 시스템 폰트를 사용하다 로딩 완료시 폰트를 교체한다.
    • 3초 경과 이후에도 폰트가 로딩되지 않는다면 시스템 글꼴로 계속 유지한다.
  • font-display: optional
    • 네트워크 여부에 따라 브라우저가 폰트의 다운 여부를 결정한다.
    • 네트워크가 좋지 않을 경우, 브라우저는 웹폰트를 캐시에 저장하고 시스템 폰트를 사용한다.
    • 다음 방문시에 캐시된 웹폰트를 사용한다.

이 속성을 이용하여 프로젝트의 폰트 랜더링 방식을 수정해 보자

body 태그에 font-display: block을 적용하였다.

결과는?

속성 자체는 적용됬으나 무시되었다.

"next/font/google" 모듈

확인해본 결과 "next/font/google" 모듈에서 제공하는 폰트 자체에 font-display 옵션이 있었다.
아마도 해당 옵션이 우선 적용되어 CSS에 적용한 font-display가 무시된 것으로 추측된다.

이 부분은 추후에 확인하여 정확한 정보를 기재해 보겠다.

그래서 "next/font/google" 모듈에서 font-display를 설정하였다.

결과는?

폰트의 변화 없이 빠르게 텍스트가 랜더링 되는것을 볼 수 있다.

profile
프론트엔드개발자를 꿈꾸는 예비 개발자

0개의 댓글