
⚡ Як завантажити веб-шрифти без втрати швидкості та прискорити відтворення тексту
Коли сайт вантажиться 3 секунди, а потім ще секунду перемальовує весь текст, відвідувач іде. Не до конкурентів, а просто закриває вкладку. Проблема майже завжди в одному: вебшрифти завантажено без урахування продуктивності.
За даними HTTP Archive за 2025, близько 84% сайтів використовують кастомні вебшрифти, і медіанний сайт робить 5 запитів до шрифтових файлів загальним обсягом під 400 КБ. За поганого з’єднання це 2-3 секунди блокування рендерингу, коли користувач бачить порожній екран. А Google враховує Cumulative Layout Shift від підміни шрифту в Core Web Vitals.
Чотири кроки нижче — це не теорія. Це практичний мінімум, який закриває переважну більшість проблем із продуктивністю вебшрифтів. Кожен крок займає від 5 до 15 хвилин.
💡 Швидкий огляд:
- Визначтеся з форматами: woff2 як основний і woff як fallback, цього достатньо для всіх сучасних браузерів.
- Додайте preload для критичних шрифтів, щоб браузер не чекав на CSS, а починав завантаження одразу.
- Перевірте font-face: local(), правильний порядок src, unicode-range для латиниці.
- Налаштуйте font-display: swap, і відвідувач бачить текст миттєво, навіть поки шрифт ще вантажиться.
Крок 1: Використовуйте woff2 і woff, решта не потрібна
Форматів вебшрифтів багато: EOT, TTF, OTF, SVG. Але у 2026 році реально потрібні лише два.
woff2, сучасний стандарт. Файли на 30% менші за woff за тієї самої якості, бо використовують brotli-стиснення замість gzip. Підтримка браузерами, усі evergreen-браузери, включно з мобільними Safari та Samsung Internet. Глобально, 98%+ користувачів.
woff, fallback для невеликої частки старих браузерів (Safari на iOS 11 і нижче, рідкісні корпоративні середовища). Теж стискається, працює всюди з IE9+. Тримайте його останнім у src, і браузер візьме woff2, якщо може, інакше відкотиться на woff.
EOT (Internet Explorer 8 і нижче) та TTF (сирий формат, без стиснення) у 2026 році не використовуйте. Частка таких браузерів, статистична похибка, а кожен зайвий формат у src збільшує CSS і плутає браузер.
Якщо у вас файли в TTF або OTF, конвертуйте через онлайн-генератор. Transfonter робить woff2 і woff однією операцією, показуючи preview гліфів і підсумковий обсяг. Альтернатива, Font Squirrel Webfont Generator.
Крок 2: Попередньо завантажте критичні шрифти через preload
Браузер дізнається про шрифт із CSS, а CSS він читає після HTML. Поки добереться, минає 500-800 мс на середньому з’єднанні. Preload скорочує цю затримку до нуля: браузер починає вантажити шрифт щойно зустрічає тег у <head>, не чекаючи на CSS.
Мінімальний робочий тег:
1 <link rel="preload" as="font" 2 href="/fonts/open-sans.woff2" 3 type="font/woff2" 4 crossorigin="anonymous">
Ключове, crossorigin="anonymous". Без нього браузер проігнорує попередньо завантажений шрифт і завантажить його повторно. Причина в тому, що шрифти фетчаться анонімно (CORS), а preload без crossorigin робить звичайний запит, браузер вважає це різними ресурсами і не зіставляє.
Що попередньо завантажувати. Не кожен шрифт на сайті. Тільки той, який використовується для основного тексту видимої частини сторінки (above the fold): заголовок, body, навігація. Решта зачекають. Попереднє завантаження 4-5 файлів дає спадну віддачу і забирає смугу в критичного контенту.
Важливий нюанс із Google Fonts та CDN. Якщо берете шрифти з Google Fonts, файли періодично оновлюються, і preload-посилання на старій версії призведе до подвійного завантаження (стара + нова). Замість preload для CDN-шрифтів використовуйте <link rel="preconnect"> до домену шрифтів — це пришвидшить handshake без ризику версійного розходження:
1 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
Prefetch для другорядних шрифтів. rel="prefetch" повідомляє браузеру: «цей ресурс знадобиться пізніше, завантаж, коли основне готове». Підходить для шрифтів на внутрішніх сторінках або для іконкових шрифтів у футері. Пріоритет низький, смугу не забирає.
Сучасний гід із пріоритизації ресурсів є в документації web.dev.
Крок 3: Оформіть @font-face без помилок
На вигляд @font-face простий. На практиці в ньому чотири тонкі місця, кожне впливає на швидкість.
Приклад правильного оголошення:
1 @font-face { 2 font-family: 'Open Sans'; 3 font-weight: 400; 4 font-style: normal; 5 font-display: swap; 6 unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, 7 U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, 8 U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, 9 U+FEFF, U+FFFD; 10 src: local('Open Sans'), 11 url('/fonts/open-sans.woff2') format('woff2'), 12 url('/fonts/open-sans.woff') format('woff'); 13 }
Розбір за пунктами:
local(): першим у src. Якщо у користувача шрифт уже встановлений у системі (Roboto на Android, Segoe UI на Windows, San Francisco на macOS), браузер візьме локальну копію і не вантажитиме жодного байта. Завжди ставте local() першим рядком у src. Ім’я беріть із самого шрифтового файлу: local('Open Sans') та local('Roboto Regular').
Порядок форматів. Браузер іде по src зліва направо і бере перший формат, який розуміє. Тому: local() → woff2 → woff. Жодних EOT/TTF/SVG у кінці, тільки якщо у вас специфічна аудиторія зі старими браузерами, і тоді вони йдуть ПІСЛЯ woff (не до).
unicode-range, вантажимо тільки потрібні гліфи. Для латиниці достатньо діапазону U+0000-00FF (Basic Latin + Latin-1 Supplement). Це ~250 гліфів проти кількох тисяч у повному наборі. Реальний обсяг файлу падає в 3-5 разів. Не перевантажуйте діапазон, кожен зайвий unicode-block додає гліфи, які ніхто не побачить. Для кириличних сайтів додайте U+0400-04FF.
Порядок @font-face-блоків. Якщо у вас кілька накреслень (regular, bold, italic), звичайне накреслення (font-weight: 400) ставте першим, браузер почне вантажити саме його.
Крок 4: Увімкніть font-display: swap і попрощайтеся з FOIT
Flash of Invisible Text (FOIT) — це коли браузер ховає текст на 3 секунди, чекаючи на шрифт. Користувач бачить порожню сторінку. Flash of Unstyled Text (FOUT), текст одразу видно системним шрифтом, потім він замінюється кастомним. Друге завжди краще за перше.
font-display: swap у @font-face робить саме це: текст рендериться миттєво системним шрифтом, а коли кастомний завантажився, підміняється. Ідеально для основного тексту.
Інші значення і коли їх застосовувати:
swap, для body-тексту. Текст видно одразу, заміна плавна.optional, для декоративних шрифтів та іконок. Браузер вирішує, чи варто вантажити шрифт узагалі: за поганого з’єднання відмовиться і залишить системний. Період очікування, 100 мс.block, коротке блокування (зазвичай 3 секунди), потім текст видно, шрифт заміниться, коли завантажиться. Майже не використовується.fallback, компроміс: коротке блокування, потім текст видно, шрифт заміниться, якщо встигне завантажитися швидко.
На практиці для body-тексту ставте swap, для іконкових шрифтів і декору, optional. Цього достатньо.
Поведінка браузерів без font-display. Якщо не вказати нічого, Chrome ховає текст до 3 секунд, Firefox, до 3 секунд, Safari, нескінченно, Edge, одразу показує системний. З font-display: swap ця поведінка уніфікується, і результат передбачуваний.
Як перевірити результат
Перевірте свій сайт до і після на web.dev/measure, Lighthouse покаже «Ensure text remains visible during webfont load» окремим рядком. Якщо аудит червоний, ваш font-display не працює або відсутній.
Для ручної перевірки: відкрийте DevTools → Network, поставте тротлінг «Slow 3G» і оновіть сторінку. Текст має з’явитися системним шрифтом миттєво, а не через 3 секунди порожнього екрана.
На скриншотах нижче, різниця між стандартним підходом і оптимізованим (тест на Slow 3G):

Типово: текст приховано, поки шрифт не завантажився

Оптимізована поведінка: текст видно одразу системним шрифтом
Видно неозброєним оком: на першому скриншоті, білий екран, на другому, контент доступний миттєво.
На конференції performance.now() 2024 Менді Майкл розбирає просунуті стратегії, інкрементальний unicode-range, font slicing і роботу з варіативними шрифтами. Для тих, хто хоче піти далі чотирьох базових кроків.
⁉️🤔 Часті запитання
Навіщо потрібен woff, якщо woff2 підтримується всюди?
Користувачі старих iOS Safari (iOS 11 і нижче) та рідкісних корпоративних середовищ із locked-down браузерами, які залишилися, не підтримують woff2. Без woff-фолбеку ці користувачі побачать системний шрифт замість вашого. Woff додає 15-20 КБ до набору, незначна ціна за покриття залишкової частки.
Чи можна використовувати Google Fonts і не перейматися?
Можна, і для більшості сайтів це оптимальний шлях. Google Fonts автоматично віддає woff2 сучасним браузерам, використовує CDN із георозподілом і підтримує
display=swapпараметром в URL. Мінуси: залежність від зовнішнього CDN (privacy-міркування, GDPR), неможливість керуватиunicode-rangeі локальною установкою шрифтів. Якщо privacy і контроль важливі, self-host шрифтів.
Як дізнатися, що шрифти реально гальмують сайт?
Lighthouse (вкладка Audits у Chrome DevTools) покаже аудит «Ensure text remains visible during webfont load». WebPageTest дасть waterfall із таймінгом кожного шрифтового запиту. Якщо шрифти стартують пізніше за перший CSS, preload не налаштовано. Якщо зсув макета більший за 0.1, шрифт викликає Cumulative Layout Shift, і Google це зараховує в Core Web Vitals.
font-display: swap псує дизайн, текст «стрибає» під час підміни?
Так, це відомий мінус swap. Боріться двома прийомами. Перший: задайте для тексту
font-sizeіline-heightтакі самі, як у системного fallback-шрифту, різниця в метриках буде мінімальною. Другий: використовуйте Font Style Matcher або модульsize-adjustу@font-face(доступний у сучасних браузерах), щоб підігнати метрики кастомного шрифту під системний. Після підгонки CLS буде нульовим.
Чи потрібно попередньо завантажувати всі шрифти на сайті?
Ні. Попередньо завантажуйте тільки critical шрифти, ті, що формують текст видимої частини сторінки (перші 1-2 екрани). Решту вантажте штатно через CSS. Попереднє завантаження 5+ шрифтів забиває смугу і затримує важливіші ресурси в черзі. На практиці 1-2 preload-посилання покривають переважну більшість сценаріїв.
Чи варто заморочуватися: чотири кроки, чотири хвилини
Налаштування вебшрифтів, не проєкт на тиждень. Конвертація в woff2, правка @font-face, preload і font-display: swap — це 20-30 хвилин роботи, навіть якщо ви ніколи цього не робили.
Вигода вимірна: текст стає видимим на 1.5-2.5 секунди раніше на Slow 3G. Core Web Vitals не штрафують за зсув макета. І користувач не йде, дивлячись на білий екран.
Почніть з одного шрифту, основного текстового. Зробіть чотири кроки. Перевірте Lighthouse до і після. Різниця в цифрах переконає краще за будь-які аргументи.



