До вмісту
fr0staman
Усі статті

Self-hosted варіативні шрифти у вебзбірці Expo

3 хв читання

У спільній кодовій базі для iOS, Android і вебу шрифти — це той ресурс, де платформи справді розходяться. Нативу потрібен файл шрифту, вкладений у збірку й зареєстрований. Вебу потрібен якнайменший файл, відданий з власного домену, і щоб браузер дізнався про нього якомога раніше. Expo згладжує цю різницю, беручи шрифти на себе, — і на вебі віддає не те, що ви обрали б самі.

Що Expo робить на вебі

expo-font реєструє шрифти в рантаймі. На вебі це означає, що правило @font-face збирається в JavaScript і вставляється в документ уже після старту застосунку. Вказує воно на той файл, який ви передали, а для кросплатформного проєкту це майже завжди TTF — бо саме він потрібен нативній частині.

Звідси два наслідки, і обидва коштують реальних мілісекунд:

TTF у вебі — це марнування. Той самий шрифт у WOFF2 зазвичай удвічі менший або й більше, бо WOFF2 стиснутий Brotli за самою специфікацією. Ви віддаєте формат, який існує для іншого середовища.

@font-face, вставлений у рантаймі, неможливо виявити рано. Preload-сканер браузера читає HTML ще до виконання скриптів. Шрифт, оголошений у початковому CSS, починає завантажуватись одразу; оголошений скриптом після гідратації — ні. На першому візиті через повільне з'єднання це різниця між швидкою підміною тексту й помітним відрізком із фолбек-шрифтом.

Що робити натомість

Оголосити шрифт самому — у CSS, який іде разом із документом:

@font-face {
  font-family: "Inter";
  src: url("/fonts/inter-variable.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-display: swap;
}

Варіативний шрифт тут важливіший, ніж здається. Кросплатформному інтерфейсу зазвичай потрібні три-чотири накреслення; як окремі файли це три-чотири запити й три-чотири кеші. Як один варіативний WOFF2 — це один файл на весь діапазон, і часто він менший за два статичні накреслення разом.

Далі — сказати про нього браузеру в head, щоб завантаження починалося разом із HTML, а не після нього:

<link
  rel="preload"
  as="font"
  type="font/woff2"
  href="/fonts/inter-variable.woff2"
  crossorigin
/>

Атрибут crossorigin не є необов'язковим навіть для файлу з того самого домену: шрифти завантажуються в режимі CORS, і без нього preload-запит і справжній запит вважаються різними. Файл приїде двічі й не допоможе нікому.

Частина, на яку насправді йде час

Зробивши все це, ви маєте два оголошення того самого сімейства: своє в CSS і те, яке Expo вставляє в рантаймі. Браузер спокійно завантажить обидва. Робота полягає в тому, щоб натив залишив свою реєстрацію шрифту, а веб її пропустив, — тобто в розділенні платформ саме там, де шрифти завантажуються, замість одного спільного виклику, який вдає, що платформи однакові.

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

Чи було воно того варте

Для абонентського кабінету — так. Люди відкривають його переважно з телефона, на мобільному інтернеті, щоб глянути баланс. Це найгірший сценарій для шрифту, який починає вантажитись пізно й нічого не блокує, але сприймається як повільність.

Для внутрішнього інструмента, який ніхто не відкриває «з холодного старту», — радше ні. Прийом дешевий, але не безкоштовний, а вся вигода — у першому візиті.

Поділитися