Уменьшить размер веб-шрифта

Типографика имеет основополагающее значение для хорошего дизайна, брендинга, читаемости и доступности. Веб-шрифты позволяют реализовать все вышеперечисленное и многое другое: текст можно выделить, искать, масштабировать, и они совместимы с высоким разрешением (DPI), обеспечивая стабильное и четкое отображение текста независимо от размера и разрешения экрана. Веб-шрифты имеют решающее значение для хорошего дизайна, пользовательского опыта и производительности.

Оптимизация веб-шрифтов — важнейший элемент общей стратегии повышения производительности. Каждый шрифт — это дополнительный ресурс, и некоторые шрифты могут блокировать отрисовку текста, но тот факт, что страница использует веб-шрифты, не означает, что она должна отображаться медленнее. Напротив, оптимизированные шрифты в сочетании с продуманной стратегией их загрузки и применения на странице могут помочь уменьшить общий размер страницы и улучшить время её отрисовки.

Анатомия веб-шрифта

Веб-шрифт — это набор глифов, и каждый глиф представляет собой векторную фигуру, описывающую букву или символ. В результате размер файла шрифта определяется двумя простыми переменными: сложностью векторных путей каждого глифа и количеством глифов в конкретном шрифте. Например, Open Sans, один из самых популярных веб-шрифтов, содержит 897 глифов, включая латинские, греческие и кириллические символы.

Таблица глифов шрифта

При выборе шрифта важно учитывать, какие наборы символов поддерживаются. Если вам необходимо локализовать контент страницы на несколько языков, следует использовать шрифт, который обеспечит единообразный внешний вид и удобство использования для ваших пользователей. Например, семейство шрифтов Noto от Google стремится поддерживать все языки мира. Однако следует отметить, что общий размер Noto, включая все языки, составляет более 1,1 ГБ в ZIP-архиве.

В этой статье вы узнаете, как уменьшить размер файла, в который поставляются ваши веб-шрифты.

форматы веб-шрифтов

Сегодня в интернете используются два рекомендуемых формата контейнеров шрифтов:

WOFF и WOFF 2.0 пользуются широкой поддержкой и совместими со всеми современными браузерами.

  • Предоставлять вариант WOFF 2.0 для современных браузеров.
  • В случае крайней необходимости — например, если вам по-прежнему нужна поддержка Internet Explorer 11 — используйте WOFF-файл в качестве резервного варианта.
  • В качестве альтернативы можно рассмотреть вариант отказа от использования веб-шрифтов в устаревших браузерах и перехода на системные шрифты. Это также может обеспечить более высокую производительность на старых, менее мощных устройствах.
  • Поскольку форматы WOFF и WOFF 2.0 охватывают все аспекты современных и устаревших браузеров, использование EOT и TTF больше не требуется и может привести к увеличению времени загрузки веб-шрифтов.

Веб-шрифты и сжатие

И WOFF, и WOFF 2.0 имеют встроенную функцию сжатия. Встроенная функция сжатия WOFF 2.0 использует Brotli и обеспечивает до 30% более высокую степень сжатия, чем WOFF. Для получения дополнительной информации см. отчет об оценке WOFF 2.0 .

Наконец, стоит отметить, что некоторые форматы шрифтов содержат дополнительные метаданные, такие как информация о хинтинге и кернинге , которые могут быть не нужны на некоторых платформах, что позволяет дополнительно оптимизировать размер файла. Например, Google Fonts поддерживает более 30 оптимизированных вариантов для каждого шрифта и автоматически определяет и предоставляет оптимальный вариант для каждой платформы и браузера.

Задайте семейство шрифтов с помощью @font-face

Правило @font-face в CSS позволяет определить местоположение конкретного ресурса шрифта, его характеристики стиля и кодовые точки Unicode, для которых он должен использоваться. Комбинация таких объявлений @font-face может использоваться для создания «семейства шрифтов», которое браузер будет использовать для определения того, какие ресурсы шрифтов необходимо загрузить и применить к текущей странице.

Рассмотрим шрифт с изменяемым размером шрифта.

Использование вариативных шрифтов может значительно уменьшить размер файлов шрифтов в тех случаях, когда вам требуется несколько вариантов одного шрифта. Вместо загрузки обычного и жирного стилей, а также их курсивных версий, вы можете загрузить один файл, содержащий всю необходимую информацию. Однако размер файлов вариативных шрифтов будет больше, чем размер файла отдельного варианта шрифта, хотя и меньше, чем размер комбинации множества вариантов. Вместо одного большого файла вариативного шрифта, возможно, лучше сначала загрузить основные варианты шрифта, а остальные варианты загрузить позже.

В настоящее время все современные браузеры поддерживают вариативные шрифты. Подробнее об этом можно узнать в разделе «Введение в вариативные шрифты в интернете» .

Выберите правильный формат

Каждое объявление @font-face содержит имя семейства шрифтов, которое представляет собой логическую группу из нескольких объявлений, свойства шрифта , такие как стиль, толщина и растяжение, а также дескриптор `src` , который задает приоритетный список местоположений для ресурса шрифта.

@font-face {
  font-family: 'Awesome Font';
  font-style: normal;
  font-weight: 400;
  src: local('Awesome Font'),
       url('/fonts/awesome.woff2') format('woff2'),
       /* Only serve WOFF if necessary. Otherwise,
          WOFF 2.0 is fine by itself. */
       url('/fonts/awesome.woff') format('woff');
}

@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');
}

Во-первых, обратите внимание, что в приведенных выше примерах определяется одно семейство шрифтов Awesome Font с двумя стилями (обычный и курсивный ), каждый из которых указывает на разный набор ресурсов шрифта. В свою очередь, каждый дескриптор src содержит приоритетный список вариантов ресурсов, разделенных запятыми:

  • Директива local() позволяет ссылаться на локально установленные шрифты, загружать и использовать их. Если шрифт уже установлен в системе пользователя, это полностью обходит сетевое соединение и является самым быстрым способом.
  • Директива url() позволяет загружать внешние шрифты и может содержать необязательную подсказку format() , указывающую формат шрифта, на который ссылается предоставленный URL.

Когда браузер определяет, что шрифт необходим, он перебирает предоставленный список ресурсов в указанном порядке и пытается загрузить соответствующий ресурс. Например, следуя приведенному выше примеру:

  1. Браузер выполняет компоновку страницы и определяет, какие варианты шрифтов необходимы для отображения указанного текста на странице. Шрифты, не входящие в объектную модель CSS страницы (CSSOM), не загружаются браузером, поскольку они не требуются.
  2. Для каждого необходимого шрифта браузер проверяет, доступен ли он локально.
  3. Если шрифт недоступен локально, браузер перебирает внешние определения:
    • Если указан формат файла, браузер проверяет, поддерживает ли он этот формат, прежде чем начать загрузку. Если браузер не поддерживает указанный формат, он переходит к следующему файлу.
    • Если подсказка о формате отсутствует, браузер загружает ресурс.

Сочетание локальных и внешних директив с соответствующими подсказками форматирования позволяет указать все доступные форматы шрифтов, а браузер позаботится обо всем остальном. Браузер определяет, какие ресурсы необходимы, и выбирает оптимальный формат.

Подмножество диапазонов Unicode

В дополнение к таким свойствам шрифта, как стиль, толщина и растяжение, правило @font-face позволяет определить набор кодовых точек Unicode, поддерживаемых каждым ресурсом. Это позволяет разделить большой шрифт Unicode на более мелкие подмножества (например, латинское, кириллическое и греческое) и загрузить только те глифы, которые необходимы для отображения текста на конкретной странице.

Дескриптор unicode-range позволяет указать список значений диапазона, разделенных запятыми, каждое из которых может быть представлено в одной из трех различных форм:

  • Отдельная кодовая точка (например, U+416 )
  • Диапазон интервалов (например, U+400-4ff ): указывает начальную и конечную кодовые точки диапазона.
  • Диапазон символов-заменителей (например, U+4?? ): символы ? обозначают любую шестнадцатеричную цифру.

Например, вы можете разделить семейство шрифтов 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');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

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

Использование подмножеств диапазонов Unicode и отдельных файлов для каждого стилистического варианта шрифта позволяет определить составное семейство шрифтов, которое загружается быстрее и эффективнее. Посетители загружают только необходимые им варианты и подмножества, и им не приходится загружать подмножества, которые они, возможно, никогда не увидят или не будут использовать на странице.

Практически все браузеры поддерживают unicode-range . Для совместимости со старыми браузерами может потребоваться использование «ручного выбора подмножеств». В этом случае необходимо предоставить единый ресурс шрифта, содержащий все необходимые подмножества, а остальные скрыть от браузера. Например, если страница использует только латинские символы, можно удалить другие глифы и предоставить это конкретное подмножество в качестве отдельного ресурса.

  1. Определите, какие подмножества необходимы:
    • Если браузер поддерживает выбор подмножества символов в диапазоне Unicode, он автоматически выберет нужное подмножество. Странице нужно лишь предоставить файлы подмножеств и указать соответствующие диапазоны Unicode в правилах @font-face .
    • Если браузер не поддерживает выделение подмножеств диапазона символов в Unicode, то страница должна скрывать все ненужные подмножества; то есть разработчик должен указать необходимые подмножества.
  2. Сгенерировать подмножества шрифтов:
    • Используйте инструмент с открытым исходным кодом pyftsubset для выбора и оптимизации шрифтов.
    • Некоторые серверы шрифтов, например Google Fonts, по умолчанию автоматически подбирают подмножество шрифтов.
    • Некоторые сервисы шрифтов позволяют вручную задавать подмножество шрифтов с помощью пользовательских параметров запроса, которые можно использовать для ручного указания необходимого подмножества для вашей страницы. Обратитесь к документации вашего поставщика шрифтов.

Выбор и синтез шрифтов

Каждое семейство шрифтов может состоять из нескольких стилистических вариантов (обычный, жирный, курсив) и нескольких вариантов толщины для каждого стиля. Каждый из которых, в свою очередь, может содержать совершенно разные формы глифов — например, различное расстояние между символами, размер или совершенно другую форму.

Толщина шрифта

Приведенная выше диаграмма иллюстрирует семейство шрифтов, которое предлагает три различных варианта начертания жирным шрифтом:

  • 400 (обычный).
  • 700 (жирным шрифтом).
  • 900 (выделено жирным шрифтом).

Все остальные промежуточные варианты (отмечены серым цветом) автоматически сопоставляются браузером с ближайшим вариантом.

Если указан вес, для которого не существует грани, используется грань с близким весом. Как правило, жирные оттенки соответствуют граням с более тяжелым весом, а светлые оттенки — граням с более легким весом.

алгоритм сопоставления шрифтов CSS

Аналогичная логика применима и к курсивным вариантам. Дизайнер шрифта контролирует, какие варианты он будет создавать, а вы контролируете, какие варианты будете использовать на странице. Поскольку каждый вариант загружается отдельно, рекомендуется ограничить количество вариантов. Например, для семейства шрифтов 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');
  /* Latin glyphs */
  unicode-range: U+000-5FF;
}

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

В приведенном выше примере объявлено семейство шрифтов Awesome Font , состоящее из двух ресурсов, охватывающих один и тот же набор латинских символов ( U+000-5FF ), но предлагающих два разных значения толщины: обычный (400) и жирный (700). Однако что произойдет, если одно из ваших правил CSS укажет другое значение толщины шрифта или установит свойство font-style в italic ?

  • Если точное совпадение по шрифту недоступно, браузер заменяет его наиболее подходящим вариантом.
  • Если стилистическое соответствие не найдено (например, в приведенном выше примере не были указаны варианты курсива), браузер синтезирует собственный вариант шрифта.
синтез шрифтов

Приведенный выше пример иллюстрирует разницу между фактическими и синтезированными результатами для шрифта Open Sans. Все синтезированные варианты созданы на основе одного шрифта с толщиной 400 пунктов. Как видите, разница в результатах заметна. Подробности о том, как создаются жирные и наклонные варианты, не указаны. Поэтому результаты различаются в зависимости от браузера и сильно зависят от используемого шрифта.

Контрольный список для оптимизации размера веб-шрифтов

  • Проведите аудит и мониторинг использования шрифтов: не используйте слишком много шрифтов на своих страницах и для каждого шрифта сведите к минимуму количество используемых вариантов. Это поможет обеспечить более единообразный и быстрый пользовательский опыт.
  • По возможности избегайте устаревших форматов: форматы EOT, TTF и WOFF больше, чем WOFF 2.0. Форматы EOT и TTF совершенно не нужны, тогда как WOFF может быть приемлемым, если вам необходимо поддерживать Internet Explorer 11. Если вы ориентируетесь только на современные браузеры, использование только WOFF 2.0 — самый простой и производительный вариант.
  • Выбирайте подмножества шрифтовых ресурсов: многие шрифты можно разделить на несколько диапазонов Юникода, чтобы предоставлять только те глифы, которые необходимы для конкретной страницы. Это уменьшает размер файла и повышает скорость загрузки ресурса. Однако при определении подмножеств следует оптимизировать их для повторного использования. Например, не следует загружать разные, но частично совпадающие наборы символов на каждой странице. Хорошей практикой является выбор подмножеств на основе алфавита: например, латинский и кириллический.
  • В списке src отдайте приоритет функции local() : указание local('Font Name') первым в списке src гарантирует, что HTTP-запросы не будут отправляться для шрифтов, которые уже установлены.
  • Используйте Lighthouse для проверки сжатия текста .

Влияние на наибольшее количество окрашенных поверхностей (LCP) и совокупное изменение планировки (CLS)

В зависимости от содержимого вашей страницы, текстовые узлы могут рассматриваться как кандидаты на отрисовку с наибольшим количеством отображаемого контента (Largest Contentful Paint, LCP) . Поэтому крайне важно убедиться, что ваши веб-шрифты максимально мелкие, следуя советам из этой статьи, чтобы пользователи могли увидеть текст на вашей странице как можно быстрее .

Если вас беспокоит, что, несмотря на ваши усилия по оптимизации, текст на странице может отображаться слишком долго из-за большого объема веб-шрифтов, свойство font-display имеет ряд настроек, которые помогут вам избежать невидимого текста во время загрузки шрифта. Однако использование значения swap может вызвать значительные изменения макета, которые повлияют на совокупный сдвиг макета (CLS) вашего сайта. По возможности рассмотрите возможность использования optional или fallback значений.

Если веб-шрифты имеют решающее значение для вашего бренда — и, как следствие, для пользовательского опыта — рассмотрите возможность предварительной загрузки шрифтов, чтобы браузер имел преимущество при их запросе. Это может сократить как период замены, если вы используете font-display: swap , так и период блокировки, если вы не используете font-display .