Fontmin을 활용한 웹 폰트 최적화 전략

웹 성능 최적화에서 폰트 처리는 핵심 과제 중 하나입니다. 특히 한글 폰트는 전체 글리프 수가 많아 파일 크기가 수 메가바이트에 달할 수 있어 로딩 지연의 주요 원인이 됩니다. Fontmin은 Node.js 기반의 폰트 최적화 도구로, 사용하지 않는 글리프를 제거하여 폰트 파일 크기를 대폭 줄일 수 있습니다.

폰트 성능 문제 진단하기

브라우저 개발자 도구의 Performance 탭을 통해 폰트 로딩 시간을 분석할 수 있습니다. 일반적으로 폰트 로딩이 100ms 이상 소요되거나 FOIT(Flash of Invisible Text) 현상이 발생하는 경우 최적화가 필요합니다.

  • 최적화 전 한글 폰트: 5MB 이상
  • 목표 파일 크기: 200KB 이하
  • 로딩 지연 시간: 50ms 미만

실제 웹 페이지에서는 전체 글리프 중 5~10%만 사용하므로, 필요한 문자만 포함하는 서브셋(subset) 생성이 효과적입니다.

Fontmin 환경 구성

Fontmin을 설치하여 개발 환경을 준비합니다:

# 전역 설치
npm install -g fontmin

# 프로젝트 내부 설치 (권장)
npm install --save fontmin

Node.js 버전은 16.0 이상이어야 하며, Windows 사용자는 Visual Studio 빌드 도구가 필요할 수 있습니다.

폰트 최적화 실행 절차

필요 문자 추출

React 또는 Vue와 같은 프레임워크에서 소스 코드 내 한글 문자를 자동으로 추출할 수 있습니다:

const { Fontmin } = require('fontmin');
const fs = require('fs');
const path = require('path');

// 소스 파일에서 한글 텍스트 추출
const sourceDir = 'src/**/*.{js,jsx,ts,tsx,vue}';
const files = glob.sync(sourceDir);
let koreanText = '';

files.forEach(file => {
  const content = fs.readFileSync(file, 'utf8');
  const matches = content.match(/[\uAC00-\uD7A3]/g);
  if (matches) koreanText += matches.join('');
});

// 중복 제거 및 폰트 최적화
const uniqueChars = [...new Set(koreanText)].join('');

new Fontmin()
  .src('assets/original-fonts/*.ttf')
  .dest('public/optimized-fonts')
  .use(Fontmin.glyph({ text: uniqueChars }))
  .run((err, files) => {
    if (err) throw err;
    console.log('폰트 최적화 완료:', files[0].history[1]);
  });

예시 결과:

  • 원본 폰트: 5.2MB (전체 한글 포함)
  • 최적화 후: 186KB (사용된 327자만 포함)

다양한 포맷 변환

브라우저 호환성을 위해 여러 포맷으로 변환합니다:

new Fontmin()
  .src('assets/fonts/*.ttf')
  .dest('output/fonts')
  .use(Fontmin.glyph({ text: uniqueChars }))
  .use(Fontmin.ttf2woff2())  // 최신 브라우저용 (최고 압축률)
  .use(Fontmin.ttf2woff())   // 구형 브라우저 지원
  .run();

자주 발생하는 오류 및 해결 방법

동적 콘텐츠 누락

AJAX나 동적 렌더링으로 추가되는 텍스트가 누락될 수 있습니다. 이를 방지하기 위해 별도의 문자 목록 파일을 관리합니다:

const staticChars = fs.readFileSync('static-text.txt', 'utf8');
const dynamicChars = fs.readFileSync('dynamic-content-chars.txt', 'utf8');
const allText = staticChars + dynamicChars;

new Fontmin()
  .use(Fontmin.glyph({ text: allText, hinting: true }))
  // ... 나머지 설정

폰트 힌팅 정보 손실

폰트 표시 품질을 유지하려면 힌팅 정보를 보존해야 합니다:

.use(Fontmin.glyph({ 
  text: extractedText, 
  hinting: true 
}))

빌드 프로세스 통합

Webpack 플러그인을 통해 빌드 시점에 자동으로 폰트 최적화를 수행할 수 있습니다:

// webpack.config.js
const FontOptimizePlugin = require('fontmin-webpack');

module.exports = {
  plugins: [
    new FontOptimizePlugin({
      sourcePath: 'src/assets/fonts/*.ttf',
      outputPath: 'dist/fonts/',
      scanPattern: 'src/**/*.{js,jsx,ts,tsx}',
      preserveHinting: true
    })
  ]
};

CI/CD 파이프라인에도 통합하여 배포마다 최신 상태의 최적화된 폰트를 생성할 수 있습니다.

문제 해결 가이드

문제 상황 해결 방법
파일 크기 감소 부족 추가 필터링 규칙 적용 및 불필요 문자 제거
폰트 깨짐 현상 hinting: true 옵션으로 힌팅 정보 유지
브라우저 호환성 문제 TTF 포맷 폴백(fallback) 추가
CLI 명령어 응답 없음 Node.js 버전 확인 (16.0 이상 필요)

Fontmin을 활용하면 웹 애플리케이션의 초기 로딩 시간을 크게 단축하고, 서버 대역폭 사용량도 줄일 수 있습니다. 디자인 품질을 유지하면서도 성능을 극대화할 수 있는 실용적인 접근법입니다.

태그: Fontmin Web Fonts performance optimization Node.js CSS Fonts

5월 24일 06:21에 게시됨