I think Spatie's response cache package should be used on more pages. The speed improvement is impressive, and even on highly dynamic pages, data is read more often than it is written or changed - a lot of room for improvement.
On static pages, the package should be a real no-brainer. When using it with dynamic content, like with my favorite CMS Statamic (❤️), there is this dreaded, scary thing called cache invalidation. When and how should we clear the cache when content changes? The saying goes:
Only 2 things in development are hard:
Naming things, cache invalidation and off-by-one errors
Luckily I found a really simple way of integrating it!
Enough Talk
To keep this post short for change, let me get right to it:
Of course, you need to have a working version of Statamic installed. In your project, also install the response cache package by running
composer require spatie/laravel-responsecache
After that, you need to add the middleware to your web group to apply the cache to all your (GET) routes. See the docs for more information and options.
// app/Http/Kernel.php
...
protected $middlewareGroups = [
'web' => [
...
\Spatie\ResponseCache\Middlewares\CacheResponse::class,
],
Now here is the kicker: To clear the cache everytime something is updated in the Statamic backend, you need to create a new Event Subscriber that clears the cache after a "something happened in Statamic" event. Create and place the following file wherever you want:
// app/Subscribers/ResponseCacheStatamicSubscriber
<?php
namespace App\Subscribers;
use Spatie\ResponseCache\Facades\ResponseCache;
use Statamic\Events\Concerns\ListensForContentEvents;
class ResponseCacheStatamicSubscriber
{
use ListensForContentEvents;
/**
* Register the listeners for the subscriber.
*
* @param \Illuminate\Events\Dispatcher $events
*/
public function subscribe($events)
{
foreach ($this->events as $event) {
$events->listen($event, self::class.'@clear');
}
}
/**
* Commit changes.
*
* @param mixed $event
*/
public function clear()
{
if (config('responsecache.enabled')) {
ResponseCache::clear();
}
}
}
The whole magic here is happening in the trait Statamic\Events\Concerns\ListensForContentEvents
where the Statamic team keeps all the Events neat and tidy for you need to listen for.
Then simply add this subscriber to the EventServiceProvider
and you are already done! Your cache is cleared and rebuild on every update, but most users will get a lightning fast response 👍
//App\Providers\AppServiceProvider
use App\Subscribers\ResponseCacheBuster;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Statamic\Git\Subscriber;
class EventServiceProvider extends ServiceProvider
{
// ...
protected $subscribe = [
ResponseCacheStatamicSubscriber::class
];
// ...
}
During Development
Just a quick note because I tend to forget this way to often: Remember to add a line to your local .env
file that you do not want to use the response cache there.
# .env
...
RESPONSE_CACHE_ENABLED=false
...
Why though?
You may ask "why the hassle, Statamic already comes with a pretty good cache". You are right, and in essence this approach should yield quite similar results like the Application Driver approach of the build in Statamic cache.
I found a little speed improvement using Spatie's library though, but this could be because I mostly create Statamic sites with Blade instead of using Antlers, the Statamic templating engine.
If you use this or not, I just wanted to share what I learned 🎉
Best! Simon
How to test static pages automatically in Laravel
I developed a way to automatically crawl and test big parts of your Laravel application.
With just one line of code, you can now write a "peace of mind" test that gives you a lot of confidence.
Your Tool is not the Problem - Your Workflow is
A few (meta) thoughts on the search for the best project management tool.
Usually, the chaos you'll find in a software is a quite accuarate representation of your teams' communication skills - and also a big chance for improvement.