Skip to content

Instantly share code, notes, and snippets.

@ThijsFeryn
Last active May 9, 2022 12:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ThijsFeryn/7ef386908f3230ef694c53d12eec5afa to your computer and use it in GitHub Desktop.
Save ThijsFeryn/7ef386908f3230ef694c53d12eec5afa to your computer and use it in GitHub Desktop.
The various Laravel snippets I used in my Laracon EU 2022 Amsterdam presentation on how to improve the cacheability of Laravel projects. I'd like to see this end up in a larger caching or edge package and I'd like some of the code to be optimized.
<?php
//An ESI service provider that defines a custom @esi(/header) directive that can be used to render ESI tags
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Blade;
class EsiServiceProvider extends ServiceProvider
{
/**
* @return void
*/
public function boot(): void
{
Blade::directive('esi', function (string $url) {
if(str_contains($this->app->request->headers->get('Surrogate-Capability'), 'ESI/1.0')) {
return "<?php echo '<esi:include src=\"$url\" />'; ?>";
} else {
return "<?php echo subrequest('GET','$url')->getContent(); ?>";
}
});
}
}
<?php
//Middleware that matches the If-None-Match value to a cached ETag and exists quickly with a 304 Not Modified status
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Closure;
use Symfony\Component\HttpFoundation\Response;
class NotModified
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
if (!$request->isMethodCacheable()) {
return $next($request);
}
$etag = Cache::get('etag:'.md5($request->getUri()));
$cacheControl = Cache::get('etag-cache-control:'.md5($request->getUri()));
$response = new Response('',304,['ETag' => $etag, 'Cache-Control' => $cacheControl]);
if($response->isNotModified(($request))) {
return $response;
}
$response = $next($request);
Cache::put('etag:'.md5($request->getUri()), $response->headers->get('ETag'),10);
Cache::put('etag-cache-control:'.md5($request->getUri()),$response->headers->get('Cache-Control'),10);
return $response;
}
}
<?php
//Middleware that sets a Surrogate-Controler header if the proper Surrogate-Capability is sent by the client
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Closure;
class Surrogate
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
$response = $next($request);
if(str_contains($request->headers->get('Surrogate-Capability'), 'ESI/1.0')) {
$response->headers->set('Surrogate-Control', 'content="ESI/1.0"');
}
return $response;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment