@font-face дилема

2

Від автора: ще зовсім нещодавно в інтернеті було стільки дискусій щодо продуктивності веб-шрифтів. Частка нестандартних, кастомних шрифтів продовжує рости, але ніхто не замислюється з приводу їх продуктивності. Якщо б ви посиділи в інтернеті з повільним з’єднанням, то ви б зрозуміли, про що я кажу.

@font-face дилема

Стандартний спосіб використання шрифтів через @font-face може збентежити ваших користувачів. У цій статті ми детально розберемо роботу @font-face, проблеми, пов’язані з ним, різні шляхи збільшення швидкості завантаження шрифтів, а також розглянемо перспективи зменшення часу завантаження веб-шрифтів в майбутньому.

Як ми до цього дійшли

«Починаючи з 1998 року, коли вийшов IE4, і далі в березні 2008 по березень 2010 років один за іншим «велика п’ятірка» браузерів — Safari, Firefox, Opera і Chrome – додають підтримку @font-face» — http://alistapart.com/article/fonts-at-the-crossing. Бум по @font-face припав на 2010 рік, але тоді ще інтернет сильно відрізнявся від сьогоднішнього:

Для кросбраузерною роботи необхідно 4 формату шрифту @font-face: EOT, TTF, WOFF і SVG.

Підтримка цього селектора в мобільних пристроях робилася за залишковим принципом. Наприклад, на момент виходу iPhone 4 в 2010 році, мобільний браузер Safari падав при спробі завантажити більше одного стилю для веб-шрифту.

Сьогодні ж за даними сайту caniuse.com numbers підтримка @font-face у всьому світі становить 92.92% і 97.89 в Штатах. За фактом для того, щоб шрифт працював у всіх браузерах, вистачає і формату WOFF. Але на жаль, все ще залишаються проблеми, які так і не були вирішені на ранній стадії розвитку веб-шрифтів: продуктивність.

@font-face в браузерах за замовчуванням

«У випадках, коли текст завантажується раніше, ніж шрифту, браузер відображати текст запасним шрифтом або прозорим. Щоб уникнути миготіння тексту на сторінці використовуйте запасний шрифт» — http://www.w3.org/TR/2011/WD-css3-fonts-20111004/#font-face-loading

Хоча даний розділ специфікації і не був представлений до 2011 року, але тепер він дуже корисний. У 2009 році Firefox і Opera вбудували підтримку резервних шрифтів @font-face: якщо основний використовуваний шрифт не встигав завантажитися до відображення сторінки, то до тексту застосовувався запасний шрифт. Однак даний підхід збентежив безліч користувачів (дивіться Firefox bug report), і цей феномен охрестили FOUT, що по-російськи означає Мигання Нестилизованного Тексту. Багато статей було написано про те, як боротися з МНТ при використанні @font-face. Все це було ще в ті часи, коли більшість браузерів просто не відображали текст до кінця завантаження шрифтів.

До нещастя, наразі основною проблемою із @font-face, від якої раніше хотіли позбутися, є МСТ або Миготіння Прихованого/невидимого Тексту. Розглянемо детальніше на прикладі:

@font-face {
font-family: ‘Open Sans’;
font-style: normal;
font-weight: 400;
src: url(opensans.woff) format(‘woff’);
}
body {
font-family: ‘Open Sans’, ‘Arial’, sans-serif;
}

Запасний шрифт вказаний, проте багато браузери диктують такий синтаксис наступним чином: текст залишиться прозорим поки Open Sans не завантажиться або не збережеться в кеш. У багато webkit браузерах є затримка в 3 секунди, перш ніж почати відлік і показати запасний шрифт. На вкрай повільних з’єднаннях деякі браузери можуть чекати від 30 секунд до нескінченності і постійно блимати текстом.

Прискорюємо завантаження веб-шрифтів

У мобільних користувачів точно був досвід використання вкрай повільних з’єднань, типу Edge, 3G і таких, які Jake Archibald називає «Помилковий Wi-Fi»: безкоштовний інтернет в аеропортах або готелях часто по швидкості порівняємо зі старим dial-up з’єднання. Щоб виправити цю недугу, нам необхідно завантажувати @font-face таким чином, щоб він не заважав візуалізації шрифту.

У той час поки одні побоюються МНТ, найвдалішим варіантом з точки зору продуктивності буде варіант відкласти завантаження своїх шрифтів за допомогою font-family до тих пір, поки вони не стануть доступні. Такий підхід також має сенс на тих сайтах, де основний упор зроблений на читання тексту.

Завантажувачі шрифтів

Вам знадобиться JavaScript, малі зміни можуть серйозно збільшити продуктивність. Нижче я навів короткий список найкращих варіантів завантаження веб-шрифтів на сьогодні:

Покращення якості її роботи/Google Web Font Loader, минифицированный до 11Кб

Можливо, вам вже доводилося мати справу з цим завантажувачем, шрифти зберігаються або в Google, або на покращення якості її роботи. Під час завантаження сторінки Web Font Loader порівнює ширину двох блоків, щоб визначити, чи готова сторінка для використання вашого шрифту (дивіться код). При асинхронному використанні Web Font Loader, як у прикладі нижче, сторінка не блокується.

WebFontConfig = {
покращення якості її роботи: { id: ‘xxxxxx’ }
};
(function(d) {
var wf = d.createElement(‘script’), s = d.scripts[0];
wf.src = ‘https://ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js’;
s.parentNode.insertBefore(wf, s);
})(document);

Web Font Loader робить майже всю роботу з JavaScript за вас, робить всілякі перевірки і встановлює класи для кожного типу шрифтів. Зверніть увагу: мінлива fvd – опис типу шрифту.

WebFontConfig = {
loading: function() {},
active: function() {},
inactive: function() {},
fontloading: function(familyName, fvd) {},
fontactive: function(familyName, fvd) {},
fontinactive: function(familyName, fvd) {}
};
.wf-loading
.wf-active
.wf-inactive
.wf—loading
.wf—active
.wf—inactive

Font Face Observer, у минифицированном вигляді 4Кб

Font Face Observer відмінний легкий інструмент від Bram Stein. Bram працював на покращення якості її роботи і були одним з розробників Web Font Loader, я просто процитую його:

«Font Face Observer це маленький @font-face завантажувач, який можна порівняти з будь-яким веб-сервісом завантаження шрифтів. Він відстежує, коли шрифт застосовується до сторінки, і повідомляє вас про це. Не існує взагалі ніяких обмежень щодо того де, коли або як ви будете завантажувати веб-шрифти. На відміну від Web Font Loader Font Face Observer використовує події прокрутки сторінки для визначення повної завантаження шрифту, а також мінімізує навантаження на браузер.»

Хочете детальніше вивчити принцип роботи, пройдіть по посиланню http://bramstein.com/writing/detecting-system-fonts-without-flash.html.

var observer = new FontFaceObserver(‘My Family’, {
weight: 400
});
observer.check().then(function () {
console.log(‘Font is available’);
}, function () {
console.log(‘Font is not available’);
});

Якщо для вас не проблема написати пару рядків коду JavaScript самому, то в такому випадку Font Face Observer виконує всі ті ж функції, що і Web Font Loader. Наприклад, нижче представлений скрипт, що виконує один виклик функції для декількох сімейств шрифтів.

var fontFamilies = {
‘Open Sans’: [
{
weight: 400
},
{
weight: 700
}
],
‘Open Sans Condensed’: [
{
weight: 700
}
]
}
var fontObservers = [];
Object.keys(fontFamilies).forEach(function(family) {
fontObservers.push(fontFamilies[family].map(function(config) {
return new FontFaceObserver(family, config).check()
}));
});
Promise.all(fontObservers)
.then(function() {
document.body.classList.add(‘fonts-loaded’);
}, function() {
console.log(‘Fonts not available’);
});

Подивитися демо на CodePen.

LocalFont

LocalFont це безкоштовний сервіс, що полегшує завантаження веб-шрифтів і повторного їх використання з локальних носіїв. Сайт кодує ваш шрифт методом base64 і генерує необхідний для відображення CSS і JS код. Спосіб дуже швидко працює, але я не зміг знайти інформації з приводу порівняння швидкості завантаження через сервіс або через кеш (https://github.com/jaicab/localFont/issues/1). Також, при кожному оновленні файлів, вам потрібно придумати спосіб скидання кешу. Якщо у вас достатньо часу на перевірку ваших веб-шрифтів, я б не став використовувати локальні носії для зберігання кешу.

Боремося з МНТ

Щоб вибрати резервний шрифт скористайтеся, наприклад, таки сервісом http://fontfamily.io/.

Знизьте по максимуму рефлоу (повторні побудови DOM сторінки) в шрифтах, використовуйте стандартні висоти рядків і т. д. все, щоб ваш шрифт був схожий на стандартний. Такий підхід мінімізує Миготіння Нестилизованного Тексту в момент перемикання на ваш шрифт, особливо на сторінках з великими обсягами тексту. Також ознайомтеся http://www.stateofwebtype.com/#font-size-adjust

Встановіть часовий ліміт на застосування кастомного веб-шрифту. У уникнення дратівної перемикання шрифту, просто не застосовуйте ваш шрифт, якщо він вантажиться дуже довго.

Коли ваш шрифт завантажився в кеш, на наступних сторінках вашого сайту можна уникнути перевірки готовності шрифту за допомогою методик cookie або схожих. Однак у більшості сучасних пристроїв і браузерах швидкість витягання файлів шрифту з локальних носіїв або з кешу настільки швидка, що, в принципі, про це можна взагалі не турбуватися.

Завантаження шрифтів у найближчому майбутньому

Немає потреби пояснювати, що ще стільки всього можна поліпшити. До щастя, що у нас є такі інструменти, як Font Loading API і CSS Font Rendering draft, які забезпечать нам світле майбутнє.

Font Loading API

Нове Font Loading API звертається до @font-face нативним способом, що дозволяє позбавитися від JS завантажувачів. Дане API вже доступно для Chrome і Opera! На Github у Bram Stein також є Font Loading полифилл.

var f = new FontFace(«newfont», «url(newfont.woff)», {});
f.load().then(function (loadedFace) {
document.fonts.add(loadedFace);
document.body.style.fontFamily = «newfont, serif»;
});
document.fonts.ready().then(function() {
// всі сімейства @font-face готові до застосування
});

CSS Font Rendering Draft

CSS Font Rendering дозволить розробникам контролювати момент відтворення браузерами шрифту за допомогою одного лише CSS. На даний момент, даний інструмент є частиною специфікації Fonts Level 4. Поки що ще занадто рано говорити, коли він буде доступний.

@font-face {
font-display: auto | block | swap | fallback | optional;
}

Висновок

Стандартне використання @font-face може сильно вдарити по продуктивності сайту, але все ж існує безліч інших способів завантаження веб-шрифтів без блокування виводу тексту. І вирішити цю проблему все легше і легше.

Зрештою, сподіваюся, що після цієї статті ви задумалися з приводу продуктивності завантаження веб-шрифти на своєму сайті. Протестуйте швидкість завантаження сторінок на webpagetest.org і вирішите, що ви можете зробити з @font-face, щоб збільшити швидкість завантаження.