Оптимізація TTFB: від 1.2 с до 150 мс за тиждень
Нещодавно до нас звернувся власник інтернет-магазину зі скаргою на повільне завантаження — TTFB становив 1.2 секунди на головній сторінці. Після комплексного аудиту ми впровадили full page cache, налаштували Nginx FastCGI кеш, оптимізували запити до БД та підключили Redis. Результат: TTFB впав до 150 мс, LCP покращився на 40%, а конверсія зросла на 12%. У цій статті розбираємо, які саме кроки призвели до такого ефекту.
TTFB (Time to First Byte) — час від відправки запиту до отримання першого байта відповіді. Він складається з DNS-резолву, встановлення з'єднання (TCP+TLS), відправки запиту, обробки на сервері та генерації відповіді. Найкерованіша частина — серверна обробка. Саме її ми й оптимізуємо. Згідно з документацією Google по Web Vitals, TTFB безпосередньо впливає на LCP та INP.
Чому TTFB критичний для Core Web Vitals?
Google використовує TTFB як показник першого відгуку. Якщо сервер думає довше 600 мс, навіть ідеальний фронтенд не врятує LCP. Ми це бачили на десятках проєктів: зниження TTFB з 1 с до 200 мс покращувало LCP на 40%. Крім того, повільний сервер затримує обробку користувацьких запитів, погіршуючи INP (Interaction to Next Paint).
Як діагностувати TTFB за допомогою Chrome DevTools та WebPageTest?
- Chrome DevTools (вкладка Network): заміряємо Waiting (TTFB) для кожного запиту. Фільтруємо за типом document.
- WebPageTest: дає детальний waterfall, що показує DNS, TCP, TLS, перший байт. Вказує, скільки часу зайняв сервер.
- Lighthouse: загальна оцінка з рекомендаціями.
- RUM-рішення (Яндекс.Метрика, Google Analytics): показують реальні значення TTFB для користувачів.
Ми завжди починаємо з RUM-даних, щоб отримати об'єктивну картину.
Кешування — головний інструмент
Full Page Cache на рівні застосунку
Найефективніший спосіб — кешувати готовий HTML для всіх неавторизованих користувачів. Ось middleware для Laravel:
class FullPageCache { private const TTL = 300; // 5 хвилин public function handle(Request $request, Closure $next): Response { if (!$this->isCacheable($request)) { return $next($request); } $key = $this->cacheKey($request); if (Cache::has($key)) { return response(Cache::get($key)) ->header('X-Cache', 'HIT') ->header('Content-Type', 'text/html; charset=UTF-8'); } $response = $next($request); if ($response->getStatusCode() === 200) { Cache::put($key, $response->getContent(), self::TTL); } return $response->header('X-Cache', 'MISS'); } private function isCacheable(Request $request): bool { return $request->isMethod('GET') && !auth()->check() && !$request->hasCookie(session()->getName()); } private function cacheKey(Request $request): string { return 'fpc:' . sha1($request->fullUrl()); } } Такий підхід дає TTFB < 50 мс для закешованих сторінок. Головне — правильно налаштувати інвалідацію при зміні контенту. Ми використовуємо події (Model events) для очищення кешу відповідних URL.
Nginx FastCGI Cache — швидше, ніж PHP+Redis
Кеш на рівні nginx працює до генерації PHP, що дає виграш ще в 10-20 мс:
fastcgi_cache_path /var/cache/nginx/fcgi levels=1:2 keys_zone=LARAVEL:10m inactive=60m max_size=1g; fastcgi_cache_key "$scheme$request_method$host$request_uri"; server { location ~ \.php$ { fastcgi_cache LARAVEL; fastcgi_cache_valid 200 5m; fastcgi_cache_valid 404 1m; fastcgi_cache_bypass $cookie_laravel_session $http_authorization; fastcgi_no_cache $cookie_laravel_session $http_authorization; add_header X-Fastcgi-Cache $upstream_cache_status; fastcgi_pass unix:/run/php/php8.2-fpm.sock; } } Для інвалідації використовуємо модуль ngx_cache_purge — надсилаємо PURGE-запит на URL.
Оптимізація запитів до бази даних
Повільні запити — друга за частотою причина високого TTFB. Типова помилка — N+1 problem:
// Повільно $products = Product::all(); foreach ($products as $product) { echo $product->category->name; } // Швидко $products = Product::with(['category', 'images', 'brand'])->get(); Ми профілюємо всі запити через DB::listen і логуємо ті, що виконуються довше 100 мс. Додаємо індекси, замінюємо вкладені цикли на єдині запити з JOIN.
Redis для кешування даних
Кешуємо результати частих запитів — дерево категорій, топ товарів, лічильники:
$categories = Cache::remember('categories:tree', 3600, function () { return Category::with('children')->whereNull('parent_id')->orderBy('sort_order')->get(); }); $stats = Cache::remember('product:stats:' . $productId, 300, function () use ($productId) { return [ 'views' => ProductView::where('product_id', $productId)->count(), 'sales' => OrderItem::where('product_id', $productId)->sum('quantity'), 'wishlist' => WishlistItem::where('product_id', $productId)->count(), ]; }); Інші оптимізації
DNS і мережа
Використовуємо <link rel="preconnect"> для сторонніх ресурсів, щоб скоротити DNS+TCP час. Підключаємо CDN (Cloudflare, Vercel) — вони зменшують затримку за рахунок географічно розподілених серверів.
OPcache для PHP
Налаштування для продакшену:
opcache.enable=1 opcache.memory_consumption=256 opcache.max_accelerated_files=20000 opcache.validate_timestamps=0 opcache.jit=tracing opcache.jit_buffer_size=64M JIT-компіляція прискорює виконання PHP-скриптів на 20-50%, що безпосередньо знижує TTFB.
Порівняння методів кешування
| Метод | TTFB (типовий) | Складність впровадження | Інвалідація |
|---|---|---|---|
| Full Page Cache (PHP) | < 50 мс | Середня | За подіями |
| Nginx FastCGI Cache | < 30 мс | Середня | PURGE-запит |
| Redis кеш даних | 1-5 мс (на запит) | Низька | TTL або ключі |
| CDN + статика | 10-50 мс (на origin) | Низька | За URL |
Що входить у нашу роботу
- Аудит — замір TTFB на всіх типах сторінок, аналіз структури кешування, профілювання БД.
- Проєктування — вибір стратегії кешування під конкретний стек.
- Реалізація — впровадження full page cache, nginx-кешу, оптимізація запитів, налаштування Redis.
- Тестування — A/B-тести до/після, перевірка коректної інвалідації.
- Документація — схема кешування для команди розробки.
- Аудит через півроку — контроль деградації.
Орієнтовний план за строками
- Діагностика та швидкі перемоги (OPcache, індекси): 1-2 дні.
- Full page cache + Nginx кеш: 2-3 дні.
- Глибока оптимізація БД та Redis: 3-5 днів.
- CDN та тонке налаштування: 1-2 дні.
Підсумковий строк — від 2 робочих днів до 2 тижнів залежно від складності.
Цільові значення TTFB за типами сторінок
| Тип сторінки | З кешем | Без кеша |
|---|---|---|
| Головна | < 50 мс | < 300 мс |
| Каталог | < 50 мс | < 400 мс |
| Картка товару | < 50 мс | < 200 мс |
| API-ендпоінти | — | < 100 мс |
Ми гарантуємо зниження TTFB до 500 мс на всіх сторінках і покращення LCP на 30-50%. Клієнти економлять до 40% на хостингу за рахунок кешування, а інвестиції в оптимізацію окупаються за 3-6 місяців. Зв'яжіться з нами для безкоштовного аудиту вашого сайту. Отримайте консультацію з оптимізації TTFB — розберемо ваш проєкт і запропонуємо конкретні кроки.







