От автора: в этой статье я хочу поделиться с вами лучшими стратегиями загрузки и тем, как их все реализовать.
Зак Лизерман составил полный список стратегий загрузки шрифтов, которые широко используются в области веб-разработки. Зак рекомендует две стратегии:
FOUT with Class — лучший подход для большинства ситуаций. (Работает независимо от того, пользуемся ли мы хостингом шрифтов или размещаем собственные шрифты.)
Critical FOFT — наиболее производительный подход. (Работает, только если мы размещаем собственные шрифты.)
Прежде чем мы углубимся в эти две стратегии, нам нужно прояснить аббревиатуры, чтобы вы поняли, о чем говорит Зак.
FOIT, FOUT, FOFT
FOIT означает вспышка невидимого текста. Когда загружаются веб-шрифты, мы скрываем текст, чтобы пользователи ничего не видели. Мы показываем текст только тогда, когда загружены веб-шрифты.
FOUT означает вспышка нестилизованного текста. Когда загружаются веб-шрифты, мы показываем пользователям системный шрифт. Когда веб-шрифт загружается, мы меняем обратно желаемый веб-шрифт.
FOFT означает вспышка искусственного текста. Это сложно и требует дополнительных объяснений. Мы поговорим об этом подробно, когда перейдем к разделу FOFT.
Способы размещения шрифтов
Есть два основных способа размещения шрифтов:
Использование облачного хранилища.
Самостоятельное размещение шрифтов.
То, как мы загружаем шрифты, сильно различается в зависимости от того, какой вариант вы выберете.
Загрузка шрифтов с помощью шрифтов, размещенных в облаке
Часто проще размещать шрифты в облаке. Провайдер даст нам ссылку для загрузки шрифтов. Мы можем просто вставить эту ссылку в наш HTML и получить наш веб-шрифт. Вот пример, в котором мы загружаем веб-шрифты из Adobe Fonts (ранее известного как Typekit).
<link rel="stylesheet" href="https://use.typekit.net/your-kit-id.css">
К сожалению, это не лучший подход. href блокируется браузером. Если загрузка веб-шрифта зависает, пользователи не смогут ничего делать, пока ждут.
Typekit используется для предоставления JavaScript, который загружает шрифт асинхронно. Но такой подход больше не поддерживается. (Код все еще работает, но я понятия не имею, перестанет ли он работать и когда это произойдёт.)
Загрузка шрифтов из Google Fonts немного лучше, потому что она предоставляет font-display: swap. Вот пример, в котором мы загружаем Lato из Google Fonts.
<link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet" />
Загрузка шрифтов с помощью автономных шрифтов
Вы можете самостоятельно разместить свои шрифты, только если у вас есть на это лицензия. Поскольку шрифты могут быть дорогими, большинство людей предпочитают вместо этого использовать шрифты размещённые в облаке.
Однако есть дешевый способ получить шрифты. Design Cuts время от времени проводит распродажи со шрифтами, где вы можете получить безумно качественные шрифты всего за 29 долларов за комплект. Каждый комплект может содержать до 12 шрифтов. Мне удалось получить классические шрифты, такие как Claredon, DIN, Futura, и целый ряд шрифтов, с которыми я могу экспериментировать, через их рекламные объявления о распродажах.
Если мы хотим самостоятельно размещать шрифты, нам нужно понять еще две концепции: @font-face и font-display: swap.
@font-face
@font-face позволяет нам объявлять шрифты в CSS. Если мы хотим самостоятельно размещать шрифты, нам нужно использовать @font-face для объявления шрифтов. В этом объявлении мы можем указать четыре вещи:
font-family: Это сообщает CSS (и JavaScript) имя шрифта.
src: Путь к поиску шрифта для загрузки.
font-weight: Толщина шрифта. По умолчанию 400, если не указано.
font-style: Выделять ли шрифт курсивом. Если не указано иное, по умолчанию используется обычный режим.
Для src нам нужно указать несколько форматов шрифтов. Для практического уровня поддержки браузера мы можем использовать woff2 и woff. Вот пример, в котором мы загружаем Lato через @font-face.
@font-face { font-family: Lato; src: url('path-to-lato.woff2') format('woff2'), url('path-to-lato.woff') format('woff'); } @font-face { font-family: Lato; src: url('path-to-lato-bold.woff2') format('woff2'), url('path-to-lato-bold.woff') format('woff'); font-weight: 700; } @font-face { font-family: Lato; src: url('path-to-lato-italic.woff2') format('woff2'), url('path-to-lato-italic.woff') format('woff'); font-style: italic; } @font-face { font-family: Lato; src: url('path-to-lato-bold-italic.woff2') format('woff2'), url('path-to-lato-bold-italic.woff') format('woff'); font-weight: 700; font-style: italic; }
Затем мы объявляем веб-шрифт в свойстве font-family.
html { font-family: Lato, sans-serif; }
Когда браузеры анализируют элемент с веб-шрифтом, они запускают загрузку шрифта.
font-display: swap
font-display принимает один из четырех возможных значений: auto, swap, fallback, и optional. Swap указывает браузерам отображать резервный текст до загрузки веб-шрифтов. Другими словами, swap запускает FOUT для автономных шрифтов.
В настоящее время поддержка браузерами font-display: swap довольно хороша, поэтому мы можем использовать ее в наших проектах.
FOUT против FOUT with Class
FOUT означает вспышку нестилизованного текста. Всегда старайтесь использовать FOUT вместо FOIT (вспышка невидимого текста), потому что пользователям лучше читать слова, написанные системными шрифтами, чем слова, написанные невидимыми чернилами. Мы упоминали ранее, что это font-display: swap дает вам возможность использовать FOUT изначально.
FOUT with Class дает те же результаты — FOUT, но использует JavaScript для загрузки шрифтов. Механика следующая:
Во-первых: загрузите системные шрифты.
Во-вторых: загрузите веб-шрифты через JavaScript.
В-третьих: при загрузке веб-шрифтов добавьте class к тегу html.
Четвертое: переключите системный шрифт на загруженный веб-шрифт.
Зак рекомендует загружать шрифты через JavaScript, даже если font-display: swap хорошо поддерживается браузером. Другими словами, Зак рекомендует использовать FOUT with Class вместо @font-face + font-display: swap. Он рекомендует FOUT with Class по трем причинам:
Можем группировать изменения цвета.
Мы можем адаптироваться к предпочтениям пользователей.
Мы можем полностью пропустить загрузку шрифтов, если у пользователей медленное соединение.
FOUT with Class (для облачных шрифтов)
Во-первых, загрузим наши шрифты как обычно из облачного хостинга. Вот пример, когда я загрузил Lato из Google Fonts:
<head> <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet" /> </head>
Затем загрузим шрифты через JavaScript. Мы добавим в head раздел script, поскольку размер кода небольшой, и он в любом случае будет асинхронным.
<head> <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet" /> <script src="js/load-fonts.js"></script> </head>
В load-fonts.js, мы будем использовать API для загрузки шрифта. Здесь мы можем использовать Promise.all для загрузки всех шрифтов одновременно. Когда мы это делаем, мы группируем изменение цвета. Код выглядит так:
if ('fonts' in document) { Promise.all([ document.fonts.load('1em Lato'), document.fonts.load('700 1em Lato'), document.fonts.load('italic 1em Lato'), document.fonts.load('italic 700 1em Lato') ]).then(_ => () { document.documentElement.classList.add('fonts-loaded') }) }
Когда шрифты загружены, мы изменяем для основного текста веб-шрифт. Мы можем сделать это через CSS, используя класс .fonts-loaded.
/* System font before [[webfont]]s get loaded */ body { font-family: sans-serif; } /* Use [[webfont]] when [[webfont]] gets loaded*/ .fonts-loaded body { font-family: Lato, sans-serif; }
Обратите внимание: нам нужно использовать класс .fonts-loaded.
Мы не можем писать веб-шрифт прямо в font-family блока body; это вызовет загрузку шрифтов, что означает, что вы используете @font-face + font-display: swap. Это также означает, что JavaScript избыточен.
/* DO NOT DO THIS */ body { font-family: Lato, sans-serif; }
Если пользователи посещают дополнительные страницы сайта, значит, в их браузере уже загружены шрифты. Мы можем пропустить процесс загрузки шрифтов (чтобы ускорить процесс), используя sessionStorage.
if (sessionStorage.fontsLoaded) { document.documentElement.classList.add('fonts-loaded') } else { if ('fonts' in document) { Promise.all([ document.fonts.load('1em Lato'), document.fonts.load('700 1em Lato'), document.fonts.load('italic 1em Lato'), document.fonts.load('italic 700 1em Lato') ]).then(_ => () { document.documentElement.classList.add('fonts-loaded') }) } }
Если мы хотим оптимизировать JavaScript для удобства чтения, мы можем использовать шаблон раннего возврата, чтобы уменьшить отступы.
function loadFonts () { if (sessionStorage.fontsLoaded) { document.documentElement.classList.add('fonts-loaded') return } if ('fonts' in document) { Promise.all([ document.fonts.load('1em Lato'), document.fonts.load('700 1em Lato'), document.fonts.load('italic 1em Lato'), document.fonts.load('italic 700 1em Lato') ]).then(_ => () { document.documentElement.classList.add('fonts-loaded') }) } loadFonts()
FOUT with Class (для автономных шрифтов)
Во-первых, нам нужно загрузить шрифты как обычно через @font-face. Свойство font-display: swap не является обязательным, так как мы загружают шрифты через JavaScript.
@font-face { font-family: Lato; src: url('path-to-lato.woff2') format('woff2'), url('path-to-lato.woff') format('woff'); } /* Other @font-face declarations */
Затем мы загружаем веб-шрифты через JavaScript.
if ('fonts' in document) { Promise.all([ document.fonts.load('1em Lato'), document.fonts.load('700 1em Lato'), document.fonts.load('italic 1em Lato'), document.fonts.load('italic 700 1em Lato') ]).then(_ => () { document.documentElement.classList.add('fonts-loaded') }) }
Затем мы хотим изменить для основного текста веб-шрифт через CSS:
/* System font before webfont is loaded */ body { font-family: sans-serif; } /* Use webfont when it loads */ .fonts-loaded body { font-family: Lato, sans-serif; }
Наконец, мы пропускаем загрузку шрифтов для повторных посещений.
if ('fonts' in document) { Promise.all([ document.fonts.load('1em Lato'), document.fonts.load('700 1em Lato'), document.fonts.load('italic 1em Lato'), document.fonts.load('italic 700 1em Lato') ]).then(_ => () { document.documentElement.classList.add('fonts-loaded') }) }
CSS Font Loader API против FontFaceObserver
CSS Font Loader API имеет неплохую поддержку браузеров.
Но, если вам нужна поддержка старых браузеров (например, IE 11 и ниже) или если вы находите API непонятным и громоздким, вы можете использовать Bramstein FontFaceObserver. Он очень легкий, поэтому особого вреда не будет.
Код выглядит так: (Это намного лучше по сравнению с CSS Font Loader API).
new FontFaceObserver('lato') .load() .then(_ => { document.documentElement.classList.add('fonts-loaded') })
Обязательно используйте, fontfaceobserver.standalone.js если вы собираетесь загружать шрифты в браузерах, которые не поддерживают CSS Font Loader API.
FOFT
FOFT означает вспышка искусственного текста. Идея состоит в том, что мы разделяем загрузку шрифта на три этапа:
Шаг 1. Используйте резервный шрифт, если веб-шрифты еще не загружены.
Шаг 2: Сначала загрузите шрифт “Roman font”. (также называемый «книжный» или «обычный»). Это заменит большую часть текста. Полужирный шрифт и курсив будут подделаны браузером (отсюда «искусственный текст»).
Шаг 3. Загрузите остальные шрифты.
Использование стандартного FOFT
Сначала загружаем шрифт «Roman font»:
@font-face { font-family: LatoInitial; src: url('path-to-lato.woff2') format('woff2'), url('path-to-lato.woff') format('woff'); unicode-range: U+65-90, U+97-122; } .fonts-loaded-1 body { font-family: LatoInitial; }
if('fonts' in document) { document.fonts.load("1em LatoInitial") .then(_ => { document.documentElement.classList.add('fonts-loaded-1') }) }
Затем загружаем другие шрифты. Обратите внимание: мы загружаем Lato снова, но на этот раз, мы устанавливаем, font-family для Lato вместо LatoInitial.
/* Load this first */ @font-face { font-family: LatoInitial; src: url('path-to-lato.woff2') format('woff2'), url('path-to-lato.woff') format('woff'); unicode-range: U+65-90, U+97-122; } /* Load these afterwards */ @font-face { font-family: Lato; src: url('path-to-lato.woff2') format('woff2'), url('path-to-lato.woff') format('woff'); unicode-range: U+65-90, U+97-122; } /* Other @font-face for different weights and styles*/ .fonts-loaded-1 body { font-family: LatoInitial; } .fonts-loaded-2 body { font-family: Lato; }
if ('fonts' in document) { document.fonts.load('1em LatoInitial') .then(_ => { document.documentElement.classList.add('fonts-loaded-1') Promise.all([ document.fonts.load('400 1em Lato'), document.fonts.load('700 1em Lato'), document.fonts.load('italic 1em Lato'), document.fonts.load('italic 700 1em Lato') ]).then(_ => { document.documentElement.classList.add('fonts-loaded-2') }) }) }
Опять же, мы можем оптимизировать его для повторных просмотров. Здесь мы можем добавить fonts-loaded-2к для html, так как шрифты уже загружены.
function loadFonts () { if (sessionStorage.fontsLoaded) { document.documentElement.classList.add('fonts-loaded-2') return } if ('fonts' in document) { document.fonts.load('1em Lato') .then(_ => { document.documentElement.classList.add('fonts-loaded-1') Promise.all([ document.fonts.load('400 1em Lato'), document.fonts.load('700 1em Lato'), document.fonts.load('italic 1em Lato'), document.fonts.load('italic 700 1em Lato') ]).then(_ => { document.documentElement.classList.add('fonts-loaded-2') // Optimization for Repeat Views sessionStorage.fontsLoaded = true }) }) } }
Критический FOFT
«Критическая» часть происходит от «критического CSS» — где мы загружаем только необходимый CSS перед загрузкой всех остальных. Мы делаем это, для улучшения производительности.
Когда дело доходит до типографики, критичны только буквы от A до Z (заглавные и строчные). Мы можем создать подмножество этих шрифтов с помощью unicode-range.
Когда мы создаем это подмножество, мы также можем создать отдельный файл шрифта с необходимыми символами. Вот как выглядит объявление @font-face:
@font-face { font-family: LatoSubset; src: url('path-to-optimized-lato.woff2') format('woff2'), url('path-to-optimized-lato.woff') format('woff'); unicode-range: U+65-90, U+97-122; }
Сначала мы загружаем это подмножество.
.fonts-loaded-1 body { font-family: LatoSubset; }
if('fonts' in document) { document.fonts.load('1em LatoSubset') .then(_ => { document.documentElement.classList.add('fonts-loaded-1') }) }
А другие файлы шрифтов мы загрузим позже.
.fonts-loaded-2 body { font-family: Lato; }
if ('fonts' in document) { document.fonts.load('1em LatoSubset') .then(_ => { document.documentElement.classList.add('fonts-loaded-1') Promise.all([ document.fonts.load('400 1em Lato'), document.fonts.load('700 1em Lato'), document.fonts.load('italic 1em Lato'), document.fonts.load('italic 700 1em Lato') ]).then(_ => { document.documentElement.classList.add('fonts-loaded-2') }) }) }
Опять же, мы можем оптимизировать его для повторных просмотров:
function loadFonts () { if (sessionStorage.fontsLoaded) { document.documentElement.classList.add('fonts-loaded-2') return } if ('fonts' in document) { document.fonts.load('1em LatoSubset') .then(_ => { document.documentElement.classList.add('fonts-loaded-1') Promise.all([ document.fonts.load('400 1em Lato'), document.fonts.load('700 1em Lato'), document.fonts.load('italic 1em Lato'), document.fonts.load('italic 700 1em Lato') ]).then(_ => { document.documentElement.classList.add('fonts-loaded-2') // Optimization for Repeat Views sessionStorage.fontsLoaded = true }) }) } }
Варианты критического FOFT
Зак предложил два дополнительных варианта критического FOFT:
Критический FOFT с URI данных
Критический FOFT с предварительной загрузкой
Критический FOFT с URI данных
В этом варианте мы загружаем критический шрифт («roman font» с подмножеством) с URI данных вместо обычной ссылки. Вот как это выглядит:
@font-face { font-family: LatoSubset; src: url("data:application/x-font-woff;charset=utf-8;base64,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") format("woff"); /* ... */ }
Критический FOFT с предварительной нагрузкой
В этом варианте мы добавляем тег link с preload для файла критического шрифта. Вот как это выглядит:
<link rel="preload" href="path-to-roman-subset.woff2" as="font" type="font/woff2" crossorigin>
Здесь мы должны предварительно загрузить только один шрифт. Если мы загружаем более одного, мы можем отрицательно повлиять на начальное время загрузки.
В списке стратегий Зак также упомянул, что предпочитает использовать URI данных вместо preload варианта. Он предпочитает это только потому, что раньше поддержка браузером preload была плохой. Сегодня я считаю, что поддержка браузера достаточно приличная, чтобы выбрать предварительную загрузку вместо URI данных.
Последнее замечание от Зака
Крис исследовал эту статью по записям Зака, и Зак пожалел, что в своей исходной статье он не уделил приоритетное внимание подходу без JavaScript.
Я думаю, что статья хороша, но, та статья, на которой она основана, вероятно, немного устарела в нескольких отношениях. Я бы хотел, чтобы он уделял больше внимания подходам no-JS, когда вы используете только один или два файла шрифтов (или больше, но только 1 или 2 каждого шрифта). Я думаю, что подходы JS в настоящее время являются своего рода исключением (если вы не используете много файлов шрифтов или облачное хранилище, которое не поддерживает font-display: swap).
Это немного меняет вердикт, который я приведу в следующем разделе.
Какую стратегию загрузки шрифтов использовать?
Если вы используете облачного хранилище:
Используйте, font-display: swap, если хост предоставляет это.
В противном случае используйте FOUT with class.
Если вы размещаете свои веб-шрифты, у вас есть несколько вариантов:
@font-face + font-display: swap
FOUT with class
Стандартный FOFT
Критический FOFT
Вот как выбирать между ними:
Выбирайте @font-face + font-display:swap если вы только начинаете и не хотите связываться с JavaScript. Это самый простой вариант. Также выбирайте этот вариант, если вы используете только несколько файлов шрифтов (менее двух файлов) для каждого шрифта.
Выбирайте Standard FOFT, если вы готовы использовать JavaScript, но не хотите выполнять дополнительную работу для создания подмоножества латинского шрифта.
Выбирайте вариант Critical FOFT, если вы хотите добиться максимальной производительности.
Вот и все! Надеюсь, вы нашли все это полезным!
Автор: Zell Liew
Источник: css-tricks.com
Редакция: Команда webformyself.