Чому швидкість WordPress важлива
Google використовує швидкість завантаження як фактор ранжування. Кожні 100 мс затримки знижують конверсію на 1%. Нижче — 10 конкретних кроків.
10 способів прискорити WordPress
| # | Метод | Приріст швидкості | Складність |
|---|---|---|---|
| 1 | Кеш сторінок (LiteSpeed/WP Rocket) | ★★★★★ | Низька |
| 2 | CDN (Cloudflare / BunnyCDN) | ★★★★☆ | Низька |
| 3 | WebP-зображення | ★★★★☆ | Низька |
| 4 | Lazy Loading зображень | ★★★☆☆ | Низька |
| 5 | Redis Object Cache | ★★★★★ | Середня |
| 6 | Мінімізація CSS/JS | ★★★☆☆ | Низька |
| 7 | Відкладений JS (defer) | ★★★☆☆ | Низька |
| 8 | Оптимізація БД (WP-Sweep) | ★★☆☆☆ | Низька |
| 9 | PHP 8.2 + OPcache | ★★★★☆ | Середня |
| 10 | GZIP/Brotli стиснення | ★★★☆☆ | Низька |
Увімкнення OPcache у php.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=0
opcache.validate_timestamps=0 ; лише для production!
GZIP у Nginx
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
gzip_min_length 256;
gzip_comp_level 6;
Розбір типових помилок при пришвидшенні
Під час увімкнення агресивного кешу та оптимізації PHP сайт іноді не пришвидшується, а падає. Розберемо, що означають конкретні тексти помилок і як їх усунути.
| Текст помилки або симптом | Причина | Що робити |
|---|---|---|
Білий екран після зміни opcache.validate_timestamps=0 | OPcache тримає в пам'яті байт-код старої версії файлів і не бачить новий деплой | Після кожного деплою викликати opcache_reset() або перезапускати php-fpm |
| There has been a critical error on this website | Мінифікатор JS склеїв несумісні між собою скрипти теми та кеш-плагіна | Вимкнути мінифікацію JS точково для конфліктного файлу і перевірити debug.log |
| Error establishing a database connection після увімкнення об'єктного кешу | Розширення Redis або Memcached недоступне на PHP-FPM, а не сама база даних впала | Перевірити php -m | grep redis і статус systemctl status redis-server |
| Верстка «стрибає» після Lazy Loading | Браузер не резервує місце під зображення без атрибутів width і height | Задати реальні width і height у тегах img, а не лише CSS-розміри |
Детальніше про налаштування самого Redis для WordPress — у статті про об'єктний кеш Redis.
Обмеження: коли кеш і CDN не допоможуть
Пришвидшення через кеш працює не для всіх типів сторінок і не на будь-якому тарифі хостингу.
- Сторінки з персональним контентом — особистий кабінет, кошик, форма замовлення — не можна кешувати цілком: кожен користувач побачить чужі дані
- На тарифах із жорстким лімітом CPU (більшість shared-хостингів) об'єктний кеш Redis підключити не вийде — там немає доступу до systemd і власних сервісів
- Якщо сайт отримує менше 100 відвідувачів на добу, налаштування CDN не окупить витрачений час — вузьке місце зазвичай у самому коді, а не в доставці статики
- Сайти з активними WebSocket-з'єднаннями або long-polling через AJAX не пришвидшуються кешем сторінок, бо кожен запит унікальний
- Важкі PDF-каталоги та генератори звітів на льоту все одно впруться в CPU під час першого звернення, кеш лише приховує проблему для повторних візитів
Перш ніж вмикати одразу всі десять способів, зробіть базовий замір: без базової метрики TTFB і Core Web Vitals неможливо довести, що конкретна зміна справді дала ефект, а не збіглася з менш завантаженим часом доби на хостингу.
Пріоритет ресурсів і Critical CSS
Після базових 10 кроків наступний рівень — винести критичні стилі в head, а решту CSS завантажувати асинхронно. Це напряму впливає на Largest Contentful Paint.
<!-- У head: інлайн критичних стилів -->
<style>/* лише стилі для першого екрана */</style>
<!-- Решта CSS — асинхронно -->
<link rel="preload" href="/wp-content/themes/mytheme/style.css" as="style" onload="this.rel='stylesheet'">
Як перевірити, що оптимізація спрацювала
Числа в PageSpeed Insights коливаються від прогону до прогону, тому перевіряйте одразу кількома способами.
# Перевірити час до першого байта
curl -o /dev/null -s -w 'TTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n' https://example.com/
# Перевірити, що віддається стиснення
curl -sI -H 'Accept-Encoding: gzip, br' https://example.com/ | grep -i content-encoding
- Content-Encoding у відповіді — br або gzip, інакше стиснення не застосувалося
- Заголовок X-Cache: HIT або аналог плагіна кешу під час другого запиту до тієї самої сторінки
- PageSpeed Insights: Largest Contentful Paint нижче 2.5 секунди на мобільному
- GTmetrix: TTFB нижче 200 мс на хостингу з NVMe і PHP OPcache
Якщо після всіх кроків PHP усе ще вузьке місце — перевірте налаштування OPcache для PHP, а стиснення на рівні вебсервера — у статті про GZIP і Brotli.
Часті питання
Чи можна кешувати сторінки кошика та особистого кабінету в WooCommerce?
Ні, сторінки з персональним змістом — кошик, особистий кабінет, оформлення замовлення — не можна кешувати як звичні статичні сторінки: один користувач побачить дані іншого. Плагіни кешування зазвичай виключають такі URL автоматично за замовчуванням, проте варто перевірити налаштування вручну і переконатися, що динамічні розділи магазину справді позначені як винятки в правилах кешу.
Чому сайт може показати білий екран саме після вимкнення opcache.validate_timestamps?
За вимкненого validate_timestamps OPcache перестає звіряти файли з диском і тримає в пам'яті байт-код старої версії коду навіть після деплою нових файлів. Якщо новий код несумісний зі старим закешованим станом, сервер віддає помилку замість сторінки. Рішення — викликати скидання кешу або перезапускати PHP-FPM одразу після кожного оновлення файлів на продакшені.
Чи варто налаштовувати CDN або Redis для сайту з дуже невеликою кількістю відвідувачів?
Для сайту з геть невеликою кількістю відвідувачів на добу налаштування CDN зазвичай не окупає витрачений час — вузьке місце частіше знаходиться в самому коді, а не в доставці статики мережею. Redis теж не завжди доступний: на тарифах із жорстким лімітом процесора об'єктний кеш просто немає де розгорнути, оскільки немає доступу до власних фонових сервісів.
Чому верстка може «стрибати» після увімкнення Lazy Loading для зображень?
Браузер резервує місце під картинку заздалегідь лише тоді, коли у тега img задані явні атрибути width і height. Якщо вказані лише CSS-розміри або атрибути взагалі відсутні, до моменту фактичного завантаження зображення браузер не знає його пропорцій, і сусідній вміст зсувається одразу після підвантаження — це і відчувається як раптовий «стрибок» верстки.