Dokumentacja
Zapisuj pliki w pamięci podręcznej przeglądarki
Zapisuj pliki w pamięci podręcznej przeglądarki
Każda podstrona ładuje te same arkusze stylów, skrypty, logotypy i czcionki. Bez nagłówka pamięci podręcznej przeglądarka pobiera je ponownie przy każdej wizycie i przy każdym kliknięciu w kolejną podstronę: więcej żądań, wolniejsze strony dla powracających odwiedzających i większy ruch na Twoim serwerze. Nagłówek Cache-Control mówi przeglądarce, że może zachować plik i użyć go ponownie bez pytania.
Lista kontrolna strony sprawdza do sześciu własnych plików ładowanych przez stronę główną (CSS, JavaScript i obrazy z tego samego adresu co strona) i oczekuje, że każdy będzie w pamięci podręcznej co najmniej 7 dni.
Co się liczy jako pamięć podręczna
| Nagłówek pliku | Wynik |
|---|---|
Cache-Control: public, max-age=31536000, immutable |
OK, najlepiej dla plików z hashem w nazwie |
Cache-Control: max-age=2592000 (30 dni) |
OK |
Cache-Control: max-age=604800 (7 dni) |
OK, minimum |
data Expires co najmniej 7 dni do przodu, bez max-age |
OK |
Cache-Control: max-age=3600 albo brak nagłówka |
za krótko |
Cache-Control: no-cache lub no-store |
brak pamięci podręcznej, niezależnie od reszty nagłówka |
Plików z innych domen (Google Fonts, CDN ze skryptami, sieć reklamowa) nie sprawdzamy: nie możesz zmienić ich nagłówków. Osobna subdomena, np. static.example.com, też liczy się jako inny adres.
Jak długo jest bezpiecznie, zależy od nazwy pliku:
- Nazwy z hashem (fingerprint), np.
app-3f2a9c1d.csslub/_next/static/…, zmieniają się przy każdej zmianie treści. Zapisuj je na rok zimmutable; nowa wersja to nowy plik. - Nazwy z wersją w parametrze, np.
style.css?ver=6.6.2(WordPress dodaje to do każdego rejestrowanego arkusza stylów i skryptu), dostają nowy adres, gdy zmienia się wersja motywu lub wtyczki. Miesiąc lub dłużej jest w porządku, o ile wersja naprawdę zmienia się razem z plikiem. - Zwykłe nazwy, np.
/css/style.css, po edycji mają ten sam adres. Przy długim czasie powracający odwiedzający zostają ze starym plikiem. Użyj tu 7 dni i, gdy możesz, dodaj do nazwy wersję lub hash. - Obrazy i czcionki rzadko zmieniają się pod tą samą nazwą. Od 30 dni do roku to norma.
Sprawdź sam
Wypisz pliki ładowane przez stronę główną, a potem sprawdź nagłówki jednego z nich. Zamiast example.com i ścieżki wpisz swoje:
curl -s https://example.com | grep -oE '(href|src)="[^"]+\.(css|js|png|jpe?g|webp|svg|woff2?)[^"]*"' | head -20
curl -sI https://example.com/wp-content/themes/example/style.css | grep -iE '^(cache-control|expires):'
Naprawione oznacza, że cache-control pokazuje max-age=604800 lub więcej (albo immutable), bez no-cache ani no-store. Jeśli drugie polecenie nic nie wypisuje, plik w ogóle nie ma nagłówka pamięci podręcznej.
Jak to naprawić
Nagłówki pamięci podręcznej ustawia to, co serwuje pliki: serwer WWW, panel hostingu, CDN albo aplikacja. Wybierz to, do czego masz dostęp; wystarczy jedno miejsce.
WordPress
Sam WordPress nie wysyła nagłówków pamięci podręcznej dla plików. Robi to serwer, a niektóre wtyczki cache mogą je ustawić za Ciebie.
- LiteSpeed Cache (na hostingu LiteSpeed): LiteSpeed Cache → Cache → Browser, włącz Browser Cache i zostaw domyślny TTL (rok). Zapisz, potem Purge All.
- WP Rocket na Apache i LiteSpeed sam dodaje reguły pamięci podręcznej przeglądarki do
.htaccess. Nie ma na to przełącznika. Na nginx nie może zapisać reguł serwera: zobacz zakładkę nginx albo zapytaj hosting.
Bez tych wtyczek dodaj reguły do .htaccess z zakładki Apache i LiteSpeed. WordPress dodaje ?ver= do rejestrowanych plików CSS i JavaScript, więc miesiąc jest dla nich bezpieczny. Jeśli edytujesz CSS motywu ręcznie, nie zmieniając wersji motywu, odwiedzający mogą widzieć stary plik tak długo, jak trwa pamięć podręczna: po takich zmianach podnieś Version: w pliku style.css motywu.
cPanel
cPanel nie ma przełącznika pamięci podręcznej przeglądarki. Reguły trafiają do pliku .htaccess w katalogu głównym strony:
- Otwórz Files → File Manager i przejdź do
public_html(albo katalogu domeny dodatkowej). - W prawym górnym rogu kliknij Settings, zaznacz Show Hidden Files (dotfiles) i zapisz.
- Prawy klik na
.htaccess→ Edit, wklej na końcu blok z zakładki Apache i LiteSpeed i zapisz.
Na hostingu LiteSpeed z WordPressem te same reguły może zapisać za Ciebie wtyczka LiteSpeed Cache (zakładka WordPress).
Plesk
W Plesku nginx zwykle stoi przed Apache i sam serwuje pliki statyczne, więc reguła należy do nginx. Przejdź do Websites & Domains → example.com → Apache & nginx Settings i w Additional nginx directives dodaj:
location ~* \.(?:css|js|mjs|png|jpe?g|gif|svg|webp|avif|ico|woff2?)$ {
expires 30d;
}
Kliknij OK; Plesk sprawdzi składnię i przeładuje nginx.
Jeśli Plesk zgłosi zduplikowany location, definiuje go już opcja Serve static files directly by nginx. Wtedy wyłącz tę opcję i zamiast tego użyj reguł .htaccess z zakładki Apache i LiteSpeed.
nginx
Dodaj reguły w bloku server { … } strony: na Debianie i Ubuntu w /etc/nginx/sites-available/example.com, na Rocky, Alma i CentOS w /etc/nginx/conf.d/example.com.conf.
# Wynik builda z hashem w nazwie (Vite, webpack): nowa wersja to nowy plik.
location /build/ {
add_header Cache-Control "public, max-age=31536000, immutable";
}
# Wszystko inne o zwykłych nazwach.
location ~* \.(?:css|js|mjs)$ {
expires 7d;
}
location ~* \.(?:png|jpe?g|gif|svg|webp|avif|ico|woff2?)$ {
expires 30d;
}
expires wysyła zarówno Cache-Control: max-age=…, jak i Expires. Zamień /build/ na katalog, do którego zapisuje Twoje narzędzie do budowania.
Ostrzeżenie:
add_headerwewnątrzlocationzastępuje dla tych plików wszystkieadd_headerz blokuserver, także nagłówki bezpieczeństwa, takie jak HSTS. Jeśli ustawiasz nagłówki wserver, powtórz je też w tymlocation.
Przetestuj i zastosuj:
sudo nginx -t && sudo systemctl reload nginx
Apache i LiteSpeed
mod_expires ustawia zarówno Cache-Control: max-age, jak i Expires. Umieść to w .htaccess w katalogu głównym strony albo, na własnym serwerze, w wirtualnym hoście. LiteSpeed odczytuje to tak samo.
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/avif "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresByType font/woff2 "access plus 1 year"
</IfModule>
Jeśli Twoje pliki CSS i JavaScript mają zwykłe nazwy bez wersji, w tych dwóch liniach użyj "access plus 1 week".
Plikom z hashem w nazwie możesz dodać immutable przez mod_headers, na przykład w .htaccess wewnątrz katalogu builda:
<IfModule mod_headers.c>
Header set Cache-Control "public, max-age=31536000, immutable"
</IfModule>
Na własnym serwerze włącz moduły i przeładuj (na Rocky, Alma i CentOS oba są domyślnie włączone; zamiast apache2 użyj httpd):
sudo a2enmod expires headers
sudo apachectl configtest && sudo systemctl reload apache2
Cloudflare
Jeśli strona działa za Cloudflare (pomarańczowa chmurka), Cloudflare może wydłużyć czas pamięci podręcznej przeglądarki dla plików, które cache'uje (domyślnie CSS, JavaScript, obrazy i czcionki):
- Otwórz domenę i przejdź do Caching → Configuration.
- W Browser Cache TTL domyślna opcja Respect Existing Headers przekazuje to, co wysyła Twój serwer. Zamiast niej wybierz wartość, np. 1 month.
Z ustawioną wartością Cloudflare używa jej, gdy serwer wysyła krótszy czas albo żaden; dłuższy max-age z Twojego serwera nadal wygrywa. Dla różnych czasów w różnych katalogach użyj Rules → Cache Rules i ustaw w regule Browser TTL.
Node.js i Next.js
Next.js w produkcji już serwuje /_next/static/… z public, max-age=31536000, immutable. Pliki w public/ dostają max-age=0, więc obrazy i czcionki stamtąd nie są zapisywane. Ustaw dla nich nagłówek w next.config.js:
module.exports = {
async headers() {
return [
{
source: '/images/:path*',
headers: [{ key: 'Cache-Control', value: 'public, max-age=2592000' }],
},
];
},
};
Express z express.static:
// Wynik builda z hashem w nazwie: rok, immutable.
app.use('/assets', express.static('dist/assets', { maxAge: '1y', immutable: true }));
// Zwykłe nazwy: tydzień.
app.use(express.static('public', { maxAge: '7d' }));
Jeśli pliki przed aplikacją serwuje nginx, ustaw nagłówki tam (zakładka nginx).
Laravel
Vite (npm run build) zapisuje pliki z hashem w nazwie do public/build/assets, np. app-3f2a9c1d.css, a @vite je linkuje. Można je bezpiecznie zapisywać na rok. Laravel nie serwuje tych plików: robi to serwer WWW, więc nagłówek ustawia się tam.
- nginx (Forge, Ploi, własny serwer): dodaj blok
location /build/z zakładki nginx do konfiguracji strony. - Apache: domyślny
public/.htaccessnie ma reguł pamięci podręcznej. Dodaj blokmod_expiresz zakładki Apache i LiteSpeed oraz regułęimmutablew.htaccesswewnątrzpublic/build.
Obrazy i inne pliki umieszczone bezpośrednio w public/ zachowują swoje nazwy. 30 dni to dla nich dobra wartość.
IIS i ASP.NET
W pliku web.config strony:
<configuration>
<system.webServer>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00" />
</staticContent>
</system.webServer>
</configuration>
30.00:00:00 to 30 dni. Dla katalogu z plikami z hashem w nazwie umieść w nim web.config z 365.00:00:00. W ASP.NET Core ustaw nagłówek w UseStaticFiles przez StaticFileOptions.OnPrepareResponse.
Platformy hostowane
Shopify, Wix, Squarespace i Webflow serwują pliki motywów i obrazy z własnego CDN z własnymi nagłówkami pamięci podręcznej, zwykle z innej domeny, której lista kontrolna nie sprawdza. Jeśli oznaczony jest tam plik z Twojej domeny, kontroluje go platforma i po Twojej stronie nie ma nic do zmiany.
Po zmianie
- Wyczyść cache CDN lub strony po zmianie nagłówków. Kopia w pamięci podręcznej zachowuje stare nagłówki, dopóki nie wygaśnie.
- Zmiany w plikach o zwykłych nazwach pozostają niewidoczne dla powracających odwiedzających, dopóki ich pamięć podręczna nie wygaśnie. Przed dużym redesignem nadaj CSS nową nazwę lub wersję, zamiast skracać czas pamięci podręcznej.
Potwierdź poprawkę
Uruchom ponownie polecenia curl z sekcji Sprawdź sam, potem otwórz cel w PulseKeeper i kliknij Sprawdź teraz na zakładce Lista kontrolna. Pozycja zmieni się na OK w ciągu kilku minut, a nie dopiero przy kolejnym codziennym sprawdzeniu.