Оптимізація продуктивності OpenCart
Стандартна установка OpenCart 3.x/4.x без тюнінгу видає TTFB 800–1500ms на середніх каталогах. Основні причини: неоптимальні запити до бази даних, відсутність opkcache, важкі розширення без кешування, стислі ресурси.
Профайлювання: де вузьке місце
Перед оптимізацією — вимірювання. Увімкнути логування повільних запитів MySQL:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 0.5;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
Через 30 хвилин роботи сайту аналізуємо:
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
Типові проблеми OpenCart у slow log:
-
SELECT * FROM oc_product_descriptionбез індексу заlanguage_id -
getProducts()робить N+1 запити на атрибути - модулі доставки та оплати роблять запити до зовнішніх API при кожній завантаженні корзини
Кешування OpenCart
OpenCart 3 має вбудований файловий кеш в system/storage/cache/. Переключення на Memcached або Redis робиться через system/library/cache.php:
// config.php (в корені)
define('CACHE_DRIVER', 'redis');
define('CACHE_PREFIX', 'oc_');
// Для redis:
define('REDIS_HOST', '127.0.0.1');
define('REDIS_PORT', 6379);
define('REDIS_AUTH', '');
define('REDIS_DB', 1);
В OpenCart 4 конфігурація кешу через config/opencart.php в розділі cache:
'cache' => [
'engine' => 'redis',
'expire' => 3600,
'host' => '127.0.0.1',
'port' => 6379,
],
Після переключення на Redis час рендерингу сторінки каталогу знижується на 40–60% на каталогах від 5000 товарів.
PHP OPcache та FPM
; opcache.ini
opcache.enable=1
opcache.memory_consumption=192
opcache.max_accelerated_files=8000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.interned_strings_buffer=16
opcache.fast_shutdown=1
Настройка PHP-FPM під OpenCart:
pm = dynamic
pm.max_children = 25
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10
pm.max_requests = 1000
pm.max_requests скидає worker після 1000 запитів — критично для OpenCart, де деякі розширення накопичують стан у статичних змінних.
Оптимізація бази даних
Індекси, яких немає в стандартній схемі:
-- Прискорює вибір товарів за категорією зі статусом
ALTER TABLE oc_product ADD INDEX idx_status (status);
ALTER TABLE oc_product_to_category ADD INDEX idx_category (category_id);
-- Для сортування за популярністю/датою
ALTER TABLE oc_product ADD INDEX idx_date_added (date_added);
-- Атрибути (частий N+1)
ALTER TABLE oc_product_attribute
ADD INDEX idx_product_lang (product_id, language_id);
Регулярна очистка застарілих сесій:
DELETE FROM oc_session WHERE expire < UNIX_TIMESTAMP(NOW() - INTERVAL 7 DAY);
Додати в cron раз на добу.
Nginx-конфіг для статики та gzip
# Довгий кеш для статичних файлів
location ~* \.(jpg|jpeg|png|webp|gif|ico|svg|woff2|css|js)$ {
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
}
# Gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_types text/plain text/css application/json application/javascript
text/xml application/xml image/svg+xml;
gzip_min_length 1024;
# Brotli (якщо модуль встановлений)
brotli on;
brotli_comp_level 5;
brotli_types text/plain text/css application/json application/javascript image/svg+xml;
Важкі розширення
Розширення на кшталт «супер-мега-SEO-пак» часто додають 5–15 запитів до БД на кожну сторінку. Діагностика:
// Тимчасово додати в index.php перед require
$start = microtime(true);
register_shutdown_function(function() use ($start) {
error_log('Page time: ' . round((microtime(true) - $start) * 1000) . 'ms');
});
Вимикати розширення по одному та порівнювати час — швидкий спосіб знайти винуватця.
Зображення
OpenCart не конвертує зображення в WebP автоматично. Швидке рішення через nginx:
map $http_accept $webp_suffix {
default "";
"~*webp" ".webp";
}
location /image/ {
try_files $uri$webp_suffix $uri =404;
}
На сервері конвертуємо існуючі зображення:
find /var/www/opencart/image -name "*.jpg" -o -name "*.png" | \
xargs -P4 -I{} sh -c 'cwebp -q 80 "$1" -o "${1%.*}.webp"' -- {}
Терміни робіт
Настройка OPcache, PHP-FPM, Redis-кешу, nginx, індексів БД: 2–3 дні. Аудит розширень та усунення проблемних: 1–2 дні. Конвертація зображень в WebP та настройка nginx: 0.5 дня.







