Загрузка…
Загрузка…
HTTP / REST · middle · сложность 6
Кэш HTTP — баланс между скоростью и свежестью: long max-age на hashed assets, no-cache + ETag на HTML, stale-while-revalidate для мягкого обновления.
# ❌ The classic mistake: long max-age on a STABLE url (index.html).
# Users are now stuck on an old app for a year with no way to bust it.
Cache-Control: public, max-age=31536000
# GET /index.html
# ✅ HTML: always revalidate, pay only a 304 when unchanged.
Cache-Control: no-cache
ETag: "v9-8f3c1a"
# GET /index.html → If-None-Match: "v9-8f3c1a" → 304 Not Modified
# ✅ Hashed asset: the URL changes on every deploy, so cache immutably.
Cache-Control: public, max-age=31536000, immutable
# GET /static/app.a1b2c3.js
# ✅ Serve-stale-while-refreshing: instant response, fresh next time.
Cache-Control: max-age=60, stale-while-revalidate=600// Server-side ETag revalidation in ~5 lines.
app.get('/api/profile', (req, res) => {
const body = getProfile(req.userId);
const etag = `"${hash(body)}"`; // strong validator from content
res.set('Cache-Control', 'private, no-cache'); // browser-only, always revalidate
res.set('ETag', etag);
if (req.headers['if-none-match'] === etag) return res.status(304).end(); // no body
res.json(body);
});Long max-age на stable URL (index.html) — footgun: пользователи застревают на старой версии. Hashed URL + immutable — safe. ETag даёт cheap 304 без полного body. private, no-cache для per-user API.
HTML revalidate, static hashed — long cache; ETag для conditional GET; не ставьте year-long max-age на URL без content hash.