laravel-responsecacheは ララベルのミドルウェアとして動作するキャッシュクラスです。 Laravelのルーティングを通る時に動作する( テンプレートファイルの更新すら確認しない)ので とても高速に動作します
composer require spatie/laravel-responsecache
php artisan vendor:publish --provider="Spatie\ResponseCache\ResponseCacheServiceProvider"
↑ このコマンドを実行すると
/config/responsecache.php ファイルが生成されます。
キャッシュをミドルウェア(アクセスのたびに自動的に呼び出されるクラス)にセットします。
既存の $routeMiddleware の一番最後に追加します。
app/Http/Kernel.php
protected $routeMiddleware = [
...
'cacheResponse' => \Spatie\ResponseCache\Middlewares\CacheResponse::class, // 追加
'doNotCacheResponse' => \Spatie\ResponseCache\Middlewares\DoNotCacheResponse::class, // 追加
];
次に routes/web.php のキャッシュを適応したいルートをこちらのミドルウェアで囲みます。
Route::group(['middleware' => 'cacheResponse'], function () {
Route::get("/", function (Request $request) {
// 何かしらの処理
});
});
以上でキャッシュは実行されています。
確認してみましょう。
.env の以下の記述があるか確認しましょう
APP_DEBUG=true
ページ描画を妨げないようにsetTimeoutで時間をずらしてfetchでキャッシュクリアのエンドポイントにアクセスします。
app/Http/Controllers/Admin/CacheController.php
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Spatie\ResponseCache\Facades\ResponseCache;
class CacheController extends Controller
{
/**
* Clear all response cache
*
* @return JsonResponse
*/
public function clear(): JsonResponse
{
try {
ResponseCache::clear();
return response()->json(['success' => true, 'message' => 'キャッシュを正常にクリアしました。']);
} catch (\Exception $e) {
return response()->json(['success' => false, 'message' => 'キャッシュのクリアに失敗しました。'], 500);
}
}
}
routes/web.php
// キャッシュクリア
Route::get('cache/clear', 'CacheController@clear')->name('cache.clear');
ビューで次のようにします。
@auth('admin')
<script>
setTimeout(() => {
fetch('{{ route("admin.cache.clear") }}')
.then(response => response.json())
.then(data => {
console.log('[Cache Clear]', data.message);
})
.catch(error => {
console.error('[Cache Clear]', 'キャッシュのクリアに失敗しました。')
});
}, 100); // 100msec後に実行
</script>
@endauth
app/ClearResponseCacheTrait.php を以下の内容で新規作成します
<?php
namespace App;
use Spatie\ResponseCache\Facades\ResponseCache;
trait ClearResponseCacheTrait
{
public static function bootClearResponseCacheTrait()
{
self::created(function () {
ResponseCache::clear();
});
self::updated(function () {
ResponseCache::clear();
});
self::deleted(function () {
ResponseCache::clear();
});
}
}
Laravelアプリで使用する全てのモデルファイルに以下のトレイトを追加します
例 : app/news.php に追加します
class News extends Model
{
// ===== Trait =====
use \App\ClearResponseCacheTrait; // キャッシュクリア(追加する)
// ===== Trait =====
これで DBにデータを「新規登録」「変更」「削除」したときにキャッシュがクリアされます。
こちらのコマンドで実際にWEBアプリのベンチマークを3回ずつとってみたところ
ab -n 100 -c 100 https://TEST-SITE.TLD/
Requests per second: 9.19 [#/sec] (mean)
Requests per second: 7.54 [#/sec] (mean)
Requests per second: 6.50 [#/sec] (mean)
↓
Requests per second: 80.19 [#/sec] (mean)
Requests per second: 73.79 [#/sec] (mean)
Requests per second: 76.89 [#/sec] (mean)
約9.9倍 速くなりました !!
開発時にこのミドルウェアが入っていると 一時的にキャッシュをオンにしたりオフにしたり する必要が出てきますそこで設定を .env ファイルに設定しておき そこで簡単に切り替えられるようにします
.env
RESPONSE_CACHE_FLAG=true
routes/web.php
// キャッシュミドルウェア( .env の RESPONSE_CACHE_FLAG が true の場合 キャッシュ on)
$cache_middleware = [];
if ( env('RESPONSE_CACHE_FLAG',false) == true ){
$cache_middleware = ['middleware' => 'cacheResponse'];
}
Route::group($cache_middleware, function () {
Route::get("/", function (Request $request) {
........... 何かしらの処理
});
});
config/responsecache.php ファイル内で lifetime_in_seconds パラメータを設定できます。デフォルトでは通常1週間(604800秒)に設定されています。 例えば、キャッシュを1日(86400秒)に設定したい場合:
**config/responsecache.php*
return [
// ...
'lifetime_in_seconds' => 86400, // 1日
// ...
];
routes/web.php
use Illuminate\Support\Facades\Route;
use Spatie\ResponseCache\Middlewares\CacheResponse;
// 特定のルートに1日のキャッシュタイムを設定
Route::get('/blog', [BlogController::class, 'index'])
->middleware(CacheResponse::class . ':86400'); // 86400秒 = 1日