На 17-ом уроке мы разберем одну из важных тем для любого Symfony-разработчика, это оптимизацию приложений. Даже самый функциональный проект будет провальным, если он медленный. Пользователи не станут ждать, пока ваша страница загрузится за 5-10 секунд. Оптимизация является обязательным этапом разработки. В этом уроке я расскажу о ключевых инструментах Symfony и PHP, которые помогут вашему приложению «летать».
Профилирование с Symfony Profiler
Symfony Profiler ваш лучший друг в поиске узких мест производительности. Он встроен в Symfony и предоставляет детальную информацию о каждом запросе: время выполнения, потребление памяти, SQL-запросы, шаблоны и многое другое.
Как это работает?
- Активация Profiler. В dev-среде Profiler включен по умолчанию. Откройте любую страницу вашего приложения и внизу экрана появится панель с метриками.
- Анализ данных:
- Время выполнения (Timeline). Показывает, сколько времени заняли разные этапы обработки запроса.
- Запросы к БД. Отображает все SQL-запросы, их время выполнения и стек вызовов.
- Память. Потребление памяти на каждом этапе.
- Пример проблемы. Допустим на странице выполняется 50 SQL-запросов. Это явный признак проблемы N+1 (о ней поговорим дальше). Profiler поможет быстро найти такие места.
Практическая задача
- Откройте любой контроллер вашего проекта.
- Добавьте код, который вызывает несколько запросов к БД (например, выборку сущностей в цикле).
- Запустите страницу и найдите в Profiler вкладку Doctrine. Посчитайте количество запросов.
- Постарайтесь сократить их, объединив в один запрос с помощью
JOIN.
Оптимизация Doctrine-запросов
Doctrine мощный ORM, но без правильной настройки он может стать источником проблем. Разберем основные подходы.
1. Проблема N+1
При ленивой загрузке (lazy loading) связанных сущностей Doctrine выполняет отдельный запрос для каждой связи. Например:
// Плохой пример: 1 запрос для постов + N запросов для комментариев $posts = $entityManager->getRepository(Post::class)->findAll(); foreach ($posts as $post) { echo count($post->getComments()); // Запрос выполняется здесь! }
Решение: Используйте жадную загрузку (eager loading) через JOIN:
// Хороший пример: 1 запрос с JOIN $posts = $entityManager->createQueryBuilder() ->select('p', 'c') ->from(Post::class, 'p') ->leftJoin('p.comments', 'c') ->getQuery() ->getResult();
2. Пакетная обработка (Batch Processing)
Если вы работаете с большими объемами данных, используйте iterate() для экономии памяти:
$query = $entityManager->createQuery('SELECT p FROM App\Entity\Product p'); $iterableResult = $query->iterate(); foreach ($iterableResult as $row) { $product = $row[0]; // Обработка... $entityManager->detach($product); // Освобождаем память }
3. Настройки Doctrine
В config/packages/doctrine.yaml добавьте:
doctrine: orm: entity_managers: default: query_cache_driver: apcu metadata_cache_driver: apcu result_cache_driver: apcu
Практическая задача
- Найдите в вашем проекте циклы с обращением к связанным сущностям.
- Перепишите запросы, используя
JOIN. - Проверьте в Profiler, сколько запросов теперь выполняется.
Кэширование конфигурации
Symfony компилирует конфигурацию (роуты, сервисы, параметры) в PHP-классы. По умолчанию в dev-среде кэш обновляется при каждом изменении, но в prod-режиме кэш статичен.
Как включить кэширование?
- Для production:
Кэш включен автоматически. Чтобы обновить его, выполните:php bin/console cache:clear --env=prod
- Для разработки (не рекомендуется, но иногда полезно):
В.envустановите:APP_DEBUG=0
Без кэша:
Время загрузки страницы: 800 мс
С кэшем:
Время загрузки страницы: 200 мс
Практическая задача
- Запустите проект в prod-режиме:
composer install --no-dev php bin/console cache:clear --env=prod
- Замерьте скорость загрузки страницы с помощью инструментов браузера (например, Chrome DevTools).
Использование OPcache
OPcache встроенный в PHP механизм кэширования опкода (скомпилированного PHP-кода). Это критически важно для ускорения Symfony.
Настройка OPcache
В php.ini:
opcache.enable=1 opcache.memory_consumption=256 opcache.max_accelerated_files=20000 opcache.validate_timestamps=0 # Для production!
Проверка статуса
Создайте файл phpinfo.php:
<?php phpinfo();
Откройте его в браузере и найдите раздел OPcache.
Практическая задача
- Проверьте, активен ли OPcache в вашем окружении.
- Если нет, то настройте его и замерьте производительность до/после.
Итоги 17-го урока
Оптимизация это постоянный процесс. используйте Symfony Profiler для поиска узких мест, оптимизируйте запросы Doctrine, не забывайте о кэшировании и OPcache.
Полный курс с уроками по Symfony для начинающих доступен здесь: https://max-gabov.ru/symphony-dlya-nachinaushih
Поддержка автора осуществляется с помощью специальной формы ниже, предоставленной сервисом «ЮMoney». Все платёжные операции выполняются на защищённой странице сервиса, что обеспечивает их корректность и полную безопасность.


