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

Digital-студия WNDER

Что такое кеширование и зачем оно нужно

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

Представьте, что вы готовите борщ. Вместо того чтобы каждый день резать овощи и варить бульон, вы один раз варите кастрюлю и потом просто разогреваете порцию. Кеш работает так же: один раз посчитали — много раз использовали.

Yii2 поддерживает несколько видов кеша: фрагментный, данных, запросов, схемы БД. Каждый решает свою задачу. Главное — не переусердствовать, иначе можно получить устаревшие данные.

Настройка компонента кеша

По умолчанию в Yii2 уже есть компонент cache, который использует файловый кеш. Для небольших проектов этого достаточно, но для высоких нагрузок лучше взять что-то посерьёзнее, например, Memcached или Redis.

Настройка в конфиге config/web.php:

'components' => [
    'cache' => [
        'class' => 'yii\caching\MemCache',
        'servers' => [
            [
                'host' => 'localhost',
                'port' => 11211,
                'weight' => 100,
            ],
        ],
    ],
],

Если не хотите ставить дополнительный софт, можно оставить файловый кеш, но указать отдельную папку для него:

'cache' => [
    'class' => 'yii\caching\FileCache',
    'cachePath' => '@runtime/cache',
],

После настройки можно пользоваться кешем через Yii::$app->cache.

Основные методы работы с кешем

У компонента кеша есть простой набор методов. Вот самые популярные:

Метод Что делает
get($key) Возвращает значение по ключу или false, если нет
set($key, $value, $duration) Сохраняет значение с временем жизни
add($key, $value, $duration) Сохраняет, только если ключа ещё нет
delete($key) Удаляет значение
flush() Очищает весь кеш

Пример использования:

$key = 'my_data_' . $id;
$data = Yii::$app->cache->get($key);
if ($data === false) {
    $data = $this->heavyCalculation($id);
    Yii::$app->cache->set($key, $data, 3600); // кеш на час
}
return $data;
Правило: всегда проверяйте, что вернул get(). Если false — значит, кеша нет, и нужно сгенерировать данные заново.

Кеширование фрагментов и страниц

В Yii2 есть удобные виджеты для кеширования частей представления. Например, если у вас есть блок «Популярные товары», который редко меняется, его можно закешировать на 10 минут.

beginCache('popular_products', ['duration' => 600])): ?>
    
endCache(); endif; ?>

А можно закешировать всю страницу целиком, если она одинакова для всех пользователей. Для этого в контроллере используйте фильтр PageCache:

public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\PageCache',
            'duration' => 3600,
            'only' => ['index', 'view'],
            'dependency' => [
                'class' => 'yii\caching\DbDependency',
                'sql' => 'SELECT MAX(updated_at) FROM product',
            ],
        ],
    ];
}

Здесь мы говорим: кешируй страницы index и view на час, но если в таблице product обновилась запись — сбрось кеш.

Кеширование запросов к базе данных

Самый жирный плюс — кеширование результатов SQL-запросов. Если у вас есть тяжёлый запрос с джойнами, который выполняется секунду, его можно закешировать.

$query = new \yii\db\Query();
$query->select(['id', 'name'])
    ->from('user')
    ->where(['status' => 1])
    ->cache(3600); // кеш на час

$users = $query->all();

Или через createCommand:

$users = Yii::$app->db->createCommand('SELECT * FROM user WHERE status = 1')
    ->cache(3600)
    ->queryAll();

Важно: если данные в таблице обновляются, кеш нужно сбрасывать. Можно использовать зависимости, как в примере с PageCache.

Лайфхак: для часто обновляемых данных используйте короткий срок кеширования (например, 60 секунд). Это снизит нагрузку, но данные будут почти всегда актуальны.

Продвинутые техники: зависимости и теги

Yii2 позволяет задавать зависимости кеша. Например, кеш зависит от файла или от значения в БД. Если зависимость меняется — кеш автоматически сбрасывается.

$dependency = new \yii\caching\DbDependency([
    'sql' => 'SELECT COUNT(*) FROM product'
]);

Yii::$app->cache->set('product_count', $count, 3600, $dependency);

Также можно использовать теги для групповой очистки. Например, помечаем все кеши, связанные с товарами, тегом 'products'. При обновлении любого товара удаляем все кеши с этим тегом.

Yii::$app->cache->set('product_1', $data, 3600, new \yii\caching\TagDependency(['tags' => ['products']]));
// при обновлении товара:
\yii\caching\TagDependency::invalidate(Yii::$app->cache, ['products']);

Это очень удобно, когда нужно сбросить кеш сразу для нескольких ключей.

Что в итоге

Кеширование в Yii2 — это не серебряная пуля, но мощный инструмент. Начните с малого: закешируйте тяжёлые запросы и фрагменты страниц. Постепенно внедряйте зависимости и теги. Следите за актуальностью данных: если кеш устарел, пользователи увидят неправильную информацию.

Помните: кеш должен ускорять, а не усложнять. Не кешируйте всё подряд, особенно если данные меняются каждую секунду. И всегда тестируйте приложение после внедрения кеша — иногда он может привести к неожиданным багам.

Удачи в оптимизации! Пусть ваши страницы грузятся быстрее, чем вы успеете моргнуть.

Студия WNDER