Урок 17: Оптимизация в Symfony. Профилирование, Doctrine, кэширование, OPcache

На 17-ом уроке мы разберем одну из важных тем для любого Symfony-разработчика, это оптимизацию приложений. Даже самый функциональный проект будет провальным, если он медленный. Пользователи не станут ждать, пока ваша страница загрузится за 5-10 секунд. Оптимизация является обязательным этапом разработки. В этом уроке я расскажу о ключевых инструментах Symfony и PHP, которые помогут вашему приложению «летать».

Профилирование с Symfony Profiler

Symfony Profiler ваш лучший друг в поиске узких мест производительности. Он встроен в Symfony и предоставляет детальную информацию о каждом запросе: время выполнения, потребление памяти, SQL-запросы, шаблоны и многое другое.

Как это работает?

  1. Активация Profiler. В dev-среде Profiler включен по умолчанию. Откройте любую страницу вашего приложения и внизу экрана появится панель с метриками.
  2. Анализ данных:
    • Время выполнения (Timeline). Показывает, сколько времени заняли разные этапы обработки запроса.
    • Запросы к БД. Отображает все SQL-запросы, их время выполнения и стек вызовов.
    • Память. Потребление памяти на каждом этапе.
  3. Пример проблемы. Допустим на странице выполняется 50 SQL-запросов. Это явный признак проблемы N+1 (о ней поговорим дальше). Profiler поможет быстро найти такие места.

Практическая задача

  1. Откройте любой контроллер вашего проекта.
  2. Добавьте код, который вызывает несколько запросов к БД (например, выборку сущностей в цикле).
  3. Запустите страницу и найдите в Profiler вкладку Doctrine. Посчитайте количество запросов.
  4. Постарайтесь сократить их, объединив в один запрос с помощью JOIN.

Оптимизация Doctrine-запросов

Doctrine мощный ORM, но без правильной настройки он может стать источником проблем. Разберем основные подходы.

1. Проблема N+1

При ленивой загрузке (lazy loading) связанных сущностей Doctrine выполняет отдельный запрос для каждой связи. Например:

php
// Плохой пример: 1 запрос для постов + N запросов для комментариев
$posts = $entityManager->getRepository(Post::class)->findAll();
foreach ($posts as $post) {
    echo count($post->getComments()); // Запрос выполняется здесь!
}

Решение: Используйте жадную загрузку (eager loading) через JOIN:

php
// Хороший пример: 1 запрос с JOIN
$posts = $entityManager->createQueryBuilder()
    ->select('p', 'c')
    ->from(Post::class, 'p')
    ->leftJoin('p.comments', 'c')
    ->getQuery()
    ->getResult();

2. Пакетная обработка (Batch Processing)

Если вы работаете с большими объемами данных, используйте iterate() для экономии памяти:

php
$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 добавьте:

yaml
doctrine:
    orm:
        entity_managers:
            default:
                query_cache_driver: apcu
                metadata_cache_driver: apcu
                result_cache_driver: apcu

Практическая задача

  1. Найдите в вашем проекте циклы с обращением к связанным сущностям.
  2. Перепишите запросы, используя JOIN.
  3. Проверьте в Profiler, сколько запросов теперь выполняется.

Кэширование конфигурации

Symfony компилирует конфигурацию (роуты, сервисы, параметры) в PHP-классы. По умолчанию в dev-среде кэш обновляется при каждом изменении, но в prod-режиме кэш статичен.

Как включить кэширование?

  1. Для production:
    Кэш включен автоматически. Чтобы обновить его, выполните:

    bash
    php bin/console cache:clear --env=prod
  2. Для разработки (не рекомендуется, но иногда полезно):
    В .env установите:

    APP_DEBUG=0

Без кэша:

Время загрузки страницы: 800 мс

С кэшем:

Время загрузки страницы: 200 мс

Практическая задача

  1. Запустите проект в prod-режиме:
    bash
    composer install --no-dev
    php bin/console cache:clear --env=prod
  2. Замерьте скорость загрузки страницы с помощью инструментов браузера (например, Chrome DevTools).

Использование OPcache

OPcache встроенный в PHP механизм кэширования опкода (скомпилированного PHP-кода). Это критически важно для ускорения Symfony.

Настройка OPcache

В php.ini:

ini
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0 # Для production!

Проверка статуса

Создайте файл phpinfo.php:

php
<?php phpinfo();

Откройте его в браузере и найдите раздел OPcache.

Практическая задача

  1. Проверьте, активен ли OPcache в вашем окружении.
  2. Если нет, то настройте его и замерьте производительность до/после.

Итоги 17-го урока

Оптимизация это постоянный процесс. используйте Symfony Profiler для поиска узких мест, оптимизируйте запросы Doctrine, не забывайте о кэшировании и OPcache.

Полный курс с уроками по Symfony для начинающих доступен здесь: https://max-gabov.ru/symphony-dlya-nachinaushih

Поделиться статьей:
Поддержать автора блога

Поддержка автора осуществляется с помощью специальной формы ниже, предоставленной сервисом «ЮMoney». Все платёжные операции выполняются на защищённой странице сервиса, что обеспечивает их корректность и полную безопасность.

Персональные рекомендации
Оставить комментарий