#19 Laravel基礎

キャッシュでパフォーマンスを改善する

キャッシュとは

キャッシュ? 一度計算した結果を一時保存して再利用する仕組み。毎回DBに問い合わせる代わりにキャッシュから返すことで処理を速くできる。 は、一度計算した結果を一時的に保存しておいて、同じリクエストが来たときにDBに問い合わせずに保存済みの結果を返す仕組みです。


キャッシュドライバーの設定

# 📁 .env

CACHE_DRIVER=file   # file(デフォルト), redis, memcached, database, array

開発中は file で十分です。本番では redis が高速でよく使われます。


基本の使い方

cache()->remember() — あれば使い、なければ生成して保存

// 📁 app/Http/Controllers/PostController.php

use Illuminate\Support\Facades\Cache;

public function index()
{
    // 'latest_posts' というキーでキャッシュ。なければクロージャーを実行して保存
    $posts = Cache::remember('latest_posts', now()->addMinutes(10), function () {
        return Post::with('user')->published()->latest()->take(20)->get();
    });

    return view('posts.index', compact('posts'));
}

第2引数は「何秒後に期限切れにするか」を表します。now()->addMinutes(10) なら10分です。


forever — 期限なし

// 期限なしでキャッシュ(明示的にクリアするまで残る)
$categories = Cache::forever('categories', function () {
    return Category::all();
});

ただし forever を使うと古いデータが残り続けるため、データが変わるときに手動でキャッシュを削除する必要があります。


キャッシュを削除する

// 特定のキーを削除
Cache::forget('latest_posts');

// 全キャッシュをクリア
Cache::flush();

オブザーバーと組み合わせて「投稿が変わったらキャッシュを削除」するパターンがよく使われます。

// 📁 app/Observers/PostObserver.php

public function saved(Post $post): void
{
    Cache::forget('latest_posts');
}

public function deleted(Post $post): void
{
    Cache::forget('latest_posts');
}

ユーザーごとにキャッシュを分ける

キーにユーザーIDを含めることでユーザーごとに異なるデータをキャッシュできます。

$userId = auth()->id();
$key = "user:{$userId}:dashboard";

$data = Cache::remember($key, now()->addMinutes(5), function () use ($userId) {
    return [
        'posts'    => Post::where('user_id', $userId)->count(),
        'comments' => Comment::where('user_id', $userId)->count(),
    ];
});

その他の操作

// 値があるかどうか確認
Cache::has('latest_posts'); // true / false

// 値を取得(なければデフォルト値)
$value = Cache::get('key', 'デフォルト値');

// 値を保存(put)
Cache::put('key', $value, now()->addHour());

// 取得して削除(1回だけ使うデータ)
$value = Cache::pull('key');

// 数値をインクリメント・デクリメント
Cache::increment('page_views');       // +1
Cache::increment('page_views', 5);    // +5
Cache::decrement('stock');            // -1

rememberForever の代わりにタグを使う(Redis限定)

Redisを使っている場合はキャッシュタグでまとめてクリアできます。

// タグ付きでキャッシュ保存
Cache::tags(['posts', 'homepage'])->put('featured', $posts, 3600);

// posts タグが付いたものを全部削除
Cache::tags('posts')->flush();

まとめ

  • Cache::remember(キー, 時間, クロージャー) が最も基本的な使い方
  • キャッシュの時間は now()->addMinutes() や整数(秒数)で指定できる
  • データが変わったら Cache::forget() でキャッシュを削除する
  • オブザーバーのイベントと組み合わせるとキャッシュ管理が自動化できる

次回はMailableを使ったメール送信を学びます。