Ускоряем Symfony2 за счет ленивого подключения бандлов

в 5:02, , рубрики: php, symfony, symfony2, метки: ,

В данной статье речь пойдет о том, как можно ускорить веб приложения, основанные на популярном фреймворке для PHP — Symfony2, за счет ленивого подключения бандлов. Для примера будет использоваться ленивое подключение SonataAdminBundle (ускорение работы сайта составляет около 30%).

Кому интересно — прошу под кат.

Думаю многие, кто работал с Symfony2 сталкивался с необходимостью создавать админ-панель. Также, многие наверняка слышали про SonataAdminBundle. Этот бандл позволяет быстро поднять админку, основанную на стандартных действиях для сущностей — CRUD (Create, Read, Update, Delete).

Однако SonataAdminBundle обладает и существенным недостатком — нужно дополнительно поставить еще пяток бандлов. В результате, это отражается на работе всех остальных страниц сайта. Но ведь если подумать — нам нужно грузить все эти бандлы только при работе с админкой. Иными словами, только тогда, когда пользователь запрашивает страницы вида /admin/*. А для всех остальных страниц — нам не нужно ни подгружать эти модули, ни их конфиги, и даже роутинг не нужен (если конечно у вас нет ссылок на разделы админки в других частях сайта).

Собственно давайте воспользуемся этой информацией. Идея заключается в том, чтобы создать дополнительное окружение (в дополение к стандартным env, prod и test), в котором подключать необходимые бандлы и конфиги для работы админки (именно это окружение будет использоваться при открытии страниц /admin/*, а для всех остальных будет использоваться prod окружение).
Нам потребуется всего несколько шагов:

  1. Создаем файл app/config_admin.yml примерно такого содержания:
    imports:
        - { resource: config_prod.yml }
        - { resource: admin.yml } # В этом файле описаны все настройки для работы sonata admin bundle
    
    framework:
        router:
            resource: "%kernel.root_dir%/config/routing_admin.yml"
    

  2. Создаем файл app/routing_admin.yml, в котором будут прописаны все роуты для админки
    _main:
        resource: routing.yml
    

  3. Поскольку в dev окружении нам также нужна админка — добавлеяем в config_dev.yml импорт конфига admin.yml
    imports:
        # Остальные импорты
        - { resource: admin.yml }
    

    а в routing_dev.yml добавляем

    _main_admin:
        resource: routing_admin.yml
    

  4. В файле app/AppKernel.php подключать бандлы для работы админки только в dev и admin окружениях:
    public function registerBundles()
        {
            $bundles = array(
                ...
            );
    
    
            if (in_array($this->getEnvironment(), array('dev', 'admin'))) {
                $bundles[] = new KnpBundleMenuBundleKnpMenuBundle();
                $bundles[] = new ShopomioAdminBundleAdminBundle();
                $bundles[] = new SonataBlockBundleSonataBlockBundle();
                $bundles[] = new SonatajQueryBundleSonatajQueryBundle();
                $bundles[] = new SonataAdminBundleSonataAdminBundle();
                $bundles[] = new SonataDoctrineORMAdminBundleSonataDoctrineORMAdminBundle();
            }
    
            return $bundles;
        }
    

  5. Последний шаг — модифицировать app.php
    Вместо

    $kernel = new AppKernel($env, false);
    

    написать

    $env = strpos($_SERVER['REQUEST_URI'], '/admin') === 0 ? 'admin' : 'prod';
    $kernel = new AppKernel($env, false);
    

Таким образом, на продакшене, при заходе на /admin/* будет подключаться admin окружение, а на всех остальных страницах — prod окружение. Такой подход позволил мне ускорить существующий сайт с SonataAdminBundle на 30% при минимальном количестве изменений.

Заключение

За счет добавления дополнительных окружений, и минимализации количества подключаемых бандлов можно существенно увеличить скорость работы сайта, основанного на Symfony2 фреймворке.

Пишите в комментариях замечания, предложения и другие интересные решения для ускорения Symfony2, а об ошибках (синтаксических, лексических и т.п.) — пишите в личку.

Автор: Sirian

Источник


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js