От автора: в истории загрузки веб-шрифтов можно выделить множество этапов. В статье рассмотрены данные этапы.
Итак, в истории загрузки веб-шрифтов можно выделить множество этапов:
1. Этап, когда никто ничего не делал: в том числе неправильное использование блока @font-face. Я считаю, что это можно назвать анти шаблоном. С таким подходом в некоторых браузерах появляется проблема мигания невидимого текста (МНТ) и даже хуже, в браузерах без таймаута загрузки шрифта (WebKit) создается единая точка ошибки.
2. Data URI для мигающего нестилизованного текста: Асинхронная загрузка CSS стилей со шрифтами (или с помощью AJAX запросов), представленными через Data URI (и сохранение их на локальном носителе для повторного использования). Данный метод устарел и может вызывать короткие мигания невидимого текста на некоторых слабых устройствах.
3. Использование класса в области видимости для мигающего нестилизованного текста: CSS Font Loading API (или полифил типа FontFaceOnload и fontfaceobserver) используется для добавления класса, защищающего наш контент от незагрузившихся веб-шрифтов. Этот метод, по моему мнению, можно назвать минимумом среди лучших практик или вступлением в Font Loading 101.
4. Использование двух классов в области видимости для мигающего фальшивого текста: Этот метод все немного усложняет и использует два разных этапа в классах, находящихся в области видимости. На первом этапе загружается Roman шрифт, затем на втором этапе уже загружается любая вариация данного шрифта: Bold, Italic, Bold Italic. Отлично подходит для медленных соединений, так как данный метод забирает на себя большую часть всех перестроений страницы, тем самым перестройка страницы становится менее заметной и не так сильно влияет на пользователя. Я бы классифицировал данный метод как средний Font Loading 201.
Следующий этап: критические мигания фальшивого текста
Метод работает по принципу мигания фальшивого текста и задействует двухэтапный процесс загрузки (звучит, как что-то из ракетостроения, но это не так). Однако вместо загрузки полного шрифта Roman на первом этапе, загружается небольшой набор данного шрифта . В этом случае загружаются только символы в верхнем и нижнем регистрах. На этом этапе можно добавить цифры.
Я реализовал данную технику на своем веб-сайте. Я использую 4 шрифта: Lato Roman, Lato Bold, Lato Italic и Lato Bold Italic.
Оригинальный шрифт Lato Roman 25Кб в формате WOFF2.
Lato Roman только знаки A-Za-z весит всего лишь 9Кб в формате WOFF2 (36% от оригинала)
Довольно ощутимая потеря в весе на первом этапе.
Сравнение по времени загрузки
Желтой рамкой выделен момент загрузки и отрисовки шрифта roman (когда он используется для основного текста). Обратите внимание, что данные развертки были сняты с моего сайта zachleat.com в браузере Chrome с помощью специальной функции «Regular 3G».
По умолчанию
Использование класса в области видимости для мигающего нестилизованного текста
Использование двух классов в области видимости для мигающего фальшивого текста
Использование двух классов в области видимости для критического мигающего фальшивого текста
Сравнение производительности
Мы значительно оттянули момент полной загрузки страницы для снижения прыгания текста перед пользователем при перестроении. Когда метод font-size-adjust будет работать не только в браузере Firefox, нужда в данной технике отпадет если не совсем, то значительно. А пока этот момент не настал, я считаю данный способ основным для снижения отвлекающий от чтения факторов.
Включите функцию имитации 3G сети в вашем любимом браузере и наблюдайте за отрисовкой страницы (некоторым не придется этого делать, так как у них и так слабое соединение). Веб-шрифт явно загружается намного быстрее, даже если общее время загрузки страницы возросло.
Код
Код данного метода можно посмотреть на GitHub. В работе метода используется событие FontFaceOnload для полифила загрузки шрифта.
Если интересно, то я реализовал похожий метод при помощи FontFaceObserver Брэма Штейна.
Для повторных просмотров можно использовать тот же самый механизм, что и раньше. Я использую sessionStorage Брэма Штейна таким образом, что мне не приходится вообще ничего делать на серверной стороне. Реализацию можно посмотреть в коде на GitHub в файлах initial.js и fonts.js (строки 15 и 37 соответственно).
Идеи по улучшению
Некоторые сервисы по загрузке шрифтов уже предлагают механизм тонкой настройки и динамического изменения наборов шрифта. Dynamic Subsetting генерирует набор шрифта налету, используя только знаки со страницы. Dynamic Augmentation добавляет знаки в уже загруженный шрифт также налету, что-то типа стриминга шрифтов.
Данный подход можно сделать более распространенным при помощи критического CSS и сканирования страницы на символы, отображающиеся в фиксированном окне просмотра. (grunt-criticalcss использует разрешение 1200х900) Сканирование позволит более точно выделить наборы символов, используемых под конкретный размер окна, даже под самые маленькие. Такой подход требует большего внимания, учитывая то, что со статическим контентом приходилось бы предугадывать, что случится для каждой уникальной ссылки. Или же процесс можно запустить динамически при помощи JS во время загрузки страницы, что потребует подключения огромной библиотеки, снижающей производительность.
На деле, можно было бы попробовать реализовать данный подход при помощи потрясающей библиотеки Plumin.js, но для нашего случая она слишком велика (минифицированная версия ~400Кб). На данный момент я ограничусь базовым шрифтом формата WOFF2 в 9Кб, подменяющим полную версию в 25Кб. Подключаемая библиотека должна быть как минимум меньше базового файла (но я бы не мечтал, что вес веб-шрифта и вес JS библиотеки сравняется – у них разное влияние на производительность).
Также стоит упомянуть про статью для сайта A List Apart Эндрю Джонсона. Следите за данным методом – с его помощью мы бы смогли динамически генерировать любую насыщенность и стили, как создатели шрифтов. При помощи различных наборов насыщенности и стилей можжно было бы экономить байты в дизайне. Я бы хотел, чтобы данный метод стандартизировали.
Автор: Zach Leatherman
Источник: www.zachleat.com
Редакция: Команда webformyself.