25P by neo 3일전 | ★ favorite | 댓글 1개
  • 웹폰트는 웹사이트의 시각적 요소로, 브랜드와 사용자 경험을 형성하며, 성능과 접근성에 직접적인 영향을 미침
  • 잘못된 폰트 로딩 방식은 FOUT(스타일 없는 텍스트 깜빡임) 또는 FOIT(보이지 않는 텍스트 깜빡임) 문제를 일으키며, 이는 Core Web Vitals에 부정적인 영향을 끼침
  • WOFF2 형식은 현대적이고 효율적인 폰트 포맷으로, 대부분의 최신 브라우저에서 지원되며, 불필요한 레거시 포맷을 제거해 성능을 개선
  • 폰트 서브셋팅preload 전략은 불필요한 데이터 전송을 줄이고, 페이지 로딩 속도를 높이는 데 필수적
  • 시스템 폰트 스택CSS 디스크립터를 활용해 폰트 로딩 시 레이아웃 이동(CLS)을 최소화하고 안정적인 사용자 경험을 제공

웹폰트의 간략한 역사

웹폰트는 웹 디자인과 사용자 경험의 핵심 요소로, 그 중요성에도 불구하고 많은 사람들이 잘못된 방식으로 사용하고 있음. 아래는 웹폰트의 발전 과정을 정리.

  • "웹 세이프" 시대

    • 초기 웹에서는 Arial, Times New Roman 같은 웹 세이프 폰트만 사용 가능했으며, 커스텀 폰트는 이미지로 대체
    • 브라우저마다 폰트 렌더링이 달라 일관된 디자인이 어려웠음
  • @font-face 이전의 해킹: sIFR과 Cufón

    • sIFR: Flash를 사용해 텍스트를 동적으로 렌더링했으나 무겁고 접근성이 떨어짐
    • Cufón: JavaScript로 폰트를 벡터 그래픽으로 변환해 삽입했지만 느리고 접근성 문제 유지
  • @font-face의 등장

    • @font-face는 CSS로 커스텀 폰트를 삽입할 수 있게 했으나, 브라우저마다 다른 포맷(EOT, SVG 폰트, TTF/OTF)을 요구해 복잡
    • 폰트 라이선스 문제와 불법 복제가 만연했음
  • 상용 서비스: Typekit과 동료들

    • Typekit(현 Adobe Fonts)은 라이선스와 호환성 문제를 해결한 구독 기반 서비스로, JavaScript 스니펫을 통해 폰트를 제공
    • 제3자 스크립트에 의존하는 패턴이 오늘날까지 이어짐
  • 호환성 해킹과 우회 방법

    • 여러 포맷을 호스팅하거나, FOUTFOIT를 해결하기 위한 JavaScript 수정이 필요했음
    • 아이콘 폰트를 사용해 글리프 부족 문제를 해결하려는 시도가 있었음
  • Google Fonts와 "무료 폰트" 붐

    • Google Fonts는 무료로 제공되는 오픈 라이선스 폰트를 통해 폰트 로딩의 편리함을 제공했으나, GDPR 위반 문제와 느린 로딩 속도로 인해 새로운 문제를 야기
    • 라이선스 제한으로 인해 최적화가 어려운 상용 폰트와 달리, Google Fonts는 자유로운 사용이 가능했음

폰트의 작동 방식 (기본)

폰트는 단순한 CSS 설정이 아니라, 브라우저의 렌더링 파이프라인에 깊이 관여하는 복잡한 요소임.

  • 포맷: TTF에서 WOFF2까지

    • TTF/OTF: 데스크톱 중심의 무거운 포맷
    • WOFF2: Brotli 압축을 사용한 현대적이고 효율적인 웹폰트 포맷으로, 대부분의 프로젝트에 적합
  • 렌더링 파이프라인

    • 폰트 로딩은 등록, 스타일 해결, 폰트 매칭, 글리프 커버리지, 요청, 디스플레이 단계, 디코딩 및 셰이핑의 단계를 거침
    • font-display 설정(swap, block, fallback, optional)은 텍스트 표시 방식을 결정
  • 메트릭

    • Ascent, descent, line gap 같은 메트릭은 폰트의 높이와 간격을 정의
    • 폰트 교체 시 메트릭 불일치로 레이아웃 이동(CLS)이 발생할 수 있음
  • 합성 스타일

    • 브라우저가 요청한 폰트 웨이트스타일을 찾지 못하면, 가짜 굵기나 이탤릭을 생성해 품질이 저하
    • font-synthesis: none; 으로 가짜 스타일 생성을 방지 가능
  • 글리프 커버리지

    • 폰트는 모든 문자를 포함하지 않으며, 누락된 글리프는 대체 폰트로 렌더링되어 일관성 문제 발생
    • unicode-range를 사용해 필요한 글리프만 로드하도록 설정

성능 및 전략 기초

폰트는 핵심 렌더링 경로에 영향을 미치며, 잘못된 관리로 인해 성능이 저하될 수 있음.

  • 파일 크기

    • 단일 폰트 패밀리는 최대 800KB에 달할 수 있으며, 불필요한 글리프 포함으로 데이터 낭비 발생
    • 폰트 서브셋팅으로 필요한 글리프만 전송해 크기 최적화
  • 레이아웃 이동

    • 대체 폰트와 커스텀 폰트의 메트릭 차이로 인해 CLS 발생
    • size-adjust, ascent-override 같은 CSS 디스크립터로 레이아웃 안정화
  • 현대적 CSS 디스크립터

    • font-display: swap; 은 대체 폰트를 즉시 표시해 안정적인 렌더링 제공
    • unicode-range를 통해 특정 스크립트에 필요한 글리프만 로드

가변 폰트: 약속 대 현실

가변 폰트는 하나의 파일로 다양한 스타일과 웨이트를 지원해 효율성을 높일 수 있음.

  • 약속

    • 여러 정적 파일을 단일 파일로 통합
    • 뷰포트 크기에 따라 동적으로 조정 가능한 반응형 타이포그래피
  • 현실

    • 필요한 웨이트가 적다면 가변 폰트가 더 무거울 수 있음
    • 브라우저 지원이 일부 축에서 제한적이며, 라이선스 문제가 발생 가능
  • 성능 전략

    • 필요한 축만 선택하고, 스크립트별 서브셋팅으로 파일 크기 최적화
    • 정적 폰트와 비교해 실제 이점이 있는지 확인
  • CSS에서 가변 폰트 축 사용 예시

    @font-face {  
      font-family: "Acme Variable";  
      src: url("/fonts/acme-variable.woff2") format("woff2-variations");  
      font-weight: 100 900;  
      font-display: swap;  
    }  
    h1 {  
      font-family: "Acme Variable", system-ui, sans-serif;  
      font-weight: 700;  
    }  
    

시스템 스택과 CDN

커스텀 폰트 없이 시스템 폰트 스택을 사용하면 즉각적인 로딩과 친숙한 경험 제공.

  • 시스템 폰트 스택

    • -apple-system, Segoe UI 같은 폰트로 구성된 스택은 모든 플랫폼에서 일관성 유지
    • 이모지 렌더링에서 시스템 폰트가 더 나은 성능 제공
  • CDN과 제3자 호스팅

    • Google Fonts는 데이터 유출로 인해 GDPR 위반 가능성 있음
    • 셀프 호스팅으로 DNS 조회 지연을 줄이고 캐싱 제어 가능

대체 폰트와 매칭

대체 폰트는 커스텀 폰트 로드 전 사용자 경험을 결정하며, 안정적인 설계가 필요함.

  • 대체 폰트 설계

    • x-height문자 폭을 커스텀 폰트와 유사하게 설정해 CLS 최소화
    • font-size-adjust로 대체 폰트의 크기 조정
  • 커스텀 및 대체 폰트 매칭

    • 비슷한 비율의 폰트를 선택하고, 메트릭 조정으로 레이아웃 안정성 확보
    • 플랫폼별 렌더링 차이를 고려해 안정성가독성 우선

프리로딩 및 로딩 전략

폰트 전달 전략은 사용자 경험에 큰 영향을 미침.

  • 로딩 결과

    • FOIT는 느린 네트워크에서 텍스트가 보이지 않는 문제 발생
    • font-display: swap; 은 안전한 기본값으로 즉시 대체 폰트 표시
  • 프리로딩

    • <link rel="preload" as="font">를 사용해 폰트 로딩을 즉시 시작
    • CORS 헤더와 정확한 URL 매칭이 필수
  • Early Hints (HTTP 103)

    • 서버가 HTML 응답 전에 폰트를 가져오도록 지시해 로딩 시간 단축
    • 크리티컬 폰트만 힌트로 지정해 대역폭 낭비 방지
  • 폰트 로딩 API

    • Font Loading API는 동적 사이트에서 폰트 로딩을 세밀히 제어 가능

파일 포맷: WOFF2, WOFF, TTF와 레거시 부담

WOFF2는 현대 웹에서 가장 효율적인 포맷으로, 대부분의 경우 단일 포맷으로 충분.

  • WOFF2만 사용해 불필요한 포맷 제거
  • base64 임베딩은 캐싱을 방해하므로 피해야 함

아이콘 폰트: Font Awesome과 큰 실수

아이콘 폰트는 접근성과 성능 문제로 인해 현대 웹에서 적합하지 않음.

  • SVG 아이콘은 의미적이고 유연하며, CSS로 스타일링 가능
  • 기존 아이콘 폰트 사용 시 서브셋팅과 SVG로의 전환 계획 필요

라틴을 넘어: 비라틴 스크립트, RTL 언어, 이모지

비라틴 스크립트와 RTL 언어는 복잡한 셰이핑과 메트릭을 요구.

  • 서브셋팅 시 스크립트별 특성을 고려해 렌더링 오류 방지
  • 이모지는 시스템 폰트를 사용해 일관성과 성능 개선

웹폰트의 미래: 진화하는 표준과 현대적 위험

새로운 CSS 속성과 가변 폰트, 컬러 폰트가 웹 타이포그래피를 발전시킴.

  • 폰트 로딩 APIEarly Hints로 SPA에서의 지연 문제 해결
  • 폰트를 인프라로 간주하고, 성능과 접근성을 우선시해야 함

도구와 감사

폰트 성능은 DevTools, Lighthouse, Glyphhanger 같은 도구로 측정 가능.

  • 폰트 서브셋팅 도구로 불필요한 글리프 제거
  • Font Style Matcher로 대체 폰트 메트릭 조정

폰트를 올바르게 다루기 위한 선언

폰트는 단순한 장식이 아니라 사용자 경험성능의 핵심 요소임.

  • 시스템 우선: 견고한 시스템 폰트 스택으로 시작
  • 지능적 서브셋팅: 필요한 글리프만 전송
  • WOFF2 전용: 레거시 포맷 제거
  • 글로벌 스크립트 존중: 다양한 언어와 이모지 지원
  • 테스트 중요: 다양한 네트워크와 디바이스에서 테스트

폰트를 콘텐츠이자 브랜드로 간주하고, 성능과 접근성에 대한 엄격한 관리를 적용해야 함

Cufón 정말 오랫만에 듣는 이름이네요ㅋㅋ