Missed the action at the 2018 Chrome Dev Summit? Catch up with our playlist on the Google Chrome Developers channel on YouTube. Watch now.

웹 글꼴 최적화

입력 체계는 좋은 디자인, 브랜딩, 가독성 및 접근성에 있어 기본적인 요소입니다. 웹 글꼴을 사용하면 위의 모든 기능과 그 이상의 것들을 구현할 수 있습니다. 텍스트는 선택, 검색 및 확대/축소가 가능하고 높은 DPI에서도 잘 작동하며 화면 크기 및 해상도에 상관없이 일관되고 선명한 텍스트 렌더링을 제공합니다. 웹 글꼴은 좋은 디자인, UX 및 성능을 실현하는 데 중요합니다.

웹 글꼴 최적화는 전반적인 성능 전략에 중요한 부분입니다. 각 글꼴은 추가 리소스이며, 일부 글꼴은 텍스트 렌더링을 차단할 수 있지만 페이지가 웹 글꼴을 사용하는 것만으로 렌더링 속도가 느려진다고는 볼 수 없습니다. 반대로, 글꼴이 페이지에 로드되고 적용되는 방법에 대한 적절한 전략과 함께 최적화된 글꼴을 사용하면 총 페이지 크기를 줄이고 페이지 렌더링 시간을 향상시키는 데 도움이 될 수 있습니다.

웹 글꼴에 대한 분석

TL;DR

  • 유니코드 글꼴은 수천 개의 글리프를 포함할 수 있습니다.
  • 네 가지 글꼴 형식, 즉 WOFF2, WOFF, EOT 및 TTF가 있습니다.
  • 일부 글꼴 형식은 GZIP 압축을 사용해야 합니다.

웹 글꼴은 글리프로 구성된 모음이며, 각 글리프는 문자나 기호를 설명하는 벡터 모양입니다. 그 결과, 두 가지 단순한 변수가 특정 글꼴 파일의 크기를 결정합니다. 이 두 변수는 각 글리프의 벡터 경로에 대한 복잡성과 특정 글꼴에 포함된 글리프 수입니다. 예를 들어, 가장 인기 있는 웹 글꼴 중 하나인 Open Sans에는 라틴어, 그리스어 및 키릴어 문자를 포함하는 897개의 글리프가 들어 있습니다.

글꼴 글리프 표

특정 글꼴을 선택할 때에는 어떤 문자 집합이 지원되는지를 고려해야 합니다. 페이지 콘텐츠를 여러 언어로 현지화해야 할 경우 사용자에게 일관된 모양과 환경을 제공할 수 있는 글꼴을 선택해야 합니다. 예를 들어, Google의 Noto 글꼴 모음은 전 세계 모든 언어를 지원하는 것을 목표로 합니다. 하지만, 모든 언어가 포함된 Noto의 총 크기는 130MB 이상의 ZIP 다운로드를 생성한다는 사실에 유의하세요.

분명한 점은, 웹에 글꼴을 사용하려면 서체가 성능을 방해하지 않도록 세심한 엔지니어링이 필요하다는 것입니다. 고맙게도, 웹 플랫폼은 필요한 모든 원시 유형을 제공합니다. 이 가이드의 나머지 부분에서는 이 두 개념을 가장 잘 활용하는 방법을 다루는 실습을 제공합니다.

웹 글꼴 형식

오늘날, 웹에서는 네 가지 글꼴 컨테이너 형식인 EOT, TTF, WOFFWOFF2가 사용됩니다. 안타깝게도, 광범위한 옵션이 있음에도 불구하고 이전 브라우저와 최신 브라우저 모두에서 작동하는 단일한 범용 형식은 없습니다. EOT는 IE 전용이고, TTF에는 부분적인 IE 지원 기능이 포함되어 있으며, WOFF는 지원 범위가 가장 넓지만 몇몇 이전 브라우저에서는 사용할 수 없습니다. 또한, WOFF 2.0 지원은 많은 브라우저에서 현재 진행 중입니다.

그렇다면, 우리에게 남는 건 뭔가요? 모든 브라우저에서 작동하는 단일한 형식은 없습니다. 이는 일관된 환경을 제공하려면 여러 형식을 제공해야 함을 의미합니다.

  • WOFF 2.0 버전을 지원하는 브라우저에 이 글꼴을 제공합니다.
  • 대부분의 브라우저에 WOFF 버전을 제공합니다.
  • 이전 버전의 Android(4.4 이전) 브라우저에 TTF를 제공합니다.
  • 이전 버전의 IE(IE9 이전) 브라우저에 EOT 버전을 제공합니다.

참고: 기술적으로는, 또 다른 컨테이너 형식인 SVG 글꼴 컨테이너가 있지만, IE와 Firefox는 이것을 지원하지 않았으며 Chrome에서도 이제는 지원이 중단되었습니다. 또한 사용이 제한적이며 이 가이드에서 의도적으로 생략되었습니다.

압축을 통해 글꼴 크기 줄이기

글꼴은 글리프의 모음이며, 각각 문자 형태를 설명하는 경로 집합입니다. 개별 글리프는 각각 다르지만, GZIP 또는 호환되는 압축 프로그램을 통해 압축될 수 있는 유사한 정보가 많이 들어 있습니다.

  • EOT 및 TTF 형식은 기본적으로 압축되지 않습니다. 서버가 이러한 형식을 제공할 때 GZIP 압축을 적용하도록 구성되었는지 확인하세요.
  • WOFF는 압축이 기본 제공됩니다. WOFF 압축 프로그램이 최적의 압축 설정을 사용하고 있는지 확인하세요.
  • WOFF2는 맞춤형 처리 및 압축 알고리즘을 사용하여 다른 형식에 비해 30% 정도 파일 크기를 절감합니다. 자세한 내용은 WOFF 2.0 평가 보고서를 참조하세요.

마지막으로, 일부 글꼴 형식에 특정 플랫폼에서 필요하지 않을 수 있는 글꼴 힌트커닝 정보와 같은 추가적인 메타데이터가 들어 있다는 사실에 주목할 필요가 있습니다. 따라서 추가적인 파일 크기 최적화가 가능합니다. 사용하는 글꼴 압축 프로그램에 사용 가능한 최적화 옵션에 대해 문의하고, 이 방법을 택할 경우 이러한 최적화된 글꼴을 테스트하고 각 브라우저에 제공하는 데 적합한 인프라를 갖추고 있는지 확인하세요. 예를 들어, Google Fonts는 각 글꼴에 대해 30개 이상의 최적화된 버전을 유지하고, 각 플랫폼 및 브라우저에 최적의 버전을 자동으로 검색하여 제공합니다.

참고: EOT, TTF 및 WOFF 형식에 Zopfli 압축을 사용해 보세요. Zopfli는 gzip을 통해 약 5%의 파일 크기 절감 효과를 제공하는 zlib 호환 압축 프로그램입니다.

@font-face를 사용하여 글꼴 모음 정의

TL;DR

  • format() 힌트를 사용하여 여러 글꼴 형식을 지정합니다.
  • 성능 향상을 위해 큰 유니코드 글꼴을 서브세팅합니다. 유니코드 범위 서브세팅을 사용하고 이전 브라우저에 대해 수동 서브세팅 대안을 제공합니다.
  • 페이지 및 텍스트 렌더링 성능을 향상시키기 위해 스타일 글꼴 버전 수를 줄입니다.

@font-face CSS at-rule을 사용하면 특정 글꼴 리소스의 위치, 해당 스타일 특징 및 이 글꼴이 사용되는 유니코드 코드 포인트를 정의할 수 있습니다. 이러한 @font-face 선언의 조합은 '글꼴 모음'을 생성하는 데 사용될 수 있으며, 브라우저는 이 글꼴 모음을 사용하여 어떠한 글꼴 리소스를 다운로드하여 현재 페이지에 적용해야 할지를 평가합니다.

형식 선택

각 @font-face 선언은 여러 선언의 논리적 그룹으로 작용하는 글꼴 모음의 이름, 글꼴 속성(예: style, weight 및 stretch) 그리고 글꼴 리소스의 위치에 대해 우선순위가 지정된 목록을 지정하는 src 설명자를 제공합니다.

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome.woff2') format('woff2'), 
       url('/fonts/awesome.woff') format('woff'),
       url('/fonts/awesome.ttf') format('truetype'),
       url('/fonts/awesome.eot') format('embedded-opentype');
}

@font-face {
  font-family: 'Awesome Font';
  font-style: italic;
  font-weight: 400;
  src: local('Awesome Font Italic'),
       url('/fonts/awesome-i.woff2') format('woff2'), 
       url('/fonts/awesome-i.woff') format('woff'),
       url('/fonts/awesome-i.ttf') format('truetype'),
       url('/fonts/awesome-i.eot') format('embedded-opentype');
}

우선, 위의 예시에서는 두 가지 스타일(normal 및 italic)을 가지는 단일 Awesome Font 모음을 정의합니다. 이러한 스타일은 각각 다른 글꼴 리소스 집합을 가리킵니다. 각각의 src 설명자에는 우선순위가 지정되고 쉼표로 구분된 리소스 버전 목록이 포함되어 있습니다.

  • local() 지시문을 사용하면 로컬로 설치된 글꼴을 참조, 로드하고 사용할 수 있습니다.
  • url() 지시문을 사용하면 외부 글꼴을 로드할 수 있으며, 이 지시문은 제공된 URL에서 참조하는 글꼴의 형식을 나타내는 format() 힌트(선택 항목)를 포함할 수 있습니다.

참고: 기본 시스템 글꼴 중 하나를 참조하지 않을 경우, 실제로 사용자가 글꼴을 로컬로 설치하는 경우는 드물며, 특히 추가 글꼴을 '설치'하는 것이 사실상 불가능한 휴대기기에서 더 그렇습니다. 따라서, 항상 외부 글꼴 위치 목록을 제공해야 합니다.

브라우저가 글꼴이 필요한지 여부를 결정할 때에는 지정된 순서대로 제공된 리소스 목록의 항목에 대해 확인 절차를 반복하여 적절한 리소스를 로드하려고 시도합니다. 예를 들어, 위의 예시를 실행한 후에는 다음 작업이 수행됩니다.

  1. 브라우저가 페이지 레이아웃을 수행하고 페이지에 지정된 텍스트를 렌더링하는 데 필요한 글꼴 버전을 결정합니다.
  2. 각 필요한 글꼴에 대해 브라우저가 이 글꼴을 로컬로 사용할 수 있는지 여부를 확인합니다.
  3. 글꼴을 로컬로 사용할 수 없으면 브라우저가 외부 정의에서 이 과정을 반복합니다.
    • 형식 힌트가 존재하면 브라우저는 다운로드를 시작하기 전에 이 힌트를 지원하는지 여부를 확인합니다. 브라우저가 힌트를 지원하지 않을 경우 그 다음 항목으로 진행합니다.
    • 형식 힌트가 없을 경우 브라우저는 리소스를 다운로드합니다.

로컬 및 외부 지시문을 적절한 형식 힌트와 함께 사용하면, 모든 사용 가능한 글꼴 형식을 직접 지정할 수 있으며 나머지는 브라우저가 처리하도록 맡길 수 있습니다. 브라우저는 필요한 리소스를 파악하고 최적의 형식을 선택합니다.

참고: 글꼴 버전이 지정되는 순서는 중요합니다. 브라우저는 자신이 지원하는 형식 중 첫 번째 형식을 선택합니다. 따라서, 최신 브라우저가 WOFF2를 사용하도록 하려면 WOFF2 선언을 WOFF 위에 추가해야 하는 식입니다.

유니코드 범위 서브세팅

style, weight 및 stretch와 같은 글꼴 속성 외에도, @font-face 규칙을 사용하면 각 리소스에서 지원되는 유니코드 코드 포인트 집합을 정의할 수 있습니다. 이를 통해 대규모 유니코드 글꼴을 더 작은 하위 집합(예: 라틴어, 키릴어 및 그리스어 하위 집합)으로 분할하여 특정 페이지에서 텍스트를 렌더링하는 데 필요한 글리프만 다운로드할 수 있습니다.

유니코드 범위 설명자를 사용하면 쉼표로 구분된 범위 값 목록을 지정할 수 있습니다. 각 범위 값은 다음 세 가지 형식 중 하나일 수 있습니다.

  • 단일 코드 포인트(예: U+416)
  • 간격 범위(예: U+400-4ff): 범위의 시작 및 끝 코드 포인트를 나타냅니다.
  • 와일드 카드 범위(예: U+4??): '?' 문자는 임의의 16진수를 나타냅니다.

예를 들어, Awesome Font 모음을 라틴어 및 일본어 하위 집합으로 분할할 수 있으며, 브라우저가 필요에 따라 이 하위 집합을 각각 다운로드합니다.

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2'), 
       url('/fonts/awesome-l.woff') format('woff'),
       url('/fonts/awesome-l.ttf') format('truetype'),
       url('/fonts/awesome-l.eot') format('embedded-opentype');
  unicode-range: U+000-5FF; /* Latin glyphs */
}

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-jp.woff2') format('woff2'), 
       url('/fonts/awesome-jp.woff') format('woff'),
       url('/fonts/awesome-jp.ttf') format('truetype'),
       url('/fonts/awesome-jp.eot') format('embedded-opentype');
  unicode-range: U+3000-9FFF, U+ff??; /* Japanese glyphs */
}

참고: 아시아 언어에서는 유니코드 범위 서브세팅이 특히 중요합니다. 여기서는 문자 수가 서양 언어보다 훨씬 더 많고, 일반적인 '전체' 글꼴은 대개 수십 킬로바이트가 아니라 메가바이트로 측정됩니다.

유니코드 범위 하위 집합과 글꼴의 각 스타일 버전에 대해 별도의 파일을 사용하면 다운로드하기에 더욱 빠르면서도 더욱 효율적인 합성 글꼴 모음을 정의할 수 있습니다. 방문자는 필요한 버전과 하위 집합만 다운로드하면 되고, 페이지에서 절대로 보거나 사용하지 않을 하위 집합은 다운로드할 필요가 없습니다.

하지만, 유니코드 범위에는 한 가지 사소한 문제가 있습니다. 아직 일부 브라우저가 이를 지원하지 않습니다. 일부 브라우저는 유니코드 범위 힌트를 무시하고 모든 버전을 다운로드하는 반면, 이외의 다른 브라우저는 @font-face 선언을 전혀 처리하지 않을 수 있습니다. 이를 해결하려면 이전 브라우저의 경우 '수동 서브세팅'으로 돌아가야 합니다.

이전 브라우저는 필요한 하위 집합만 선택할 만큼 지능적이지 않고 합성 글꼴을 생성할 수 없으므로 필요한 모든 하위 집합을 포함하는 단일 글꼴 리소스를 제공하는 것으로 환원해야 하며, 브라우저에서 나머지 글꼴 리소스는 숨겨야 합니다. 예를 들어, 페이지가 라틴어 문자만 사용할 경우 다른 글리프를 제거하고 해당 특정 하위 집합을 독립형 리소스로 제공할 수 있습니다.

  1. 필요한 하위 집합은 어떻게 판별할까요?
    • 브라우저가 유니코드 범위 하위 집합을 지원하는 경우 올바른 하위 집합을 자동으로 선택합니다. 페이지는 하위 집합 파일을 제공하고 @font-face 규칙에 적절한 유니코드 범위만 지정하면 됩니다.
    • 브라우저가 유니코드 범위 하위 집합을 지원하지 않으면, 페이지에서 모든 불필요한 하위 집합을 숨겨야 합니다. 즉, 개발자가 필수 하위 집합을 지정해야 합니다.
  2. 글꼴 하위 집합을 어떻게 생성하나요?
    • 오픈소스 pyftsubset 도구를 사용하여 글꼴을 서브세팅하고 최적화합니다.
    • 일부 글꼴 서비스에서는 페이지에 필요한 하위 집합을 수동으로 지정하는 데 사용할 수 있는 사용자설정 쿼리 매개변수를 통한 수동 서브세팅을 허용합니다. 글꼴 제공업체의 문서를 참조하세요.

글꼴 선택 및 합성

각 글꼴 모음은 여러 스타일 버전(일반, 굵게, 기울임꼴)과 각 스타일에 대한 여러 두께로 구성됩니다. 각 스타일에는 서로 아주 다른 글리프 모양(예: 공백, 크기 또는 모양이 서로 다름)이 포함될 수 있습니다.

글꼴 두께

예를 들어, 위에 나와 있는 다이어그램은 세 가지 서로 다른 두께, 즉 400(일반), 700(굵게) 및 900(아주 굵게)을 제공하는 글꼴 모음을 보여줍니다. 그 사이에 있는 기타 모든 버전(회색으로 표시되어 있음)은 브라우저에 의해 가장 가까운 버전으로 자동으로 매핑됩니다.

글꼴이 존재하지 않는 상태에서 두께가 지정되면 가까운 두께를 가진 글꼴이 사용됩니다. 일반적으로, 굵은 두께는 두꺼운 두께를 가진 글꼴에 매핑되고, 얇은 두께는 얇은 두께를 가진 글꼴에 매핑됩니다.

CSS3 글꼴 매칭 알고리즘

유사한 논리가 기울임꼴 버전에도 적용됩니다. 글꼴 디자이너는 생성되는 버전을 제어하고, 개발자는 페이지에 사용할 버전을 제어합니다. 버전은 각각 개별적인 다운로드이므로 버전 수를 적게 유지하는 것이 좋습니다. 예를 들어, Awesome Font 모음에 대해 두 가지 굵은 글꼴 버전을 정의할 수 있습니다.

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome-l.woff2') format('woff2'), 
       url('/fonts/awesome-l.woff') format('woff'),
       url('/fonts/awesome-l.ttf') format('truetype'),
       url('/fonts/awesome-l.eot') format('embedded-opentype');
  unicode-range: U+000-5FF; /* Latin glyphs */
}

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 700;
  src: local('Awesome Font'),
       url('/fonts/awesome-l-700.woff2') format('woff2'), 
       url('/fonts/awesome-l-700.woff') format('woff'),
       url('/fonts/awesome-l-700.ttf') format('truetype'),
       url('/fonts/awesome-l-700.eot') format('embedded-opentype');
  unicode-range: U+000-5FF; /* Latin glyphs */
}

위의 예시에서는 동일한 라틴어 글리프 집합(U+000-5FF)을 포함하되, 두 가지 다른 '두께', 즉 일반(400) 및 굵게(700)를 제공하는 두 가지 리소스로 구성된 Awesome Font 모음을 선언합니다. 하지만, CSS 규칙 중 하나가 다른 글꼴 두께를 지정하거나 font-style 속성을 italic으로 설정하면 어떻게 될까요?

  • 정확한 글꼴 일치를 사용할 수 없는 경우 브라우저는 가장 가까운 일치 항목을 대신 사용합니다.
  • 스타일 일치 항목이 없으면(예: 위의 예에서는 기울임꼴 버전이 선언되지 않음) 브라우저가 자체 글꼴 버전을 합성합니다.

글꼴 합성

작성자는 또한 기울임꼴 형식이 모양 면에서 상당히 다른 키릴어와 같은 스크립트에는 합성 방식이 적합하지 않을 수 있다는 점을 인식하고 있어야 합니다. 어떠한 경우든지 합성 버전을 사용하기 보다는 실제 기울임꼴 글꼴을 사용하는 것이 더 좋습니다.

CSS3 font-style

위의 예시에서는 Open-Sans에 대한 실제 글꼴 결과와 합성 글꼴 결과 사이의 차이점을 보여줍니다. 모든 합성 버전은 단일한 400 두께 글꼴을 기반으로 생성되었습니다. 보시다시피, 결과가 눈에 띄게 차이가 납니다. 굵은 글꼴 버전과 기울임꼴 글꼴 버전을 생성하는 방법에 대한 세부정보는 명시되어 있지 않습니다. 따라서, 결과는 브라우저마다 달라지며 글꼴에 따라서도 상당히 달라집니다.

참고: 최상의 일관성 및 시각적 효과를 얻기 위해서는 글꼴 합성을 사용하지 마세요. 대신, 사용되는 글꼴 버전의 수를 최소화하고 해당 위치를 지정하세요. 그러면 브라우저가 페이지에서 글꼴이 사용될 때 이러한 글꼴을 다운로드할 수 있습니다. 하지만, 일부 경우 합성된 버전이 사용 가능한 옵션일 수 있으므로 합성된 버전을 사용할 때 주의하세요.

로드 및 렌더링 최적화

TL;DR

  • 글꼴 요청은 텍스트 렌더링을 지연시킬 수 있으므로 렌더링 트리가 생성될 때까지 지연됩니다.
  • Font Loading API를 사용하면 기본 지연 로드(lazyload) 글꼴 로드를 재정의하는 맞춤형 글꼴 로드 및 렌더링 전략을 구현할 수 있습니다.
  • 이전 브라우저에서는 글꼴 인라인 처리를 통해 기본 지연 로드(lazyload) 글꼴 로드를 재정의할 수 있습니다.

필요하지 않을 수 있는 모든 스타일 버전과 사용되지 않을 수 있는 모든 글리프를 포함하는 '전체' 웹 글꼴은 수 메가바이트 크기의 다운로드를 쉽게 발생시킬 수 있습니다. 이 문제를 해결하기 위해 @font-face CSS 규칙은 글꼴 모음을 유니코드 하위 집합, 개별 스타일 버전 등의 리소스 모음으로 분할할 수 있도록 특별히 설계되었습니다.

이러한 선언을 고려하여 브라우저는 필요한 하위 집합 및 버전을 파악하고 텍스트를 렌더링하는 데 필요한 최소 집합만 다운로드하며, 이것은 매우 편리합니다. 그러나 주의하지 않으면, 주요 렌더링 경로에서 성능 병목 현상이 발생할 수도 있고 텍스트 렌더링이 지연될 수도 있습니다.

웹 글꼴 및 주요 렌더링 경로

글꼴의 지연 로드에는 중요한 함축이 숨겨져 있습니다. 즉, 텍스트 렌더링을 지연시킬 수 있다는 것입니다. 브라우저는 텍스트를 렌더링하는 데 필요한 글꼴 리소스가 무엇인지 인식하기 전에 렌더링 트리를 생성해야 하며, 이 렌더링 트리는 DOM 및 CSSOM 트리에 종속됩니다. 따라서, 글꼴 요청은 다른 주요 리소스 훨씬 후로 지연되며, 브라우저는 리소스를 가져올 때까지 텍스트를 렌더링하지 못하도록 차단될 수 있습니다.

글꼴 주요 렌더링 경로

  1. 브라우저가 HTML 문서를 요청합니다.
  2. 브라우저가 HTML 응답 파싱 및 DOM 생성 작업을 시작합니다.
  3. 브라우저가 CSS, JS 및 기타 리소스를 발견하고 요청을 발송합니다.
  4. 모든 CSS 콘텐츠가 수신된 후 브라우저가 CSSOM을 생성하고 이를 DOM 트리와 결합하여 렌더링 트리를 생성합니다.
    • 렌더링 트리가 페이지에 지정된 텍스트를 렌더링하는 데 필요한 글꼴 버전이 무엇인지 나타내면 글꼴 요청이 발송됩니다.
  5. 브라우저가 레이아웃을 수행하고 콘텐츠를 화면에 페인팅합니다.
    • 글꼴을 아직 사용할 수 없으면, 브라우저가 텍스트 픽셀을 렌더링할 수 없습니다.
    • 글꼴을 사용할 수 있게 되면, 브라우저가 텍스트 픽셀을 페인팅합니다.

렌더링 트리가 빌드된 후 곧바로 수행될 수 있는 첫 번째 페이지 콘텐츠 페인트와 글꼴 리소스에 대한 요청 사이의 '경합'으로 인해 '빈 텍스트 문제'가 생성됩니다. 이 경우 브라우저가 페이지 레이아웃을 렌더링할 수는 있지만 모든 텍스트를 생략합니다. 실제 동작은 브라우저마다 다릅니다.

  • Safari는 글꼴 다운로드가 완료될 때까지 텍스트 렌더링을 지연시킵니다.
  • Chrome과 Firefox는 글꼴 렌더링을 최대 3초까지 지연하며, 그 후에는 대체 글꼴을 사용합니다. 글꼴 다운로드가 완료된 후, 다운로드된 글꼴을 사용하여 텍스트를 다시 렌더링합니다.
  • IE는 요청 글꼴을 아직 사용할 수 없는 경우 대체 글꼴을 사용하여 즉시 렌더링하고, 글꼴 다운로드가 완료된 후 텍스트를 다시 렌더링합니다.

다른 여러 렌더링 전략에 대한 좋은 논쟁들이 있습니다. 몇몇 사람들은 다시 렌더링하는 것이 불편하다고 생각하는 반면, 다른 사람들은 즉각적인 결과를 보기를 선호하고 글꼴 다운로드가 완료된 후 페이지 리플로우가 수행되는 것을 개의치 않습니다. 여기서 이러한 논쟁에 대해 살펴보지는 않겠습니다. 중요한 점은 지연 로드는 바이트 수를 줄이지만, 텍스트 렌더링을 지연시킬 수도 있다는 점입니다. 다음 섹션에서는 이 동작을 최적화하는 방법에 대해 설명합니다.

Font Loading API를 사용하여 글꼴 렌더링 최적화

Font Loading API는 CSS 글꼴을 정의하고 조작하며, 해당 다운로드 진행 상황을 추적하고, 해당 기본 지연 로드 동작을 재정의할 수 있는 스크립팅 인터페이스를 제공합니다. 예를 들어, 특정 글꼴 버전이 필요하다고 확신할 경우 이 글꼴 버전을 정의하고 브라우저에 글꼴 리소스에 대한 즉각적인 가져오기를 시작하도록 지시할 수 있습니다.

var font = new FontFace("Awesome Font", "url(/fonts/awesome.woff2)", {
  style: 'normal', unicodeRange: 'U+000-5FF', weight: '400'
});

font.load(); // don't wait for the render tree, initiate an immediate fetch!

font.ready().then(function() {
  // apply the font (which may re-render text and cause a page reflow)
  // after the font has finished downloading
  document.fonts.add(font);
  document.body.style.fontFamily = "Awesome Font, serif";

  // OR... by default the content is hidden, 
  // and it's rendered after the font is available
  var content = document.getElementById("content");
  content.style.visibility = "visible";

  // OR... apply your own render strategy here... 
});

또한, check() 메서드를 통해 글꼴 상태를 확인하고 해당 다운로드 진행 상황을 추적할 수 있으므로, 텍스트를 페이지에 렌더링하기 위한 맞춤형 전략을 정의할 수도 있습니다.

  • 글꼴을 사용할 수 있게 될 때까지 모든 텍스트 렌더링을 보류할 수 있습니다.
  • 각 글꼴별로 맞춤형 제한 시간을 구현할 수 있습니다.
  • 대체 글꼴을 사용하여 렌더링이 차단되지 않도록 하고 글꼴을 사용할 수 있게 되면 원하는 글꼴을 사용하는 새로운 스타일을 삽입할 수 있습니다.

무엇보다도, 위에 설명된 전략을 페이지의 서로 다른 콘텐츠에 맞게 적절히 혼합할 수도 있습니다. 예를 들어, 글꼴을 사용할 수 있게 될 때까지 일부 섹션에서 텍스트 렌더링을 지연시킬 수 있고, 대체 글꼴을 사용한 후 글꼴 다운로드가 완료된 후 다시 렌더링할 수 있으며, 각각 다른 제한 시간을 지정할 수가 있습니다.

참고: Font Loading API는 몇몇 브라우저에서 여전히 개발 중에 있습니다. 추가 자바스크립트 종속성으로 인한 오버헤드가 있기는 하지만 유사한 기능을 제공하려면 FontLoader 폴리필 또는 webfontloader 라이브러리를 사용해 보세요.

인라인 처리를 통해 글꼴 렌더링 최적화

Font Loading API를 사용하여 '빈 텍스트 문제'를 제거하는 방법 대신 사용할 수 있는 간단한 다른 전략은 글꼴 콘텐츠를 CSS 스타일시트에 인라인으로 추가하는 것입니다.

  • CSSOM 구성에 필요하므로, 브라우저는 일치하는 미디어 쿼리가 있는 CSS 스타일시트를 우선적으로 자동 다운로드합니다.
  • 글꼴 데이터를 CSS 스타일시트에 인라인 처리하면 브라우저가 렌더링 트리를 기다리지 않고 우선적으로 해당 글꼴을 다운로드하도록 만들 수 있습니다. 즉, 기본 지연 로드 동작을 수동으로 재정의하는 것과 같습니다.

인라인 처리 전략은 유연하지 않고 각 콘텐츠에 대해 맞춤형 제한 시간 또는 렌더링 전략을 정의할 수도 없지만, 간단하며 모든 브라우저에서 작동하는 강력한 솔루션입니다. 최상의 결과를 얻으려면, 인라인 처리된 글꼴을 독립형 스타일시트에 분리하고, max-age를 길게 설정하여 글꼴을 제공하세요. 그러면 CSS를 업데이트할 때 방문자가 글꼴을 다시 다운로드하지 않아도 됩니다.

참고: 인라인 처리는 선별적으로 사용해야 합니다. @font-face가 지연 로드 동작을 사용하는 이유는 불필요한 글꼴 버전과 하위 요소들을 다운로드하는 것을 방지하기 위한 것임을 기억하세요. 또한, 공격적인 인라인 처리를 통해 CSS의 크기를 늘리면 주요 렌더링 경로에 부정적인 영향을 미치게 됩니다. 브라우저는 먼저 모든 CSS를 다운로드해야만 CSSOM을 생성하고, 렌더링 트리를 빌드하고, 화면에 페이지 콘텐츠를 렌더링할 수 있습니다.

HTTP 캐싱을 통한 글꼴 재활용 최적화

글꼴 리소스는 일반적으로 자주 업데이트되지 않는 정적 리소스입니다. 따라서, 긴 max-age 만료에 적합합니다. 모든 글꼴 리소스에 조건부 ETag 헤더최적의 Cache-Control 정책을 지정해야 합니다.

글꼴을 localStorage나 다른 메커니즘을 통해 저장할 필요가 없습니다. 이러한 글꼴에는 각각 고유한 성능 문제가 있습니다. Font Loading API 또는 webfontloader 라이브러리와 함께 브라우저의 HTTP 캐시는 글꼴 리소스를 브라우저에 제공하는 최고이자 가장 강력한 메커니즘을 제공합니다.

최적화 검사 목록

일반적인 믿음과는 달리, 웹 글꼴을 사용할 경우 페이지 렌더링을 지연시킬 필요가 없고 다른 성능 메트릭에 부정적인 영향을 미치지도 않습니다. 글꼴 사용을 제대로 최적화하면, 모든 화면 형식 및 해상도에 잘 맞는 확장 가능한 다중 해상도 솔루션과 더불어 뛰어난 브랜딩, 가독성, 사용성 및 검색 가능성 향상 등 전반적으로 훨씬 더 나은 사용자 환경을 제공할 수 있습니다. 웹 글꼴을 사용하는 것을 두려워하지 마세요.

하지만, 아무것도 모르는 상태에서 단순하게 구현하면 대규모 다운로드 및 불필요한 지연이 발생할 수 있습니다. 글꼴 자산을 최적화하고 글꼴 자산을 가져와서 페이지에 사용하는 방법을 최적화하여 브라우저를 도와야 합니다.

  • 글꼴 사용 감사 및 모니터링: 페이지에 너무 많은 글꼴을 사용하지 말고, 각 글꼴마다 사용된 글꼴 버전의 수를 최소화하세요. 이렇게 하면 사용자에게 더욱 일관되고 빠른 경험을 제공할 수 있습니다.
  • 글꼴 리소스 서브세팅: 많은 글꼴을 서브세팅하거나 여러 유니코드 범위로 분할하면 특정 페이지에 필요한 글리프만 제공할 수 있습니다. 그러면 파일 크기가 줄어들고 리소스의 다운로드 속도가 향상됩니다. 하지만, 하위 집합을 정의할 때 글꼴 재활용에 맞게 최적화하도록 주의를 기울이세요. 예를 들어, 각 페이지에서 서로 다르지만 겹치는 문자 집합은 다운로드하지 마세요. 좋은 방법은 스크립트(예: 라틴어, 키릴어 등)를 기반으로 서브세팅하는 것입니다.
  • 각 브라우저에 최적화된 글꼴 형식 제공: 각 글꼴을 WOFF2, WOFF, EOT 및 TTF 형식으로 제공합니다. GZIP 압축을 EOT 및 TTF 형식에 적용해야 합니다. 이들 형식은 기본적으로 압축되지 않기 때문입니다.
  • 유효성 재검사 및 최적의 캐싱 정책 지정: 글꼴은 자주 업데이트되지 않는 정적 리소스입니다. 여러 페이지 간에 효율적인 글꼴 재활용이 가능하도록, 수명이 긴 max-age 타임스탬프와 유효성 재검사 토큰을 서버가 제공해야 합니다.
  • Font Loading API를 사용하여 주요 렌더링 경로 최적화: 기본 지연 로드 동작은 텍스트 렌더링 지연을 초래할 수 있습니다. Font Loading API를 사용하면 특정 글꼴에 대해 이 동작을 재정의하고 페이지의 각 콘텐츠에 대해 맞춤형 렌더링 및 제한 시간 전략을 지정할 수 있습니다. 이 API를 지원하지 않는 이전 브라우저의 경우, 웹 글꼴 로더 자바스크립트 라이브러리를 사용하거나 CSS 인라인 처리 전략을 사용할 수 있습니다.