CSS-live.ru

Минимально необходимые шрифты

Перевод статьи CRITICAL WEB FONTS с сайта zachleat.com, опубликовано на css-live.ru с разрешения автора — Зака Лезермана.

История загрузки веб-шрифтов проходила через много этапов:

  1. Не делать ничего: подключение CSS-блока @font-face и использование его у себя в коде без уточнений. Но по мне, так это антипаттерн. Это приводит к мельканию невидимого текста (англ. flash of invisible text — FOIT) в некоторых браузерах, или того хуже, если что-то пойдет не так, в браузерах без таймаута на загрузку шрифта (WebKit) текст вообще так и не появится.
  2. Встраивание шрифтов с помощью Data URI для мелькания неоформленного текста (англ. flash of unstyled text — FOUT): загрузка таблицы стилей CSS асинхронно (или с помощью AJAX-запроса) с веб-шрифтами, встроенными как Data URI (и сохранение их в localStorage для повторных показов).  Этот подход устарел, поскольку может вызвать краткое мелькание невидимого текста (FOIT) на некоторых маломощных устройствах.
  3. Динамический класс для мелькания неоформленного текста: использовать API загрузки CSS-шрифтов (или полифилл для той же цели, вроде FontFaceOnload или fontfaceobserver), чтобы добавить класс-ограничитель, защищающий наш контент от веб-шрифтов до того, как они загрузятся (это также подробно описано на «Filament Group Lab«). Это необходимый минимум того, что я могу признать передовым методом, или «Введение в основы загрузки шрифтов».
  4. Два динамических класса для мелькания ложного жирного и ложного курсива (англ. flash of faux text — FOFT): Этот метод немного усложняет процесс и использует два разных этапа динамических классов. На первом этапе загружается только обычный шрифт, затем все другие варианты — жирный, курсив и жирный курсив — загружаются на втором этапе. Это замечательно для медленных соединений тем, что основная масса перерасчетов страницы происходит на поздних этапах ее загрузки, где они не так заметны и меньше мешают пользователям. Я бы классифицировал этот подход, как «Средняя школа загрузки шрифтов».

Следующий этап: минимально необходимые шрифты

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

Я реализовал эту технику у себя на сайте. Здесь я использую четыре веб-шрифта: Lato Roman, Lato Bold, Lato Italic, and Lato Bold Italic.

  • Исходный Lato Roman весит 25KB в формате WOFF2.
  • Lato Roman только с символами A-Za-z весит всего 9KB в формате WOFF2 (36% от исходного)

Это существенно сокращает первый этап.

Покадровое сравнение

Желтая рамка показывает, когда обычный шрифт (используемый для основной массы текста) загружен и отображен. Заметьте, что все эти кадры «отсняты» на сайте zachleat.com с помощью инструмента «Имитация медленного соединения (обычный 3G)» в Chrome

По умолчанию

default-3

Динамический класс для FOUT

fout-1

Два динамических класса для FOFT

foft-1

Два динамических класса для минимально необходимых шрифтов

critical-foft-2

Сравнение производительности

benchmarks

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

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

Код

Код с реализацией этого подхода можно увидеть на GitHub. Здесь используется FontFaceOnload в качестве полифилла для API загрузки шрифтов.

Если интересно, я также реализовал тот же подход с помощью промисов и FontFaceObserver Брэма Стейна

Для повторных просмотров можно использовать тот же механизм, что и ранее. Я использую трюк Брэма Стейна с sessionStorage, так что мне не приходится делать что-либо на стороне сервера. Вы можете увидеть реализацию в коде на GitHub в initial.js и fonts.js (также строки 15 и 37).

Предложения по улучшению

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

Можно расширить этот подход, используя нечто похожее на рабочий процесс для «Минимально необходимого CSS» и просканировать страницу, выяснив, какие символы используются в фиксированной области просмотра (grunt-criticalcss использует 1200x900), чтобы точнее выделить подмножество веб-шрифта, еще сильнее уменьшив его файл. Это отнимет больше сил, поскольку процесс пришлось бы прогнать заранее для каждого уникального URL для статического контента. Ещё его можно запустить динамически с помощью JavaScript при загрузке страницы, для чего, вероятно, пришлось бы грузить целую библиотеку и жертвовать быстродействием.

В принципе, есть ещё вариант в виде потрясающей библиотеки Plumin.js, но, к сожалению, она слишком большая (~400KB в сжатом виде) для этой задачи. Так что пока я придерживаюсь начального 9-килобайтного исходного WOFF2, который потом заменяется на 25-килобайтную полную версию. Эта библиотека не должна быть больше начального файла шрифта, чтобы от динамического шрифта был толк (но я бы не сравнивал напрямую килобайты веб-шрифта с килобайтами JavaScript — они по-разному влияют на производительность).

Также стоит упоминуть статью Эндрю Джонсона «Живая интерполяция шрифтов в вебе» на A List Apart. Следите за этим подходом — он позволит динамически генерировать жирность и стили из основных шрифтов в надежде сэкономить загружаемые байты для дизайнов, использующих широкий выбор жирностей и стилей. Мне бы очень хотелось, чтобы это стало стандартом в вебе.

P.S. Это тоже может быть интересно:

1 комментарий

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

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

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