Рекомендации по использованию шрифтов

Оптимизируйте веб-шрифты для Core Web Vitals.

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

  • Задержка рендеринга текста. Если веб-шрифт не загружен, браузеры обычно задерживают рендеринг текста. Во многих ситуациях это приводит к задержке First Contentful Paint (FCP) . В некоторых ситуациях это приводит к задержке Largest Contentful Paint (LCP) .
  • Сдвиги макета. Практика замены шрифтов может привести к сдвигам макета и повлиять на накопительный сдвиг макета (CLS) . Эти изменения макета происходят, когда веб-шрифт и его резервный шрифт занимают разное количество места на странице.

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

Загрузка шрифта

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

Если вы не уверены, что шрифты вашей страницы запрашиваются вовремя, проверьте вкладку «Время» на панели «Сеть» в Chrome DevTools для получения дополнительной информации.

Вкладка «Время» в DevTools.

Понимать @font-face

Прежде чем углубляться в лучшие практики загрузки шрифтов, важно понять, как работает @font-face и как это влияет на загрузку шрифтов.

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

@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}

Распространенным заблуждением является то, что шрифт запрашивается при обнаружении объявления @font-face . Это неверно. Само по себе объявление @font-face не запускает загрузку шрифта. Вместо этого шрифт загружается только в том случае, если на него ссылается стиль, используемый на странице. Например:

@font-face {
  font-family: "Open Sans";
  src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}

h1 {
  font-family: "Open Sans"
}

В этом примере Open Sans будет загружен только в том случае, если страница содержит элемент <h1> .

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

Встроенные объявления шрифтов

Большинству сайтов было бы полезно встроить объявления шрифтов и другие важные стили в <head> основного документа, а не включать их во внешнюю таблицу стилей. Это позволяет браузеру быстрее обнаружить объявления шрифтов, поскольку ему не нужно ждать загрузки внешней таблицы стилей.

<head>
  <style>
    @font-face {
        font-family: "Open Sans";
        src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
    }

    body {
        font-family: "Open Sans";
    }

    ...etc.

  </style>
</head>

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

Предварительное подключение к критически важным сторонним источникам

Если ваш сайт загружает шрифты со стороннего сайта, настоятельно рекомендуется использовать подсказку ресурса preconnect для установления раннего соединения со сторонним источником. Подсказки по ресурсам должны быть помещены в <head> документа. Следующая подсказка ресурса устанавливает соединение для загрузки таблицы стилей шрифта.

<head>
  <link rel="preconnect" href="https://fonts.com">
</head>

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

<head>
  <link rel="preconnect" href="https://fonts.com">
  <link rel="preconnect" href="https://fonts.com" crossorigin>
</head>

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

<head>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
</head>

Будьте осторожны при использовании preload для загрузки шрифтов.

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

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

Кроме того, следует осторожно использовать preload в качестве стратегии загрузки шрифтов, поскольку она обходит некоторые встроенные в браузер стратегии согласования контента. Например, preload игнорирует объявления unicode-range и при разумном использовании ее следует использовать только для загрузки одного формата шрифта.

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

Доставка шрифтов

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

Используйте собственные шрифты

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

Если вы планируете использовать локальные шрифты, убедитесь, что ваш сайт использует сеть доставки контента (CDN) и HTTP/2 . Без использования этих технологий вероятность того, что локальные шрифты обеспечат более высокую производительность, гораздо ниже.

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

Используйте WOFF2

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

Учитывая поддержку браузера, эксперты теперь рекомендуют использовать только WOFF2:

На самом деле, мы считаем, что пришло время заявить: используйте только WOFF2 и забудьте обо всем остальном.

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

Брэм Стейн, из Веб-альманаха 2022 года.

Подмножество шрифтов

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

Дескриптор unicode-range в объявлении @font-face сообщает браузеру, для каких символов может использоваться шрифт.

@font-face {
    font-family: "Open Sans";
    src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
    unicode-range: U+0025-00FF;
}

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

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

Количество глифов в шрифте сильно различается:

  • Латинские шрифты обычно имеют размер от 100 до 1000 знаков на шрифт.
  • Шрифты CJK могут содержать более 10 000 символов.

Удаление неиспользуемых глифов может значительно уменьшить размер файла шрифта.

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

/* devanagari */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJbecnFHGPezSQ.woff2) format('woff2');
  unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB;
}
/* latin-ext */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJnecnFHGPezSQ.woff2) format('woff2');
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJfecnFHGPc.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

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

Вы можете вручную поднастроить шрифты, если это разрешено вашим поставщиком шрифтов, либо с помощью API ( Google Fonts поддерживает это, предоставляя text параметр ), либо вручную отредактировав файлы шрифтов, а затем разместив их самостоятельно. Инструменты для создания подмножеств шрифтов включают subfont и glyphanger .

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

Используйте меньше веб-шрифтов

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

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

Чтобы использовать системный шрифт в CSS, укажите system-ui в качестве семейства шрифтов:

font-family: system-ui

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

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

Рендеринг шрифтов

Столкнувшись с еще не загруженным веб-шрифтом, браузер сталкивается с дилеммой: следует ли ему приостановить рендеринг текста до тех пор, пока не будет получен веб-шрифт? Или он должен отображать текст в резервном шрифте до тех пор, пока не появится веб-шрифт?

Разные браузеры обрабатывают этот сценарий по-разному. По умолчанию браузеры на базе Chromium и Firefox блокируют рендеринг текста на срок до 3 секунд, если соответствующий веб-шрифт не загружен. Safari блокирует рендеринг текста на неопределенный срок.

Это поведение можно настроить с помощью атрибута font-display . Этот выбор может иметь серьезные последствия: font-display может повлиять на LCP, FCP и стабильность макета.

Выберите подходящую стратегию font-display

font-display сообщает браузеру, как ему следует выполнять рендеринг текста, если связанный веб-шрифт не загружен. Он определяется для каждого шрифта.

@font-face {
  font-family: Roboto, Sans-Serif
  src: url(/fonts/roboto.woff) format('woff'),
  font-display: swap;
}

Существует пять возможных значений для font-display :

Ценить Период блокировки Период свопа
Авто Зависит от браузера Зависит от браузера
Блокировать 2-3 секунды бесконечный
Менять 0 мс бесконечный
Отступать 100 мс 3 секунды
Необязательный 100 мс Никто
  • Период блокировки : период блокировки начинается, когда браузер запрашивает веб-шрифт. Если в период блокировки веб-шрифт недоступен, он отображается в виде невидимого резервного шрифта, и, таким образом, текст невидим для пользователя. Если шрифт недоступен в конце периода блокировки, он отображается с использованием резервного шрифта.
  • Период свопа : период свопа наступает после периода блокировки. Если веб-шрифт становится доступным в период замены, он «заменяется».

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

Для большинства сайтов это три наиболее применимые стратегии, основанные на вашем главном приоритете:

  • Производительность : используйте font-display: optional . Это наиболее «производительный» подход: отрисовка текста задерживается не более чем на 100 мс, и есть уверенность в том, что не произойдет никаких сдвигов макета, связанных с заменой шрифтов. Обратной стороной является то, что веб-шрифт не будет использоваться, если он появится поздно.

  • Быстро отображайте текст и по-прежнему используйте веб-шрифт : используйте font-display: swap , но убедитесь, что шрифт доставлен достаточно рано, чтобы он не вызвал изменения макета. Обратной стороной этого варианта является резкий сдвиг, когда шрифт приходит поздно.

  • Текст отображается веб-шрифтом : используйте font-display: block но убедитесь, что шрифт доставлен достаточно рано, чтобы минимизировать задержку текста. Первоначальное отображение текста задерживается. Несмотря на эту задержку, она все равно может вызвать сдвиг макета, поскольку текст фактически рисуется невидимым, и поэтому для резервирования места используется резервное пространство шрифта. После загрузки веб-шрифта может потребоваться разностное пространство и, следовательно, сдвиг. Это может быть менее резким сдвигом, чем font-display: swap , поскольку сам текст не будет смещаться.

Также имейте в виду, что эти два подхода можно комбинировать: например, использовать font-display: swap для фирменного оформления и других визуально отличительных элементов страницы. Использовать font-display: optional для шрифтов, используемых в основном тексте.

Иконочные шрифты

Стратегии font-display , которые хорошо работают для обычных веб-шрифтов, не работают так же хорошо для иконочных шрифтов. Резервный шрифт для иконочного шрифта обычно выглядит значительно иначе, чем иконочный шрифт, и его символы могут иметь совершенно другое значение. В результате иконочные шрифты с большей вероятностью вызовут значительные изменения в макете.

Кроме того, использование резервного шрифта может оказаться нецелесообразным. Если возможно, замените шрифты значков на SVG, что также лучше с точки зрения доступности. Новые версии популярных иконочных шрифтов обычно поддерживают SVG. Дополнительную информацию о переходе на SVG см. в разделах Font Awesome и Material Icons .

Уменьшите сдвиг между резервным шрифтом и веб-шрифтом.

Чтобы уменьшить влияние CLS, вы можете использовать атрибуты size-adjust .

Заключение

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