От автора: когда я создал сайт, я не собирался совершать загрузку шрифтов. Какой-то урон производительности, даже небольшой, почти неизбежен, а я хотел, чтобы сайт был быстрым. Тем не менее, в конце я решил использовать один шрифт для заголовков страниц и просто убедиться, что любое влияние на производительность будет минимизировано.
Первым шагом было сделать файл шрифта как можно меньшего размера, поэтому я поместил его в подмножество. Другими словами, он содержит только символы, необходимые для слов в заголовке.
Результатом стал крошечный файл — менее 2 КБ. Я также размещал его локально, удаляя сторонние зависимости и соответственно необходимость подключения к другому домену. Наконец, на шрифт ссылался встроенный CSS вверху HTML, а не внешний CSS-файл.
Это означало, что браузер мог обнаружить и загрузить его, не загружая внешнюю таблицу стилей — частая причина поздней загрузки шрифтов.
Сюрприз
Поскольку для отображения текста требуются пользовательские шрифты, браузеры должны относиться к ним как к приоритетным ресурсам.
Поэтому я ожидал, что мой файл шрифтов загрузится быстро. В любом случае, эти страницы были довольно легкими, так что больше ничего не могло быть на пути. Я был немного шокирован.
Когда я проверил страницу в Chrome Devtools, а затем в Webpagetest, я обнаружил, что файл шрифта с высоким приоритетом загружается после изображений, которые должны иметь более низкий приоритет.
Это не имело никакого смысла для меня. Я же знаю, что браузеры могут ждать, пока не обнаружат, что файл шрифта необходим перед загрузкой. Но элемент, который использует мой шрифт, находится прямо вверху страницы, внутри header, задолго до изображений, загруженных перед ним. Он даже выше в дереве DOM.
Предварительная загрузка вам в помощь
Предварительная загрузка сообщает браузеру, что ему нужно загрузить ресурс на текущей странице.
Это хороший способ загрузить важные ресурсы на ранней стадии, когда в противном случае они будут обнаружены поздно.
Шрифты являются отличным примером. Если на шрифт есть ссылка во внешней таблице стилей, он не будет обнаружен, пока эта таблица стилей не будет загружена.
Предварительная загрузка шрифта дает браузеру уведомление о том, что он понадобится. Это также очень просто реализовать в элементе link.
<link rel="preload" href="myfont.woff2" as="font" type="font/woff2" crossorigin>
В качестве альтернативы вы можете добавить директиву preload в качестве заголовка ответа (хотя некоторые серверы / CDN будут интерпретировать это как запрос на передачу ресурса, если не указано иное).
Я не ожидал использовать предварительную загрузку на этом сайте. Мой CSS довольно минималистичен, и я добавил его в HTML, чтобы страницы быстрее отображались при первом посещении. Так как мой шрифт не зависит от внешнего CSS-файла, он должен быть обнаружен в любом случае без предварительной загрузки.
Однако, я обнаружил, что предварительная загрузка шрифта восстановила его на своем законном месте перед изображениями. Вот графики водопадов из Webpagetest — я выделил точку, где шрифт загружается с и без предварительной загрузки:
Возможно, более показательным является сравнение кадров загрузки (это было проверено на очень медленном соединении, чтобы проиллюстрировать разницу), причем нижняя полоса показывает преимущество использования предварительной нагрузки:
Кроме того, я фактически использовал font-display: fallback, чтобы заголовок изначально отображался резервным шрифтом, если пользовательский шрифт загружался медленно. Однако из-за того, что на этом тесте их было бы трудно различить, для теста он был отключен.
Почему это работает?
Чтобы отобразить веб-страницу, браузер должен построить дерево объектной модели документа (DOM) и дерево объектной модели CSS (CSSOM), которые затем он использует для построения дерева визуализации.
Добавление ссылки предварительной загрузки для шрифта позволяет браузеру начать сборку CSSOM раньше, до завершения DOM. Вы можете увидеть это в выдержках из Chrome Devtools ниже. Во-первых, без предварительной загрузки:
Теперь с предварительной загрузкой:
Другая альтернатива?
Если бы я не смог использовать предварительную загрузку для повышения приоритета шрифта, как насчет уменьшения приоритета изображений?
Из любопытства я также попытался применить loading = «lazy» к изображениям на странице. Начиная с Chrome 76 (на момент написания статьи поддержка в других браузерах отсутствовала) это должно уменьшить приоритет изображений за пределами исходного окна просмотра.
Быстрая проверка в Devtools показала, что это действительно позволяет загружать шрифт раньше — возможно, это следует учитывать при расширении поддержки этой функции в браузерах.
Переменное поведение браузера
Я протестировал несколько разных браузеров и устройств и обнаружил, что iOS Safari (iPhone 8) демонстрирует то же поведение, что и Chrome — шрифт с поздней загрузкой, который можно загружать раньше, добавив предварительную загрузку.
Проблема поздней загрузки шрифта также возникла в Firefox, но предварительная загрузка еще не поддерживается по умолчанию в Firefox, поэтому добавление не имеет значения.
В Edge файл шрифтов загружался слишком поздно. Добавление предварительной загрузки, казалось, работало в Webpagetest. На самом деле, оказалось, что шрифт загружался дважды (один раз рано, один раз поздно).
Я говорю, кажется, загружается, потому что, при попытке проверить это в Developer Tools в моей собственной версии Edge, дублирующая загрузка исчезла. И предварительная загрузка больше не давала загружать шрифт раньше. Так что, если была ошибка, возможно, она была исправлена.
Вывод
Браузеры не всегда ведут себя так, как нам хотелось бы или как мы ожидали, но в нашем распоряжении есть инструменты, позволяющие направить это поведение к желаемому результату.
Я раньше думал, что предварительно загружать шрифты на этом сайте было бы совершенно бессмысленно. Так что, если это был урок для меня, возможно, это что-то даст вам!
Автор: Alex Painter
Источник: https://www.alexrp.co.uk
Редакция: Команда webformyself.