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

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

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

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

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

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

При выборе шрифта важно учитывать, какие наборы символов поддерживаются. Если вам необходимо локализовать содержимое вашей страницы на несколько языков, вам следует использовать шрифт, который обеспечит единообразный внешний вид и удобство для ваших пользователей. Например, семейство шрифтов Google Noto предназначено для поддержки всех языков мира. Однако обратите внимание, что общий размер 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

CSS-правило @font-face позволяет вам определить местоположение конкретного ресурса шрифта, его характеристики стиля и кодовые точки 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. Если шрифт недоступен локально, браузер перебирает внешние определения:
    • Если подсказка формата присутствует, браузер проверяет, поддерживает ли он подсказку, прежде чем начать загрузку. Если браузер не поддерживает подсказку, он переходит к следующему.
    • Если подсказка формата отсутствует, браузер загружает ресурс.

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

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

В дополнение к свойствам шрифта, таким как стиль, вес и растяжение, правило @font-face позволяет определить набор кодовых точек Юникода, поддерживаемых каждым ресурсом. Это позволяет разделить большой шрифт 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-range . Для совместимости со старыми браузерами вам может потребоваться вернуться к «ручной настройке». В этом случае вам придется вернуться к предоставлению одного ресурса шрифта, содержащего все необходимые подмножества, и скрыть остальное от браузера. Например, если на странице используются только латинские символы, вы можете удалить другие глифы и использовать это конкретное подмножество как отдельный ресурс.

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

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

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

Вес шрифта

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

  • 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 — самый простой и наиболее эффективный вариант.
  • Подмножество ресурсов шрифтов: многие шрифты могут быть подмножествами или разделены на несколько диапазонов Юникода, чтобы доставлять только те глифы, которые требуются конкретной странице. Это уменьшает размер файла и повышает скорость загрузки ресурса. Однако при определении подмножеств будьте осторожны и оптимизируйте повторное использование шрифтов. Например, не загружайте на каждой странице разные, но пересекающиеся наборы символов. Хорошей практикой является создание подмножества на основе алфавита: например, латиницы и кириллицы.
  • Отдайте приоритет local() в вашем списке src : указание local('Font Name') первым в вашем списке src гарантирует, что HTTP-запросы не будут выполняться для уже установленных шрифтов.
  • Используйте Lighthouse для проверки сжатия текста .

Влияние на наибольшую отрисовку содержимого (LCP) и совокупный сдвиг макета (CLS)

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

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

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