Введение: Почему скорость имеет значение?
Представьте, что ваш сайт загружается дольше 3 секунд. По данным Google, 53% пользователей покинут его, а конверсия упадет на 20%. Для PHP-разработчика умение оптимизировать приложение — это не просто «хороший тон», а необходимость. Даже если вы только начинаете свой путь, базовые техники ускорения кода помогут вам создавать быстрые и отзывчивые проекты.
В этой статье мы разберем 4 ключевых направления: от кэширования и работы с базами данных до настройки сервера и профилирования. Вы получите готовые примеры кода и чек-лист для внедрения.
1. Кэширование: сохраняем результат, а не пересчитываем заново
Кэширование — это как запись шпаргалки перед экзаменом. Вместо того чтобы каждый раз заново вычислять сложные данные, мы сохраняем их в быстром хранилище.
1.1. Кэширование в памяти (Memcached / Redis)
Для данных, которые редко меняются (например, список категорий или настройки), идеально подходит кэширование в оперативной памяти.
<?php
// Пример с Memcached
$memcached = new Memcached();
$memcached->addServer('localhost', 11211);
$key = 'categories_list';
$categories = $memcached->get($key);
if ($categories === false) {
// Данных нет в кэше — получаем из БД
$categories = $db->query("SELECT * FROM categories")->fetchAll();
// Сохраняем на 1 час (3600 секунд)
$memcached->set($key, $categories, 3600);
}
// Используем $categories
foreach ($categories as $cat) {
echo $cat['name'];
}
?>
1.2. Кэширование HTML-фрагментов (Output Buffer)
Если у вас есть тяжелые блоки (виджеты, меню), кэшируйте готовый HTML.
<?php
function getCachedWidget($widgetName, $ttl = 300) {
$cacheFile = __DIR__ . '/cache/' . md5($widgetName) . '.html';
if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < $ttl) {
return file_get_contents($cacheFile);
}
ob_start();
// Здесь код, который генерирует виджет
echo "<div class='widget'>Сложный контент...</div>";
$html = ob_get_clean();
file_put_contents($cacheFile, $html);
return $html;
}
echo getCachedWidget('sidebar_menu');
?>
2. Оптимизация запросов к базе данных
Самое узкое место в PHP-приложениях — это база данных. Один плохой запрос может «убить» производительность всего сайта.
2.1. Используйте индексы
Без индекса MySQL вынужден сканировать всю таблицу. Добавьте индексы на поля, которые участвуют в WHERE, JOIN и ORDER BY.
-- Плохо: полное сканирование
SELECT * FROM users WHERE email = 'test@test.com';
-- Хорошо: используем индекс
CREATE INDEX idx_email ON users(email);
SELECT * FROM users WHERE email = 'test@test.com';
2.2. Избегайте N+1 запросов
Это классическая ошибка: в цикле вы дергаете БД для каждого элемента.
<?php
// ПЛОХО: N+1 запросов
$users = $db->query("SELECT * FROM users")->fetchAll();
foreach ($users as $user) {
$orders = $db->query("SELECT * FROM orders WHERE user_id = " . $user['id']);
// ...
}
// ХОРОШО: один запрос с JOIN
$users = $db->query("
SELECT u.*, o.*
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
")->fetchAll();
?>
2.3. Ленивая загрузка (Lazy Loading)
Не загружайте данные, которые не нужны прямо сейчас. Используйте пагинацию или LIMIT.
// Вместо:
$all = $db->query("SELECT * FROM logs"); // 100 000 строк
// Используйте:
$page = $_GET['page'] ?? 1;
$limit = 20;
$offset = ($page - 1) * $limit;
$logs = $db->query("SELECT * FROM logs LIMIT $limit OFFSET $offset");
3. Настройка сервера и OPcache
Иногда проблема не в коде, а в конфигурации PHP. Самая мощная оптимизация — включить OPcache.
3.1. Включаем OPcache
OPcache кэширует скомпилированный байт-код PHP, избавляя сервер от повторной компиляции скриптов при каждом запросе.
; В php.ini или .user.ini
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.revalidate_freq=60
; Отключаем проверку изменений на продакшене (для разработки оставьте 0)
opcache.validate_timestamps=0
После включения вы заметите прирост скорости на 20-40% без изменения кода.
3.2. Настройка сессий
Если сессии хранятся в файлах, а у вас много посетителей, используйте Redis или Memcached для хранения сессий.
// В php.ini
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"
4. Профилирование: находим узкие места
Не оптимизируйте вслепую. Используйте инструменты, чтобы понять, что именно тормозит.
4.1. Xdebug + Webgrind
Xdebug генерирует профилировочные файлы, а Webgrind визуализирует их.
// Установка Xdebug (пример для Ubuntu)
sudo apt install php-xdebug
// Включите профилирование в php.ini
xdebug.profiler_enable = 1
xdebug.profiler_output_dir = /tmp
4.2. Простой таймер своими руками
Для быстрой проверки одного участка кода:
<?php
$start = microtime(true);
// Ваш код
for ($i = 0; $i < 100000; $i++) {
$arr[] = $i;
}