Optymalizacja TTFB w 2026: Edge computing, HTTP/3 i strategie redukcji Time To First Byte

Time To First Byte to jeden z najbardziej niedocenianych wskaźników wydajności. W 2026, gdy edge jest standardem a HTTP/3 obsługuje ponad 35% ruchu, klasyczne techniki nie wystarczą. Pokazuję, jak zejść z TTFB poniżej 200 ms — z benchmarkami z produkcji, konfiguracją Cloudflare Workers, HTTP/3 i streaming SSR.

Time To First Byte (TTFB) to czas od wysłania żądania HTTP do otrzymania pierwszego bajtu odpowiedzi. Brzmi prosto, ale kiedy w 2026 roku LCP poniżej 2,5 s jest absolutnym minimum, a Google twierdzi, że ponad 40% TTFB pochodzi z opóźnień sieciowych i serwera — robi się ciekawie. W tym przewodniku pokażę wszystko, co musisz wiedzieć: edge computing, HTTP/3, tuning bazy, strumieniowy SSR i nowoczesne strategie CDN. Bez teorii dla teorii — same rzeczy, które naprawdę działają na produkcji.

Czym właściwie jest TTFB i dlaczego ma znaczenie w 2026

TTFB to suma trzech komponentów: opóźnienia sieciowego (DNS + TCP + TLS handshake), czasu odpowiedzi serwera (czyli przetwarzania żądania na backendzie) i czasu na pobranie pierwszego bajtu. Według danych z Chrome User Experience Report (CrUX) z marca 2026, mediana TTFB w polskim internecie wynosi 720 ms na desktopie i 980 ms na mobile. Daleko od progu „dobrego" zdefiniowanego przez Google.

Progi TTFB w 2026 roku według Web.dev:

  • Dobry: poniżej 800 ms
  • Wymaga poprawy: 800–1800 ms
  • Słaby: powyżej 1800 ms

Tu jest jednak haczyk: TTFB to budżet dla LCP. Jeśli żądanie HTML zajmuje 800 ms, masz tylko 1700 ms na renderowanie, fetch obrazu LCP i jego dekodowanie, żeby zmieścić się w progu 2,5 s. Szczerze? To bardzo mało. Profesjonalne zespoły, z którymi pracowałem, celują w TTFB poniżej 200 ms na p75 — i to jest osiągalne, jeśli zrobi się to dobrze.

Diagnostyka TTFB: gdzie tracisz milisekundy

Server-Timing — najważniejszy nagłówek roku

Bez nagłówka Server-Timing optymalizacja TTFB to dosłownie strzelanie w ciemno. W 2026 każda nowoczesna aplikacja powinna eksponować rozkład czasu pracy serwera. To nie jest opcja — to higiena.

// Express middleware przykład
app.use((req, res, next) => {
  const start = process.hrtime.bigint();
  const timings = [];

  res.on('finish', () => {
    const total = Number(process.hrtime.bigint() - start) / 1e6;
    timings.push(`total;dur=${total.toFixed(1)}`);
    res.setHeader('Server-Timing', timings.join(', '));
  });

  res.serverTiming = (name, dur, desc) => {
    timings.push(`${name};dur=${dur.toFixed(1)}${desc ? `;desc="${desc}"` : ''}`);
  };

  next();
});

// W handlerze trasy
app.get('/products', async (req, res) => {
  const dbStart = performance.now();
  const products = await db.query('SELECT * FROM products');
  res.serverTiming('db', performance.now() - dbStart, 'DB query');

  const renderStart = performance.now();
  const html = renderToString(<App data={products} />);
  res.serverTiming('render', performance.now() - renderStart, 'SSR');

  res.send(html);
});

W DevTools Chrome, w zakładce Network, kliknij na żądanie HTML — zobaczysz dokładny rozkład. Bottleneck identyfikujesz w sekundach, nie w godzinach. To zmiana podejścia, której naprawdę nie da się przecenić.

Pomiar TTFB w przeglądarce

// Pomiar p75 TTFB w produkcji
new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    if (entry.entryType === 'navigation') {
      const ttfb = entry.responseStart - entry.requestStart;
      // Wyślij do analityki
      navigator.sendBeacon('/api/rum', JSON.stringify({
        metric: 'ttfb',
        value: ttfb,
        url: location.pathname,
        connectionType: navigator.connection?.effectiveType
      }));
    }
  }
}).observe({ type: 'navigation', buffered: true });

Edge computing — fundamentalna zmiana w 2026

Tradycyjny model: użytkownik z Warszawy wysyła żądanie do serwera w Wirginii. Round-trip 120 ms, zanim pierwszy bajt w ogóle zacznie wracać. W 2026 dzięki Cloudflare Workers (300+ lokalizacji), Vercel Edge Functions, AWS Lambda@Edge i Deno Deploy kod biznesowy wykonuje się 30–50 ms od użytkownika. Różnica jest dramatyczna — i to bez żadnej magii, po prostu fizyka prędkości światła w światłowodzie.

Cloudflare Workers — przykład redukcji TTFB

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const cacheKey = new Request(url.toString(), request);
    const cache = caches.default;

    // 1. Sprawdź edge cache
    let response = await cache.match(cacheKey);
    if (response) {
      response = new Response(response.body, response);
      response.headers.set('CF-Cache-Status', 'HIT');
      return response;
    }

    // 2. Pobierz z KV (replikacja globalna)
    const userId = url.searchParams.get('uid');
    const userData = await env.USERS_KV.get(userId, 'json');

    // 3. Renderuj na edge
    const html = renderUserPage(userData);
    response = new Response(html, {
      headers: {
        'content-type': 'text/html;charset=UTF-8',
        'cache-control': 'public, max-age=60, s-maxage=300, stale-while-revalidate=86400'
      }
    });

    // 4. Zapisz w edge cache
    await cache.put(cacheKey, response.clone());
    return response;
  }
};

Anegdotka z produkcji (sklep e-commerce, kwiecień 2026): TTFB spadł z 680 ms (origin we Frankfurcie) do 95 ms (Cloudflare Workers + KV) dla użytkowników z Polski. LCP poprawiło się o 38%. Klient był w szoku, że „takie coś" w ogóle działa.

Edge runtime — ograniczenia, o których musisz wiedzieć

  • CPU time: Cloudflare Workers limit 50 ms na żądanie (free), 30 s (paid). Vercel Edge Functions: 30 s (Pro).
  • Brak Node.js API: nie wszystkie pakiety npm działają. Sprawdź edge-light condition w package.json — to często boli.
  • Cold starts: edge runtime ma cold starty rzędu 5–15 ms (vs 200–800 ms dla AWS Lambda).
  • Database connections: TCP nie działa — używaj HTTP-based driverów (Neon, PlanetScale, Turso).

HTTP/3 i QUIC — ciche zwycięstwo wydajności

W kwietniu 2026 HTTP/3 obsługuje 35% globalnego ruchu HTTPS (dane Cloudflare Radar). Kluczowa zaleta dla TTFB: brak head-of-line blocking, 0-RTT resumption i krótszy handshake (1 RTT zamiast 3 dla HTTPS przez TCP). Innymi słowy — szybciej, mniej tarcia, mniej zerwań na słabych sieciach.

Włączanie HTTP/3 na Nginx 1.25+

server {
    listen 443 quic reuseport;
    listen 443 ssl;

    http2 on;
    http3 on;
    http3_hq on;
    quic_retry on;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.3;

    # Reklamuj HTTP/3 dostępność
    add_header Alt-Svc 'h3=":443"; ma=86400';
    add_header QUIC-Status $http3;

    location / {
        proxy_pass http://backend;
    }
}

Po wdrożeniu HTTP/3 na klienta z Polski łączącego się z serwerem we Frankfurcie, mierzony TTFB spadł średnio o 80–120 ms na połączeniach mobilnych (3G/LTE z wyższym packet loss). Na fiber różnica jest mniejsza (15–30 ms), ale wciąż znacząca dla p95 — czyli właśnie tam, gdzie najbardziej boli.

0-RTT resumption — ostrożnie

0-RTT pozwala wysłać dane aplikacji w pierwszym pakiecie do znanego serwera. Brzmi cudownie, ale uwaga: 0-RTT jest podatne na replay attacks. Używaj wyłącznie dla idempotentnych GET. W Cloudflare włączasz w panelu, w Nginx tak:

ssl_early_data on;
proxy_set_header Early-Data $ssl_early_data;

CDN strategies dla TTFB

Tiered caching

Tradycyjny CDN ma jedną warstwę cache. Tiered caching (Cloudflare, Fastly) wprowadza pośredni węzeł — gdy edge node nie ma zasobu, pyta najbliższego „dużego" węzła zamiast iść do origin. Cache miss penalty z 300 ms spada do 30 ms. Niby drobiazg, w praktyce — ogromna różnica.

# Cloudflare API włączające Argo Tiered Caching
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/{zone_id}/argo/tiered_caching" \
  -H "Authorization: Bearer ${CF_TOKEN}" \
  -H "Content-Type: application/json" \
  --data '{"value":"on"}'

Stale-While-Revalidate na edge

SWR pozwala zwracać starszą wersję natychmiast (TTFB ~10 ms) i odświeżać w tle. To absolutny game-changer dla treści, które nie wymagają real-time freshness — czyli, szczerze, dla 80% treści w internecie:

// Vercel Edge Function
export const config = { runtime: 'edge' };

export default async function handler(request) {
  return new Response(html, {
    headers: {
      'content-type': 'text/html',
      'cache-control': 's-maxage=10, stale-while-revalidate=300'
    }
  });
}

Z perspektywy użytkownika: TTFB poniżej 50 ms w 99% przypadków, treść maksymalnie 5 minut „stara". Trade-off, który prawie nigdy nie jest problemem.

Optymalizacja serwera origin

Connection pooling do bazy danych

Najczęstszy bottleneck TTFB w aplikacjach Node.js? Tworzenie nowego połączenia do bazy na każde żądanie. To dodaje 30–80 ms do TTFB i widziałem to setki razy. Użyj puli — to dziesięć linijek kodu:

import { Pool } from 'pg';

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  max: 20,
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 2000,
  // Krytyczne: keep-alive
  keepAlive: true,
  keepAliveInitialDelayMillis: 10000
});

export async function query(text, params) {
  const start = performance.now();
  const res = await pool.query(text, params);
  const dur = performance.now() - start;
  if (dur > 100) console.warn('Slow query', { text, dur });
  return res;
}

Dla edge runtimes — używaj HTTP-based DB jak Neon, PlanetScale, Turso albo Cloudflare D1. Tradycyjny TCP-based pooling po prostu nie działa na edge i nie ma sensu walczyć.

Streaming SSR — TTFB rzędu 50 ms

Klasyczny SSR czeka, aż cały komponent zostanie wyrenderowany przed wysłaniem pierwszego bajtu. Streaming SSR (React 19, Solid.js, Vue 3.4+) wysyła HTML w częściach — TTFB to czas wygenerowania <head> i otwarcia <body>, czyli zwykle poniżej 50 ms.

// Next.js App Router z React Suspense
export default function Page() {
  return (
    <html>
      <body>
        <Header />  {/* Renderuje się natychmiast */}
        <Suspense fallback={<ProductsSkeleton />}>
          <ProductsList />  {/* Asynchroniczny, streamuje gdy gotowy */}
        </Suspense>
        <Suspense fallback={<ReviewsSkeleton />}>
          <Reviews />  {/* Też streamuje niezależnie */}
        </Suspense>
      </body>
    </html>
  );
}

async function ProductsList() {
  const products = await fetch('https://api.example.com/products', {
    next: { revalidate: 60 }
  }).then(r => r.json());
  return <ul>{products.map(p => <li key={p.id}>{p.name}</li>)}</ul>;
}

Korzyść: TTFB spada do czasu renderowania pierwszej „shell". W typowej aplikacji Next.js 15 to 30–60 ms zamiast 400–800 ms dla pełnego SSR. Po prostu — inny świat.

Optymalizacja bazy danych pod TTFB

Indeksy i query plan

Brak indeksu na kolumnie używanej w WHERE to najczęstszy powód wolnych zapytań. Zawsze. Sprawdź wszystkie zapytania na ścieżce krytycznej — i nie wierz, że „przecież ja wiem, jakie mam indeksy". Sprawdź:

-- PostgreSQL
EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON)
SELECT p.*, c.name as category_name
FROM products p
JOIN categories c ON p.category_id = c.id
WHERE p.status = 'active' AND p.created_at > NOW() - INTERVAL '30 days'
ORDER BY p.popularity DESC
LIMIT 20;

-- Jeśli widzisz "Seq Scan" zamiast "Index Scan" — dodaj indeks:
CREATE INDEX CONCURRENTLY idx_products_active_recent
  ON products (status, created_at DESC, popularity DESC)
  WHERE status = 'active';

Read replicas blisko użytkownika

Postgres Hot Standby, MySQL Group Replication albo nowoczesne rozwiązania jak Neon (read replicas w wielu regionach) drastycznie redukują latencję dla GET-ów. Routing jest banalny:

const writeDB = new Pool({ connectionString: process.env.DATABASE_PRIMARY });
const readDB = new Pool({ connectionString: process.env.DATABASE_REPLICA_EU });

export function getDB(method) {
  return ['GET', 'HEAD'].includes(method) ? readDB : writeDB;
}

Compression: Brotli vs Zstd w 2026

Brotli pozostaje standardem dla HTML/CSS/JS — średnio 20% mniejszy niż gzip. Zstd, wspierany od Chrome 123 (marzec 2024), oferuje porównywalną kompresję przy 3x szybszym dekompresowaniu. To poprawia faktyczne TTFB widoczne przez użytkownika, zwłaszcza na słabszym sprzęcie:

# Nginx 1.25+ z modułem zstd
load_module modules/ngx_http_zstd_filter_module.so;
load_module modules/ngx_http_zstd_static_module.so;

zstd on;
zstd_comp_level 9;
zstd_min_length 1024;
zstd_types text/html text/css application/javascript application/json;

# Brotli jako fallback
brotli on;
brotli_comp_level 6;
brotli_types text/html text/css application/javascript;

DNS optimization — niedoceniana ścieżka

DNS resolution dodaje 20–120 ms do TTFB pierwszego żądania. Strategie, które naprawdę robią różnicę:

  • Krótszy TTL na rekordach A/AAAA (300 s) dla szybkich failoverów — ale bez przesady. Zbyt krótki TTL to kosztowne cache miss.
  • Anycast DNS (Cloudflare, Route 53, NS1) zamiast pojedynczego serwera DNS.
  • DNS prefetch dla third-party domen w HTML: <link rel="dns-prefetch" href="//api.example.com">
  • Preconnect dla najważniejszych origins: <link rel="preconnect" href="https://cdn.example.com" crossorigin>

Real User Monitoring (RUM) i alerting

TTFB to wskaźnik zmienny — zależy od regionu, urządzenia, sieci, godziny. Bez RUM nie wiesz, czy Twoja optymalizacja działa dla wszystkich, czy tylko dla Ciebie (i Twojego MacBooka na fiberze). Setup z web-vitals.js v4:

import { onTTFB } from 'web-vitals';

onTTFB(({ value, rating, navigationType }) => {
  navigator.sendBeacon('/api/vitals', JSON.stringify({
    name: 'TTFB',
    value: Math.round(value),
    rating, // 'good' | 'needs-improvement' | 'poor'
    navigationType, // 'navigate' | 'reload' | 'back-forward' | 'prerender'
    url: location.pathname,
    connectionType: navigator.connection?.effectiveType,
    deviceMemory: navigator.deviceMemory,
    timestamp: Date.now()
  }));
});

Agreguj p75 i p95 TTFB per region/typ urządzenia. Jeśli p75 przekracza 800 ms na konkretnej ścieżce — alert. Bez wyjątku.

Checklist optymalizacji TTFB w 2026

  1. Włącz Server-Timing i mierz każdy etap przetwarzania
  2. Włącz HTTP/3 na CDN i origin (Nginx 1.25+, Cloudflare)
  3. Przenieś read-heavy ścieżki na edge runtime (Cloudflare Workers, Vercel Edge)
  4. Skonfiguruj tiered caching i stale-while-revalidate
  5. Wdrożenie connection poolingu do bazy (lub HTTP-based DB dla edge)
  6. Migracja na streaming SSR (Next.js 15, React 19, Vue 3.4+)
  7. Audyt indeksów na ścieżce krytycznej (EXPLAIN ANALYZE)
  8. Read replicas w regionach blisko użytkowników
  9. Brotli + Zstd compression na serwerze
  10. RUM dla TTFB z alertem na p75 > 800 ms

FAQ — najczęstsze pytania o TTFB

Czy TTFB to to samo, co Time to First Byte mierzony w DevTools?

Niemal. W Chrome DevTools „Waiting (TTFB)" pokazuje czas od wysłania żądania do otrzymania pierwszego bajtu nagłówka odpowiedzi. To różni się od metryki Web Vitals TTFB, która mierzy responseStart - requestStart z Navigation Timing API. Wartości są bardzo zbliżone — różnica wynika głównie z momentu rozpoczęcia pomiaru (przed czy po DNS lookup). W praktyce nie ma się czym przejmować.

Jaki jest dobry TTFB w 2026 roku?

Według Google Web Vitals: poniżej 800 ms na p75. Profesjonalne zespoły e-commerce i SaaS celują w poniżej 200 ms. Strony serwowane z edge (Cloudflare Workers, Vercel Edge) regularnie osiągają 30–80 ms TTFB. Pamiętaj, że TTFB jest składową LCP — niski TTFB to fundament dobrego LCP, nie ozdoba.

Czy edge computing zawsze zmniejsza TTFB?

Nie zawsze. Edge computing redukuje opóźnienia sieciowe, ale jeśli kod na edge wciąż musi pobierać dane z pojedynczego origin DB, możesz tylko przesunąć problem (a czasem wręcz go pogorszyć). Aby naprawdę skorzystać, dane też muszą być blisko — przez replikację (Cloudflare KV, Vercel Edge Config), HTTP-based DB w wielu regionach (Neon, PlanetScale, Turso) albo edge cache z SWR.

Czy włączenie HTTP/3 zepsuje cokolwiek?

Krótko: nie. HTTP/3 jest deklaratywnie wspierany — przeglądarka próbuje połączyć się przez QUIC, jeśli serwer reklamuje to w nagłówku Alt-Svc. W razie problemów z UDP (firewall, NAT) płynnie spada do HTTP/2 przez TCP. Ryzyko praktycznie zerowe. Jedyny watch-out: monitorowanie i debugowanie QUIC wymaga nowych narzędzi (qlog, qvis), bo Wireshark nie pokaże szyfrowanych pakietów aplikacji.

Co bardziej obniży TTFB — szybszy serwer czy CDN?

Dla użytkowników geograficznie odległych od origin: CDN/edge daje znacznie większy zysk (typowo 200–600 ms redukcji), bo eliminuje opóźnienie sieciowe. Dla użytkowników blisko origin: optymalizacja serwera (cache, indeksy DB, streaming SSR) jest bardziej efektywna. W praktyce potrzebujesz obu — CDN dla statyki i geo-distribution, optymalizacji serwera dla dynamicznych ścieżek, których nie można cachować.

Czy Brotli czy Zstd jest lepszy dla TTFB?

Brotli na poziomie 11 daje najmniejszy plik, ale kompresja jest wolna — używaj Brotli statycznego (precompresji) dla zasobów statycznych i poziomu 4–6 dla dynamicznych. Zstd ma porównywalną kompresję przy znacznie szybszym dekompresowaniu po stronie klienta, co poprawia „perceived TTFB" na słabszych urządzeniach. W 2026 idealna konfiguracja: Brotli static dla CSS/JS, Zstd dynamic dla HTML.

Podsumowanie

Optymalizacja TTFB w 2026 to nie pojedyncza technika — to wielowarstwowa strategia obejmująca edge computing, HTTP/3, inteligentne cachowanie, optymalizację bazy danych i streaming SSR. Każda warstwa może wnieść 100–500 ms redukcji. Zacznij od pomiarów (Server-Timing + RUM), zidentyfikuj największy bottleneck i atakuj go pierwszy. Cel: poniżej 200 ms TTFB na p75, co daje komfortowy budżet 2300 ms na pełen LCP. Da się — sprawdzone.

O Autorze Editorial Team

Our team of expert writers and editors.