Скорость загрузки сайта — это как скорость подачи в ресторане. Если официант бегает туда-сюда с каждой тарелкой отдельно, посетители заскучают. В Yii2 за подачу ресурсов отвечает AssetBundle. Если вы до сих пор подключаете CSS и JS вручную в каждом представлении, эта статья для вас.

Digital-студия WNDER

Что такое AssetBundle и зачем он нужен

AssetBundle — это контейнер для файлов ресурсов: стилей, скриптов, картинок. Вместо того чтобы в каждом шаблоне писать <link> и <script>, вы описываете один класс, который знает, какие файлы подключить и в каком порядке. Yii2 сам решает, когда их выводить.

Представьте, что у вас есть два блока: библиотека jQuery и ваш собственный скрипт, который от неё зависит. Без AssetBundle вы можете случайно подключить скрипт раньше jQuery — и всё сломается. С бандлами Yii2 выстраивает зависимости автоматически. Это как умный официант, который приносит блюда в правильной последовательности.

Кроме того, AssetBundle умеет публиковать ресурсы из недоступных веб-директорий (например, из vendor) в публичную папку. Это избавляет от необходимости копировать файлы вручную.

Как создать свой AssetBundle

Создадим бандл для условного сайта. Допустим, у нас есть папка assets с файлами style.css и app.js, а также мы хотим подключить Bootstrap из CDN.

<?php
namespace app\assets;

use yii\web\AssetBundle;

class AppAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = [
        'css/style.css',
    ];
    public $js = [
        'js/app.js',
    ];
    public $depends = [
        'yii\web\YiiAsset',
        'yii\bootstrap\BootstrapAsset',
    ];
}

Здесь basePath указывает на физическую папку, а baseUrl — на веб-адрес. В css и js перечисляются файлы относительно этих путей. Массив depends говорит: «Сначала подключи YiiAsset (jQuery) и Bootstrap, а потом мои файлы».

Теперь в представлении достаточно вызвать:

<?php
use app\assets\AppAsset;
AppAsset::register($this);
?>

Yii2 сам добавит все необходимые теги в нужном порядке. Если вы подключите этот бандл дважды, он не продублируется.

Оптимизация: кэширование и сжатие

AssetBundle не только управляет порядком, но и помогает оптимизировать загрузку. Основные приёмы — объединение файлов и сжатие. Yii2 умеет автоматически публиковать ресурсы и генерировать уникальные имена для кэша.

Чтобы включить сжатие и объединение, настройте компонент assetManager в конфиге приложения:

'components' => [
    'assetManager' => [
        'bundles' => [
            'app\assets\AppAsset' => [
                'jsOptions' => ['position' => \yii\web\View::POS_HEAD],
            ],
        ],
        'linkAssets' => true, // создавать символические ссылки вместо копирования
        'appendTimestamp' => true, // добавлять метку времени к URL
    ],
],

Параметр appendTimestamp добавляет к ссылкам ?v=123456, чтобы браузер не кэшировал старые версии после обновления. linkAssets создаёт симлинки, экономя место на диске.

Для сжатия CSS и JS можно использовать сторонние инструменты, но Yii2 из коробки не сжимает содержимое. Однако вы можете подключить минифицированные версии файлов вручную или через конвертер.

Правило: Всегда указывайте зависимости в $depends. Это избавит от ошибок «jQuery is not defined» и подобных.

Тонкая настройка: позиция, условия, группировка

Иногда нужно, чтобы скрипт подключался в определённом месте страницы. Например, в <head> или перед </body>. Для этого в бандле можно указать jsOptions:

public $jsOptions = ['position' => \yii\web\View::POS_HEAD];

По умолчанию скрипты подключаются в конце <body> (POS_END). Это хорошо для производительности, но не всегда удобно.

Если нужно подключить ресурсы только для определённых браузеров, используйте cssOptions с условиями:

public $cssOptions = ['condition' => 'lt IE 9'];

Этот код обернёт ссылку в условный комментарий для IE.

Для группировки нескольких бандлов можно использовать yii\web\AssetBundle::register с массивом. Но чаще достаточно зависимостей.

Практические советы и лайфхаки

  • Не дублируйте ресурсы. Если два бандла подключают jQuery, Yii2 сам разрулит — но лучше указать зависимость только в одном месте.
  • Используйте CDN. Для популярных библиотек (jQuery, Bootstrap) можно указать sourcePath = null и прописать внешние URL в css/js. Это ускорит загрузку за счёт кэша браузера.
  • Включайте appendTimestamp в продакшене. Это гарантирует, что пользователи увидят свежие стили после обновления.
  • Разделяйте бандлы по страницам. Не пихайте всё в один файл — подключайте только то, что нужно на конкретной странице.

Вот пример бандла с CDN-ресурсами:

<?php
namespace app\assets;

use yii\web\AssetBundle;

class CdnAsset extends AssetBundle
{
    public $basePath = null;
    public $baseUrl = null;
    public $css = [
        'https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css',
    ];
    public $js = [
        'https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js',
    ];
    public $depends = [];
}

Обратите внимание: при использовании CDN basePath и baseUrl должны быть null, а пути — полными URL.

Лайфхак: Чтобы быстро проверить, какие бандлы зарегистрированы на странице, используйте отладочную панель Yii2. Она покажет список всех активов и их зависимости.

Что в итоге

AssetBundle — мощный инструмент, который избавляет от ручного подключения ресурсов и автоматизирует порядок загрузки. Вы описываете зависимости один раз, а Yii2 делает всё остальное. Это экономит время, уменьшает количество ошибок и ускоряет сайт.

Главное — не ленитесь настраивать assetManager и указывать зависимости. Тогда ваши стили и скрипты будут загружаться быстро и в правильном порядке.

Студия WNDER