103 Early Hints у 2026: як прискорити LCP і TTFB на 100–400 мс

Практичний гід із 103 Early Hints у 2026: як CDN, Next.js і Node.js надсилають preload під час TTFB та реально прискорюють LCP на 100–400 мс.

Оновлено: 17 серпня 2026

103 Early Hints — це проміжна HTTP-відповідь зі статусом 103, яку сервер надсилає ще до того, як згенерує фінальну 200 OK, щоб браузер міг почати завантажувати критичні ресурси (CSS, шрифти, LCP-зображення) під час «мертвого часу», поки бекенд рахує сторінку. У 2026 році ця техніка стала стандартом де-факто для скорочення TTFB-«вікна очікування» на 100–400 мс і суттєвого покращення LCP на 15–30%. Я перевіряв це на понад тридцяти клієнтських проектах за останній рік.

  • 103 Early Hints (RFC 8297) дозволяє серверу надіслати заголовки Link: rel=preload до фінальної відповіді, використовуючи час TTFB продуктивно.
  • Підтримка стабілізувалась: Chrome 103+, Edge, Opera; Firefox увімкнено за замовчуванням з версії 120, Safari — з 17.4.
  • Cloudflare, Fastly та Vercel мають нативну підтримку Early Hints, вмикається одним перемикачем або HTTP-заголовком.
  • Node.js 18.11+ підтримує response.writeEarlyHints(); Next.js вмикає їх автоматично для App Router з v14.1.
  • Реальні кейси показують покращення LCP на 100–400 мс, особливо на «холодних» рендерах ISR та SSR-сторінках із важким першим байтом.
  • Основний антипатерн: надсилати Early Hints для ресурсів, які вже є в HTTP/2 push або в service worker кеші. Це подвійне навантаження без виграшу.

Що таке 103 Early Hints і як воно працює

103 Early Hints, це інформаційний HTTP-статус, описаний у RFC 8297. Ідея проста. Між моментом, коли браузер зробив запит, і моментом, коли сервер віддає фінальну відповідь (як правило, 200 OK з HTML-тілом), можна встигнути надіслати одну або кілька проміжних відповідей зі статусом 103. У кожній такій відповіді сервер вказує заголовок Link: з rel=preload або rel=preconnect, і браузер починає стягувати ці ресурси, поки бекенд ще генерує HTML.

Чесно кажучи, для мене як для інженера, що постійно бореться за кожні 50 мс TTFB, це чи не найкращий подарунок останніх років. Замість того щоб оптимізувати сам рендер (який часто впирається у SQL або третій сервіс), ми просто перестаємо марнувати мертвий час. У класичному водоспаді браузер сидить і чекає перший байт; з Early Hints він уже качає шрифт і hero-зображення паралельно з роботою бекенда.

Типова відповідь виглядає так:

HTTP/2 103 Early Hints
Link: </fonts/inter-var.woff2>; rel=preload; as=font; type=font/woff2; crossorigin
Link: </hero.avif>; rel=preload; as=image; fetchpriority=high
Link: <https://cdn.example.com>; rel=preconnect

HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
...

Браузер побачить 103, розпарсить Link-заголовки і почне preload/preconnect. Коли прийде 200 OK, критичні ресурси вже частково або повністю в кеші браузера. Це дає той самий ефект, що <link rel="preload"> у <head>, але спрацьовує на 100–400 мс раніше.

Підтримка браузерів та CDN у 2026 році

Ситуація з браузерною підтримкою у 2026 суттєво покращилась порівняно з 2023-м:

ПлатформаПідтримка Early HintsДата стабільної підтримки
Chrome / ChromiumТак, увімкнено за замовчуваннямChrome 103 (червень 2022)
Microsoft EdgeТак, з коробкиEdge 103 (2022)
FirefoxТак, увімкнено за замовчуваннямFirefox 120 (листопад 2023)
Safari (macOS/iOS)ТакSafari 17.4 (березень 2024)
CloudflareНативна опція, безкоштовноЗагальний реліз 2022, розширення 2025
FastlyЧерез VCL / Compute@EdgeСтабільно з 2023
VercelАвтоматично для Edge Functions2024, розширено у 2026
AWS CloudFrontЧерез Lambda@EdgeТехнічно можливо, але без нативного UI

Це означає, що у 2026 році Early Hints підтримує ≈95% глобального трафіку. Але тут є нюанс, який я щоразу пояснюю клієнтам: Early Hints передаються тільки по HTTP/2 або HTTP/3. По HTTP/1.1 їх фактично неможливо надіслати надійно, бо старі проксі та балансувальники плутаються з проміжними відповідями. Якщо ваш сайт ще ходить через legacy nginx-фронт без HTTP/2, спершу закривайте цю проблему. Про це я детально писав у матеріалі про оптимізацію TTFB у 2026 році: Early Hints там ідуть після переходу на H2/H3.

Як увімкнути Early Hints на Cloudflare, Fastly та Vercel

Найшвидший шлях, це увімкнути на рівні CDN. Cloudflare робить це в одне натискання і буквально сканує ваш HTML на предмет <link rel="preload"> та <link rel="preconnect">, потім кешує їх і надсилає як Early Hints під час наступних запитів.

Cloudflare: увімкнення через Dashboard

  1. Відкрийте Dashboard → Speed → Optimization → Content Optimization.
  2. Знайдіть перемикач Early Hints та увімкніть його для потрібного домену.
  3. Переконайтесь, що у вашому HTML у <head> є <link rel="preload"> для критичних ресурсів. Cloudflare бере саме їх.
  4. Прогрійте кеш: перший запит просто збереже підказки, другий уже надішле 103.

Через Wrangler і Workers ви можете керувати Early Hints програмно:

// Cloudflare Worker: надсилаємо Early Hints самостійно
export default {
  async fetch(request, env, ctx) {
    // Дізнаємось, який шлях запитує користувач
    const url = new URL(request.url);

    // Формуємо заголовки-підказки залежно від маршруту
    const hints = new Headers();
    if (url.pathname === '/') {
      hints.append('Link', '</fonts/inter-var.woff2>; rel=preload; as=font; crossorigin');
      hints.append('Link', '</hero.avif>; rel=preload; as=image; fetchpriority=high');
    }

    // early hints response
    const earlyHintsResponse = new Response(null, {
      status: 103,
      headers: hints,
    });

    // Надсилаємо 103, потім реальну відповідь з origin
    const originResponse = fetch(request);
    return new Response(earlyHintsResponse.body, earlyHintsResponse)
      .then(() => originResponse);
  },
};

Fastly: через VCL

На Fastly Early Hints вмикаються у vcl_recv або vcl_deliver. Найпростіший варіант, це використати h2.early_hints:

sub vcl_recv {
  # Тільки для навігаційних запитів з HTTP/2
  if (fastly_info.h2 && req.http.Sec-Fetch-Mode == "navigate") {
    h2.early_hints("Link: </app.css>; rel=preload; as=style");
    h2.early_hints("Link: </logo.svg>; rel=preload; as=image");
  }
}

Vercel: автоматично для Edge

Vercel почав автоматично надсилати Early Hints для роутів під Edge Runtime та ISR-сторінок з 2024 року. У 2026-му це працює для app/-роутів Next.js без будь-яких налаштувань. Vercel сканує ваш RSC-стрім і додає Link-заголовки для тих ресурсів, які фреймворк уже позначив як high-priority через fetchPriority="high" та preload у head.

Node.js, Next.js і response.writeEarlyHints()

Якщо ви ходите повз CDN або хочете контролю на рівні застосунку, Node.js має нативну підтримку через response.writeEarlyHints() починаючи з версії 18.11 (LTS з 20.0). Ось як це виглядає у чистому Express:

import express from 'express';

const app = express();

app.get('/', async (req, res) => {
  // 1. Одразу надсилаємо підказки браузеру
  res.writeEarlyHints({
    link: [
      '</fonts/inter-var.woff2>; rel=preload; as=font; type=font/woff2; crossorigin',
      '</css/critical.css>; rel=preload; as=style',
      '<https://cdn.example.com>; rel=preconnect',
    ],
  });

  // 2. Тепер повільна логіка: БД, зовнішні API тощо
  const data = await fetchExpensiveData(); // припустимо, 250 мс
  const html = await renderTemplate(data);  // ще 50 мс

  // 3. Фінальна відповідь. Браузер уже качав ресурси всі ці 300 мс.
  res.status(200).type('html').send(html);
});

app.listen(3000);

Для Next.js App Router підтримка увімкнена автоматично з v14.1. Фреймворк сам збирає preload-hints з ваших <link>-тегів у head.tsx та надсилає їх ще до старту RSC-рендеру. У Pages Router потрібно робити це вручну через custom server або middleware, що зайвий раз підштовхує до міграції на App Router, якщо ще не переїхали.

Наскільки Early Hints покращують LCP і TTFB

Тут потрібно бути точним у термінології: Early Hints не зменшують TTFB у метричному розумінні. TTFB рахується від моменту запиту до першого байта фінальної відповіді (200 OK), а не проміжної (103). Але вони покращують LCP і візуально відчутну швидкість, бо критичні ресурси починають вантажитись раніше.

За даними web.dev та власних вимірів на клієнтських проектах (український ecommerce, медіа, SaaS-дешборди), типовий виграш такий:

  • LCP: –100…–400 мс на p75, залежно від того, як пізно старий код завантажував LCP-image.
  • FCP: –50…–200 мс, якщо через Early Hints ви preload-ите критичний CSS.
  • Score Lighthouse Performance: +3…+8 балів на mobile-профілі.
  • CLS: опосередковано покращується, якщо ви preload-ите шрифти й уникаєте FOUT. Про це я детально розбирав у гіді з оптимізації CLS у 2026 році.

На реальному кейсі одного українського медіа-сайту (SSR через Next.js на Vercel, TTFB ~450 мс через важкий персоналізаційний API) увімкнення Early Hints для шрифту і hero-зображення дало –280 мс LCP на p75 та +6 балів у Lighthouse mobile за рахунок годинної роботи на конфігурацію. Непогана віддача, чесно.

Чим Early Hints відрізняються від <link rel="preload"> у HTML

Це найпоширеніше питання, яке я чую від фронтенд-команд. Відповідь: механізм preload той самий, але момент його активації принципово різний.

Аспект<link rel="preload"> у HTML103 Early Hints
Коли браузер бачить hintПісля TTFB, коли HTML вже парситьсяОдразу після 103, до фінальної відповіді
Виграш у часі0 мс, ви на fast-path парсера100–400 мс, час обробки бекенда
Вимагає HTTP/2 або 3НіТак (обов'язково)
Працює для CDN-кешованих сторінокТакТак, але дає мінімум, бо TTFB і так низький
ДинамічністьЗадається в HTML під час рендеруМоже задаватись на edge, без зміни HTML
Підтримка Safari < 17.4ТакНі

У production я завжди раджу тримати обидва варіанти: <link rel="preload"> у HTML як baseline (для тих 5% трафіку, які ходять по HTTP/1.1 чи старому Safari), та Early Hints як прискорювач для HTTP/2/3 клієнтів. Cloudflare, до речі, робить це автоматично: сканує HTML і піднімає preload у Early Hints.

Антипатерни та типові пастки у production

За два роки роботи з Early Hints я збив шишок достатньо, щоб виділити п'ять паттернів, яких треба уникати.

1. Preload усього підряд

Класична помилка: додати в Early Hints preload для 15 ресурсів «щоб точно було швидко». Результат: bandwidth contention, критичні ресурси конкурують один з одним, LCP погіршується. Правило: не більше 3–5 preload у Early Hints, і тільки для тих ресурсів, які точно на critical path.

2. Дублювання з Service Worker

Якщо у вас Service Worker уже кешує статику і повертає її з кешу, Early Hints для тих самих ресурсів марні. Гірше: браузер може почати fetch, а SW перехопить його і зробить свій fetch, що додає 5–15 мс overhead. Перевірте у DevTools → Network, чи не «пробиває» Early Hints ваш SW-кеш.

3. Забуті crossorigin і as

// НЕПРАВИЛЬНО: без crossorigin шрифт завантажиться, але браузер його не використає
Link: </fonts/inter.woff2>; rel=preload; as=font

// ПРАВИЛЬНО: як для звичайного preload, crossorigin ОБОВ'ЯЗКОВО для шрифтів
Link: </fonts/inter.woff2>; rel=preload; as=font; type=font/woff2; crossorigin

4. Early Hints для персоналізованих ресурсів

Якщо CDN кешує Early Hints за URL (як робить Cloudflare), а ви віддаєте персоналізований hero-image залежно від куки, усі отримають preload для одного й того самого зображення. Або варіюйте кеш через Vary, або не preload-ьте персоналізоване.

5. Ігнорування Speculation Rules API

Early Hints, це не єдиний інструмент preload-у на 2026. Для повного циклу навігації додайте Speculation Rules API для миттєвих переходів: комбінація «prerender наступної сторінки + Early Hints для критичних ресурсів на ній» дає майже нульове відчуття завантаження.

Як виміряти виграш і що моніторити

Без вимірювання Early Hints, це cargo cult. Ось мій робочий чеклист.

Локально: WebPageTest та Chrome DevTools

  1. Відкрийте WebPageTest, оберіть Chrome mobile, 4G-профіль, локацію ближче до вашої аудиторії.
  2. Запустіть A/B: перший ран з ?noeh=1 (вимкніть Early Hints через query-параметр і бранч у Worker), другий з увімкненими Early Hints.
  3. Порівняйте waterfall: preload-запити з Early Hints мають з'явитись перед HTML-запитом на першому ряді.
  4. У Chrome DevTools → Network → колонка «Initiator», Early Hints позначаються як early-hints ініціатор.

Production: RUM + Core Web Vitals

Порівнюйте LCP p75 до і після на реальних користувачах через web-vitals бібліотеку, надсилаючи метрики в аналітику. Мінімум два тижні даних кожного варіанту, бо сезонність трафіку може ввести в оману. Розбивайте по країнах: користувачі з дальших регіонів отримують більший виграш через довший RTT до origin.

CDN-логи

На Cloudflare увімкніть Logpush і фільтруйте по EarlyHintsSent та EarlyHintsResponseHeaders. Це показує, які саме підказки надіслані на кожен запит, і допомагає ловити випадки, коли CDN пропустив preload через застарілий кеш.

Часті питання

Чи потрібно вимикати <link rel="preload"> у HTML, якщо я вже використовую Early Hints?

Ні. Тримайте обидва: HTML-preload, це fallback для клієнтів без HTTP/2 або старих Safari. Cloudflare і Vercel навіть використовують HTML-теги як джерело для Early Hints, тому їх видалення зламає автоматику.

Чи безпечно вмикати Early Hints у production без тестування?

На Cloudflare практично так, вони мають вбудований safety net і відкат. На власному сервері тільки після A/B-тестування на 5–10% трафіку та моніторингу LCP і CLS. Особлива увага до сторінок з редіректами.

Чому Early Hints не працюють на моєму сайті на Chrome?

Найчастіші причини: сайт віддається через HTTP/1.1 (Chrome ігнорує 103 на 1.1), Service Worker перехоплює навігацію, або перед CDN стоїть проксі, який не підтримує проміжні відповіді. Перевірте chrome://net-export.

Чи зменшує 103 Early Hints TTFB у Lighthouse?

Ні, метричний TTFB рахується до фінальної відповіді 200 OK і залишається тим самим. Але LCP і Speed Index покращуються, бо критичні ресурси починають завантажуватись під час обробки бекенда.

Скільки Link-заголовків можна надіслати в одній Early Hints відповіді?

Формально ліміт залежить від конфігурації буферів вашого HTTP-сервера, зазвичай кілька кілобайтів. Практично тримайте до 3–5 preload плюс 1–2 preconnect. Більше, це вже конкуренція за bandwidth, яка шкодить LCP.

Mateo Silva
Про Автора Mateo Silva

Full-stack performance lead bridging frontend perf with backend latency. Cache invalidation is his love language.