로딩 성능 최적화 - 폰트

2023. 4. 28. 18:09·프론트엔드/성능 최적화

폰트 최적화

초기 페이지 로딩 시 폰트 다운로드 하는 시간 때문에

폰트가 깜빡이는 현상이 나타난다. (폰트 다운로드 후 폰트가 글자에 입혀짐)

웹 폰트의 문제점

  • FOUT(Flash of Unstyled Text) - 폰트 다운로드 전 기본 폰트로 텍스트가 보여짐, 다운로드 후 폰트 적용된 텍스트 보여줌 / IE, Edge
  • FOIT(Flash of Invisible Text) - 폰트 다운로드 전 텍스트 노출하지 않음, 다운로드 후 폰트 적용된 텍스트 보여줌 / Chrome, Safari

웹 폰트의 최적화 방법

1) 폰트 적용 시점 컨트롤 - FOUT or FOIT or 혼합, 새 방식 등

css의 속성 font-display 사용

  • auto - 브라우저 기본 동작
  • block - FOIT(timeout = 3s) / 폰트 다운로드 완료시 폰트 입힌 텍스트 보여줌

timeout: 다운로드까지 기다리는 시간, 지나면 기본 폰트 입힌 텍스트 보여줌

  • swap - FOUT
  • fallback - FOIT(timeout = 0.1s) 3초 후에도 불러오지 못했을 시, 기본 폰트로 유지, 이후 캐시(다운로드 되도 기본 폰트 사용)
  • optional - FOIT(timeout = 0.1s) 이후 네트워크 상태에 따라, 기본 폰트로 유지할지 웹폰트를 적용할지 결정, 이후 캐시

FOIT 시 자연스러운 애니메이션 주기

FOIT 사용시 폰트가 입혀진 텍스트가 갑자기 화면에 띄워진다. fade-in 애니메이션을 줘서 자연스럽게 띄워줄 수 있다.

fontfaceobserver 모듈을 활용해서 폰트 다운로드가 완료된 시점을 감지한다.

import FontFaceObserver from 'fontfaceobserver'

function BannerVideo() {
    const [isFontLoaded, setIsFontLoaded] = useState(false)
    const font = new FontFaceObserver('BMYEONSUNG')

    useEffect(() => {
        font.load().then(function() {
            setIsFontLoaded(true)
        })
    }, [])

    //...생략

    return (
        <div style={{opacity: isFontLoaded ? 1 : 0, transition: 'opacity 0.3s ease'}}>폰트있는글씨</div>
    )
}

2) 폰트 용량 줄이기 - 용량 줄여서 빠르게 다운로드

  • 웹폰트 포맷 사용
    • 압축이 거의 안 된 TTF/OTF 대신 압축된 WOFF, WOFF2를 사용 | 용량: TTF/OTF > WOFF > WOFF2
    • 폰트 변환기 ex) https://transfonter.org 사용해서 폰트 포맷 변경 가능
    • woff2가 브라우저와 호환이 안되는 경우가 있을 수 있다. src에 각 포맷 폰트의 주소를 줘서 해결할 수 있다.
    • @font-face { font-family: hi; src; url('url') format('woff2'), url('url') format('woff'), url('url') format('truetype'); }
  • local 폰트 사용
    • 사용자 시스템에 설치되어 있는 폰트가 있을 경우 src에 추가해서 빠르게 사용할 수 있게 한다.
    • @font-face { font-family: hi; src; local('BMYEONSUNG'), url('url') format('woff2'), url('url') format('woff'), url('url') format('truetype'); }
  • Subset 사용
    • 폰트 파일은 각 글자마다 폰트 입혀진 글자가 각각 파일로 구성되어 있다.
    • 사용하는 글자 수가 적을 경우 굳이 전체 폰트를 다운로드할 필요는 없다. 필요한 글자만 다운로드해주면 된다.
    • 폰트 변환기 ex) https://transfonter.org 사용해서 Subset에 사용하는 글자 입력 후 변환해준다. 얘를 사용한다.
  • Unicode Range 적용
    • 폰트 사용하지 않는 페이지에서 불필요하게 폰트를 로드하는 것을 막기 위해 사용
    • 지정된 unicode 범위에 대해서만 폰트를 적용, 글자 없으면 폰트 로딩하지 않음
    • @font-face { font-family: hi; unicode-range: U+0041; /* A */ }
    • 유니코드 구하는 법
    • Array.prototype.map.call('ABCDEFGIKLMNOPR', c => 'u+' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4)).join(', ')
  • data-uri로 변환
    • 폰트 사이즈가 작을 경우 페이지 자체에 폰트를 넣어서 한꺼번에 다운로드하도록 한다. (네트워크 리소스 절약) - 이미지에 사용한 것과 같음
    • 폰트 변환기 ex) https://transfonter.org 사용해서 Base64 encode 켜주고 변환 -> css 파일 @font-face src 부분을 확인해보면 이상한 글자들이 엄청 많이 있다. css파일에 폰트에 대한 데이터가 직접적으로 들어가게 된다.
    • 이 방법은 굳이 안 쓸 것 같다. css 파일이 알아보기가 너무 힘들어 진다. 그리고 커진다.

3) 폰트 Preload

폰트는 css읽는 순간 로드한다. 그 시점보다 먼저 폰트를 로드하도록 하는 방법

html 파일에 link 태그로 명시해준다.

빌드된 폰트 파일 주소를 href에 넣어야 한다.

<link rel="preload" href="./static/media/font.[hash].woff2" as="font" type="font/woff2" crossorigin>

이 방식은 매 빌드시마다 hash 값 달라지기 때문에 번거롭다.

웹팩 플러그인 추가해서 편하게 폰트 preload를 할 수 있다. preload-webpack-plugin

new PreloadWebpackPlugin({
    rel: 'preload',
    as: 'font',
    include: 'allAssets',
    fileWhitelist: [/(.woff2?)/i]
})

빌드 결과물 html을 확인해보면 모든 조건에 맞는 폰트들이 link태그에 들어가 있다.

저작자표시 (새창열림)

'프론트엔드 > 성능 최적화' 카테고리의 다른 글

로딩 성능 최적화 - 텍스트 압축, 불필요한 CSS 제거  (0) 2023.04.28
로딩 성능 최적화 - 캐시  (0) 2023.04.28
로딩 성능 최적화 - 프리 로딩  (0) 2023.04.28
로딩 성능 최적화 - 코드 스플릿, 레이지 로딩  (0) 2023.04.28
로딩 성능 최적화 - 이미지, 동영상  (0) 2023.04.25
'프론트엔드/성능 최적화' 카테고리의 다른 글
  • 로딩 성능 최적화 - 텍스트 압축, 불필요한 CSS 제거
  • 로딩 성능 최적화 - 캐시
  • 로딩 성능 최적화 - 프리 로딩
  • 로딩 성능 최적화 - 코드 스플릿, 레이지 로딩
정현우12
정현우12
  • 정현우12
    정현우의 개발 블로그
    정현우12
  • 전체
    오늘
    어제
    • 분류 전체보기 (80)
      • 프론트엔드 (56)
        • JavaScript, TypeScript (12)
        • 스타일링 (1)
        • React (13)
        • Next.js (4)
        • 개발 환경 (9)
        • 테스트 (3)
        • 성능 최적화 (11)
        • 함수형 프로그래밍 (2)
        • 구조 (1)
      • 프로젝트 회고 (24)
        • 이미지편집기 개발 (7)
        • 엑셀 다운로드, 업로드 공통 모듈 개발 (4)
        • 사용자 매뉴얼 사이트 개발 (3)
        • 통계자동화 솔루션 개발 (1)
        • 엑셀 편집기 개발 (5)
        • API 플랫폼 (1)
        • 콜센터 솔루션 OB 캠페인 (1)
        • AI 스튜디오 (1)
        • AI 워크플로우 저작도구 (1)
      • 백엔드 (0)
  • 블로그 메뉴

    • 홈
    • 포트폴리오
    • 태그
  • 인기 글

  • 태그

    memoization
    성능 최적화
    Github Actions
    회고
    webpack
    렌더링 성능 최적화
    Next.js
    React
    라이브러리 선정
    이미지 편집기
    TypeScript
    엑셀
    React-boilerplate
    useReducer
    사용자 매뉴얼 사이트
    JavaScript
    커스텀 훅
    로딩 성능 최적화
    엑셀 에디터
    웹 성능 최적화
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
정현우12
로딩 성능 최적화 - 폰트
상단으로

티스토리툴바