← Назад к статьям
Производительность и базы данных

Кэширование — это не роскошь, а необходимость. Как и зачем использовать его в Laravel

Практическое руководство по кэшированию в Laravel: от кэширования тяжёлых запросов и целых страниц до умной инвалидации с тегами и атомарных блокировок против cache stampede.

Доступные языки
Кэширование — это не роскошь, а необходимость. Как и зачем использовать его в Laravel
Рекомендуемая статья ↗

Кэширование — это не роскошь, а необходимость. Как и зачем использовать его в Laravel

Введение: медленное приложение теряет пользователей

Сколько раз вы закрывали сайт или приложение, потому что оно «загружалось»? В современном цифровом мире скорость — это не просто удобство; это ожидание пользователя и ключевой фактор для SEO, конверсии и удержания пользователей.

Один из самых эффективных способов ускорить ваше веб-приложение — кэширование. Проще говоря, кэширование — это сохранение результатов дорогостоящих операций (запросов к базе данных, сложных вычислений, вызовов API) во временном, но быстром хранилище (например, в оперативной памяти). Когда те же данные запрашиваются снова, они отдаются оттуда, экономя время и ресурсы.

Сегодня я покажу вам, насколько простым и элегантным может быть кэширование в Laravel — фреймворке, который превращает эту задачу из рутины в удовольствие.

1. Почему Laravel? Потому что кэширование здесь — полноценный гражданин

Laravel предоставляет единый, элегантный API для работы с различными системами кэширования прямо из коробки: Redis, Memcached, файлы и даже базы данных. Вы пишете один и тот же код, а драйвер можно изменить одной строкой в конфиге (config/cache.php). Вот она — сила абстракции!

// Конфигурация драйвера кэша (например, в .env) CACHE_DRIVER=redis // или memcached, file, database

2. Практика: от простого к сложному. Реальные примеры

Пример 1: Кэширование результатов тяжёлого запроса

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

Без кэша:

public function index() { $products = Product::with('category', 'reviews') ->where('is_active', true) ->withCount('orders') ->orderBy('orders_count', 'desc') ->take(20) ->get(); // Запрос выполняется каждый раз! return view('home', compact('products')); }

С кэшем (на 60 минут):

use Illuminate\Support\Facades\Cache; public function index() { $products = Cache::remember('homepage.popular_products', 60, function () { return Product::with('category', 'reviews') ->where('is_active', true) ->withCount('orders') ->orderBy('orders_count', 'desc') ->take(20) ->get(); }); return view('home', compact('products')); }

Что это даёт? После первого запроса данные сохраняются в Redis на час. 10 000 посетителей? База данных получит всего 1 запрос в час вместо 10 000. Нагрузка на базу данных и время отклика снижаются кардинально.

Пример 2: Кэширование целой страницы (Page Caching)

Если страница статична для всех пользователей (например, «Условия обслуживания»), вы можете кэшировать весь отрендеренный вывод.

// В ваших маршрутах (web.php) Route::get('/terms', function () { return Cache::rememberForever('page.terms', function () { return view('pages.terms')->render(); // Отрендерить один раз и сохранить HTML }); });

rememberForever() идеально подходит для этого. Только не забудьте очистить кэш, когда контент обновится!

Пример 3: «Умная» инвалидация кэша при изменении данных (теги и события модели)

Самая сложная часть кэширования — инвалидировать его в нужный момент. Laravel решает это с помощью тегов (поддерживаются драйверами вроде Redis) и событий модели.

Сценарий: Мы кэшируем список статей блога. Кэш должен обновляться, когда:

  • Добавлена новая статья.
  • Статья обновлена или удалена.
  • Автор статьи изменён (если это влияет на отображение).
// В модели Article protected static function booted() { // При любом сохранении или удалении сбрасываем кэшированную коллекцию static::saved(function () { Cache::forget('articles.all'); }); static::deleted(function () { Cache::forget('articles.all'); }); } // В контроллере public function index() { $articles = Cache::remember('articles.all', 120, function () { return Article::with('author')->latest()->get(); }); return view('articles.index', compact('articles')); }

Более продвинутый способ — использование тегов:

// Сохранение с тегами $articles = Cache::tags(['articles', 'authors'])->remember('key', 3600, function () { return Article::with('author')->get(); }); // Сброс ВСЕХ данных с тегом 'articles' (например, когда любая статья меняется) Cache::tags(['articles'])->flush();

Пример 4: Атомарные блокировки для предотвращения cache stampede

Что, если два пользователя одновременно запрашивают данные, отсутствующие в кэше, и оба процесса запускают тяжёлую операцию? Laravel позволяет «заблокировать» операцию.

use Illuminate\Support\Facades\Cache; public function getReportData($userId) { $lock = Cache::lock('report.lock.' . $userId, 10); // Блокировка на 10 секунд if ($lock->get()) { // Тяжёлая генерация отчёта... $report = generateComplexReport($userId); Cache::put('report.' . $userId, $report, 300); $lock->release(); // Освобождаем блокировку return $report; } // Ждём, пока другой процесс сгенерирует отчёт return Cache::get('report.' . $userId); }

3. Ключевые принципы, которые стоит запомнить

  1. Кэшируйте «дорогие» операции: Запросы с GROUP BY, JOIN, проблемами N+1, вызовы внешних API.
  2. Планируйте стратегию инвалидации: Устаревший кэш часто хуже, чем отсутствие кэша. Используйте события модели, теги или ручную очистку через Artisan (php artisan cache:clear).
  3. Выбирайте правильный драйвер: Redis для продакшена, файл для локальной разработки.
  4. Не кэшируйте всё подряд: Персонализированные данные (например, «Мой профиль») сложнее кэшировать эффективно. Начните с самых тяжёлых, самых публичных частей вашего приложения.

Заключение

Кэширование в Laravel — это не магия; это мощный, хорошо продуманный инструмент, доступный каждому разработчику. Правильная реализация может снизить нагрузку на сервер на порядки и создать по-настоящему быстрый пользовательский опыт.

Начните с одного метода. Измерьте производительность до и после. Результаты вас удивят!

Технологии и темы

Теги статьи

Нет статей, соответствующих этим фильтрам.

Есть проект или идея для обсуждения?

Давайте обсудим ↗