Оптимизируйте веб-шрифты для Core Web Vitals.
В этой статье обсуждаются рекомендации по повышению производительности шрифтов. Веб-шрифты влияют на производительность по-разному:
- Задержка рендеринга текста. Если веб-шрифт не загружен, браузеры обычно задерживают рендеринг текста. Во многих ситуациях это приводит к задержке First Contentful Paint (FCP) . В некоторых ситуациях это приводит к задержке Largest Contentful Paint (LCP) .
- Сдвиги макета. Практика замены шрифтов может привести к сдвигам макета и, таким образом, повлиять на накопительный сдвиг макета (CLS) . Эти изменения макета происходят, когда веб-шрифт и его резервный шрифт занимают разное количество места на странице.
Эта статья разбита на три раздела: загрузка шрифтов , доставка шрифтов и рендеринг шрифтов . В каждом разделе объясняется, как работает этот конкретный аспект жизненного цикла шрифта, и приводятся соответствующие рекомендации.
Загрузка шрифта
Шрифты обычно являются важным ресурсом, поскольку без них пользователь не сможет просматривать содержимое страницы. Таким образом, лучшие практики загрузки шрифтов обычно направлены на то, чтобы шрифты загружались как можно раньше. Особое внимание следует уделять шрифтам, загруженным со сторонних сайтов, поскольку для загрузки этих файлов шрифтов требуется отдельная настройка соединения.
Если вы не уверены, что шрифты вашей страницы запрашиваются вовремя, проверьте вкладку «Время» на панели «Сеть» в Chrome 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 и забудьте обо всем остальном.
Брэм Стейн, из Веб-альманаха 2022 года.
Это значительно упростит ваш CSS и рабочий процесс, а также предотвратит случайную двойную или неправильную загрузку шрифтов. WOFF2 теперь поддерживается везде. Итак, если вам не нужна поддержка действительно древних браузеров, просто используйте WOFF2. Если вы не можете, рассмотрите возможность вообще не использовать веб-шрифты в этих старых браузерах. Это не будет проблемой, если у вас есть надежная запасная стратегия. Посетители старых браузеров просто увидят ваши резервные шрифты.
Подмножество шрифтов
Файлы шрифтов обычно включают большое количество глифов для всех поддерживаемых ими символов. Но вам могут не понадобиться все символы на вашей странице, и вы можете уменьшить размер файлов шрифтов, разделив шрифты на подмножества.
Дескриптор 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
для шрифтов, используемых в основном тексте.
Уменьшите сдвиг между резервным шрифтом и веб-шрифтом.
Чтобы уменьшить влияние CLS, вы можете использовать новые атрибуты size-adjust
. Для получения дополнительной информации см. статью о size-adjust
CSS . Это совершенно новое дополнение к нашему набору инструментов, поэтому на данный момент оно более продвинутое и немного ручное. Но определенно стоит экспериментировать и следить за улучшениями инструментов в будущем!
Заключение
Веб-шрифты по-прежнему являются узким местом производительности, но у нас есть постоянно растущий набор возможностей, которые позволяют нам оптимизировать их, чтобы максимально уменьшить это узкое место.