Через заголовки Cache-Control і ETag - тоді браузер чи CDN не звертаються до застосунку або отримують коротку відповідь «не змінилося».
Route::middleware('cache.headers:public;max_age=3600;etag')->group(function () {
Route::get('/privacy', PrivacyController::class);
Route::get('/sitemap.xml', SitemapController::class);
});
Що означають директиви:
public- відповідь можна зберігати в спільних кешах (CDN, проксі);private- лише в браузері;max_age/s_maxage- скільки секунд вважати свіжою;s_maxage- лише для спільних кешів, зручно дати CDN довший термін, ніж браузеру;etag- Laravel рахує хеш тіла відповіді. Якщо браузер надіслав той самийIf-None-Match, відповідь буде304 Not Modifiedбез тіла.
Чого ETag не дає: застосунок усе одно виконує весь запит і рендеринг - економиться лише трафік. Справжня економія серверу - коли CDN віддає відповідь сам за max_age.
Головна небезпека - персоналізовані сторінки. Якщо сторінку з ім'ям користувача чи CSRF-токеном позначити public, CDN віддасть її наступному відвідувачу. Тому:
publicлише для сторінок, однакових для всіх;- сесійні cookie у відповіді зазвичай роблять її некешованою для CDN, і це правильно;
- для авторизованих -
private, no-store.
Статичні ассети з хешем у назві (Vite) кешують на рік з immutable - ім'я зміниться разом зі вмістом.