CDN'de asset sürümleme: hash'leme ve cache stratejisini nasıl kurarım?
Soru
DeployerPHP ile yeni kodu canlıya alınca kullanıcının tarayıcısındaki eski CSS/JS yüzünden arayüz kırılıyor. `mix.js?id=123` gibi query string'i bazı CDN'ler göz ardı ediyor, eski sürümü servis etmeye devam ediyor. Kalıcı çözüm için asset adlarını hash'leyip (`app.a8f9b2.js`) `Cache-Control: max-age=31536000` ile CDN'e göndermek istiyorum. CI/CD'de derleme ve invalidate otomasyonunu nasıl tasarlarım?
Cevap
Kısa cevap: Query-string ile cache busting güvenilmez; kalıcı çözüm content-hash’li dosya adı (app.a8f9b2.js) — ad sadece içerik değişince değişir, gerisini cache stratejisi halleder.
Sorunun kökü şu: app.js?id=123 desende dosya adı hep aynı. Bazı CDN’ler query string’i cache key’inden atar ya da yok sayar, dolayısıyla id değişse de cache’teki ESKİ dosyayı servis etmeye devam eder. Cache key’ini değiştirmen gerekiyor — query’yi değil, adı.
- Content-hash’li dosya adı kullan.
app.a8f9b2.jsgibi; hash dosyanın içeriğinden türer. İçerik değişince ad değişir, değişmediyse aynı kalır. Böylece her asset’i sonsuza kadarCache-Control: public, max-age=31536000, immutableile cache’leyebilirsin —immutabledirektifi tarayıcıya “bunu bir daha doğrulama bile” der, gereksiz koşullu istekleri keser. - Uzun cache’lenMEYECEK tek dosya: HTML/giriş noktası. Hash’li asset’lere işaret eden HTML’i (veya manifest’i referanslayan entrypoint’i) kısa ömürlü ya da
no-cacheyap. Mantık basit: HTML her zaman taze gelsin ki YENİ hash’lere işaret etsin; asset’ler ise hash sayesinde zaten doğru sürümü taşır. Burayı uzun cache’lersen tüm zincir kilitlenir. - CI/CD: önce yükle, sonra canlıya geç. Vite manifest’i ile hash’li çıktı üret. Sıra kritik: asset’leri CDN’e/bucket’a uygulamayı canlıya almadan ÖNCE yükle. Yoksa yeni HTML henüz yüklenmemiş bir hash’e işaret eder ve 404 alırsın. DeployerPHP akışında bunu “symlink’i çevirmeden önce upload” adımı olarak kur.
- Önceki sürümün asset’lerini bir süre tut. Deploy anında sayfası açık olan kullanıcı hâlâ eski HTML’i çalıştırıyor ve eski hash’leri ister. Bir önceki release’in asset’lerini silmezsen bu “in-flight” kullanıcılar kırılmaz. DeployerPHP’nin
keep_releasesmantığı zaten sana bunu verir.
Sonuç: Ben olsam content-hash’li, immutable cache’li asset + kısa ömürlü HTML + canlıya-geçmeden-önce-upload üçlüsünü kurardım. Gerçek content hashing’de pratikte asset purge’üne neredeyse hiç ihtiyacın olmaz — ad değiştiği için eski dosya zaten dokunulmadan kalır, kimse onu istemez. Tek invalidate etmen gereken şey HTML’dir, o da zaten kısa cache’li. Query-string busting’i tamamen bırak.
Yorumlar
Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.