{
“title”: “Statik Dosyalar İçin Cache-Control immutable, ETag ve Last-Modified ile Versiyonlama Nasıl Kurulur?”,
“content”: “
Hiç başınıza geldi mi? Canlıya yeni bir tasarım attınız, sizde her şey harika görünüyor ama kullanıcı ‘Butonlar yamulmuş’ diye yazıyor. Ekranı yeniliyor, tarayıcıyı kapatıp açıyor, yine aynı. O an anlıyorsunuz ki kullanıcı eski CSS’e takılı kalmış. Benzer bir günü ben de yaşadım; dağıtımdan sonra renk paleti güncellenmişti, ama tarayıcılar ısrarla eskisini kullanıyordu. O akşam, statik dosyalar için Cache-Control, immutable, ETag, Last-Modified ve versiyonlama konularını masaya yatırdım.
O gün öğrendiğim şey şu oldu: Statik dosyalarda hız ve doğruluk arasında kurduğumuz denge, küçük ayarlarla bambaşka bir yere taşınıyor. Mesela şöyle düşünün, bir kere indirilen bir logoyu bir yıl aynı şekilde sunmak mümkünken, HTML gibi sık değişen içerikleri daha tetikte tutmak gerekiyor. Bu yazıda, bu dengeyi nasıl kurduğumu ve canlı sistemlerde nasıl uyguladığımı anlatacağım. Adım adım, örneklerle, gereksiz jargon olmadan ilerleyelim.
Önce tarayıcının nasıl düşündüğünü çözeceğiz, sonra ‘immutable’ dedikleri sihirli anahtarı doğru yerde nasıl kullanırız onu konuşacağız. Ardından ETag ile Last-Modified arasındaki farklara dokunacağız; son durakta da versiyonlama, yani dosya adlarına parmak izi ekleme meselesini, Nginx/Apache/S3-CloudFront ve Node.js tarafında nasıl kurarız, hepsini birlikte bağlayacağız.
İçindekiler
- 1 Tarayıcı Ne İstiyor? Hız, Netlik ve Güvence
- 2 ETag mı, Last-Modified mı? Hangisini Ne Zaman Kullanmalı?
- 3 Immutable Ne Zaman Harika, Ne Zaman Sakıncalı?
- 4 Versiyonlama (Fingerprinting): Her Şeyi Bir Dosya Adına Sığdırmak
- 5 Nginx ile Adım Adım: Hangi Dosyaya Ne Verelim?
- 6 Apache (.htaccess) ile Ayarlar: Kısa ve Net
- 7 Node.js/Express ile Başlıklar: Uygulamadan Vermek
- 8 S3, CloudFront ve CDN Dünyasında Kurulum
- 9 HTML’i Kısa Tut, Statikleri Uçur: Dağıtımın İncelikleri
- 10 Test Etmeden Güvenme: DevTools, curl ve Küçük Tüyolar
- 11 Gerçek Bir Senaryo: Kırık CSS ve Yamalı Çözümden Kalıcı Düzen
- 12 Sık Yapılan Hatalar: Kısa Bir Tur ve Çözüm Yolları
- 13 Kapanış: Hafif, Hızlı ve Güvenilir Bir Dünyaya Doğru
Tarayıcı Ne İstiyor? Hız, Netlik ve Güvence
Tarayıcıların tek derdi var: Daha önce indirdiğin dosyayı tekrar indirme. Ama kafasını karıştıran şey, ‘Bu dosya değişti mi?’ sorusu. İşte burada iki mekanizma devreye giriyor: biri süreye güvenmek, diğeri kontrol etmeyi sürdürmek. Süreye güvenmek dediğim, Cache-Control: max-age gibi bir ayarla ‘Bu dosyayı şu kadar zaman hiç kurcalama’ demek. Kontrol etmek dediğim, ‘Belki değişmiş olabilir, bir sor bakayım’ diyerek tarayıcının sunucuya ‘Değişti mi?’ diye yoklama yapması.
Süre ayarladığınızda işler hızlanıyor, çünkü tarayıcı dosyayı diskten ya da RAM’den çekiyor. Ama bir sorun var: O süre boyunca dosya değişirse, eski görünümle yaşamak zorunda kalıyorsunuz. Burada immutable devreye giriyor. Sözün özü, tarayıcıya ‘Bu dosya değişmeyecek, hiç sorma bile’ diyorsunuz. Bu cesur cümleyi sadece gerçekten değişmeyecek dosyalara söyleyebiliriz. Peki hangi dosyalar değişmez? Versiyonlanmış olanlar.
Kontrol etmeyi seçtiğinizde ise ETag ve Last-Modified yardıma koşuyor. Tarayıcı ‘Bende şu etiketli sürüm var, aynısıysa boşuna göndermeyelim’ diye haber yolluyor. Sunucu ‘Aynı, 304 Not Modified’ diyerek yanıtlıyor ve ağdan veri indirilmeden iş çözülüyor. Bu da şık bir yöntem, ama her istekte minik de olsa bir tur sunucuya uğrama maliyeti var. Özetle, tarayıcıya doğru yerde doğru sözleri söylemek, sayfayı hem hızlı hem güncel tutuyor.
ETag mı, Last-Modified mı? Hangisini Ne Zaman Kullanmalı?
ETag, dosyanın bir tür kimlik kartı gibi. İçerik değişti mi, ETag de değişiyor. Tarayıcı ‘If-None-Match’ başlığıyla sunucuya ‘Bende şu etiket var’ diyor. Sunucu da ‘Aynı’ derse 304 dönüyor, ‘Değişti’ derse yeni içeriği gönderiyor. Last-Modified ise dosyanın son değişim tarihine güveniyor. Tarayıcı ‘If-Modified-Since’ diyerek ‘Şu tarihten sonra değişti mi?’ diye soruyor. Yani biri içerik temelli, diğeri zaman temelli düşünüyor.
Gerçek hayatta ben şöyle yapıyorum: Versiyonlanmamış ama nadiren değişen dosyalarda kısa bir max-age verip ETag veya Last-Modified ile kontrolü açık bırakıyorum. Örneğin yönetim panelinde kullanılan bir ikon seti aylardır aynıysa, tarayıcı sık sık indirmesin, ama arada değişirse de fark etsin. Versiyonlanmış dosyalarda ise ETag ile uğraşmıyorum; çünkü dosya adı zaten değişiyor ve tarayıcı yeni dosyayı yeni adından tanıyor. Bu durumda uzun bir max-age ve immutable şahane çalışıyor.
Mevzu çok sunuculu ortamlara geldiğinde ETag bazen sürpriz yapabiliyor. Farklı makineler farklı ETag üretirse, yük dengeleyici hangi makineye denk gelirse gelsin tarayıcıyı gereksiz yere ‘değişti’ diye düşündürebilir. Bu yüzden, ya ETag’ı devre dışı bırakıp Last-Modified’la devam ediyorum ya da ETag’ı içerik karmasıyla stabil hale getiriyorum. Basit tutmak çoğu zaman daha huzurlu bir uyku getiriyor.
Immutable Ne Zaman Harika, Ne Zaman Sakıncalı?
immutable direktifi, tarayıcıya çok net bir söz verdiriyor: Süre dolana kadar tekrar sorma. Bu direktifi seviyorum, çünkü işe yaradığı yerde harikalar yaratıyor. Örneğin dosya adı hash içeriyor ve değişmeyecekse, immutable ile uzun bir max-age birlikte verdiğimde, sayfa ikinci ziyarette resmen uçuyor.
Ama her güzel şey gibi, yanlış yerde kullanırsanız ters teper. HTML dokümanına immutable verirseniz, kullanıcınız yeni deploy’u günlerce görmeyebilir. Aynı şekilde versiyonlanmamış bir CSS dosyasında immutable riskli, çünkü ufak bir düzeltme yaptığınızda tarayıcı onu asla sormayabilir. Kural basit: Dosya adı değiştiğinde içeriğin de değiştiğinden emin misiniz? Evetse immutable, hayırsa kontrollü bir strateji daha mantıklı.
Bu arada immutable modern tarayıcılar tarafından iyi destekleniyor. Yine de davranışların ayrıntılarını okumak isterseniz, Cache-Control başlığının MDN sayfasındaki açıklamalar kafayı sakinleştiriyor. Bazı CDN’ler de buna özel iyileştirmeler yapıyor; mesela Cache-Control immutable desteğini anlatan Cloudflare yazısı pratik örneklerle hoş bir kaynak.
Versiyonlama (Fingerprinting): Her Şeyi Bir Dosya Adına Sığdırmak
Versiyonlamayı ilk kez düzgün kurduğum projede, sanki trafik yarı yarıya azalmış gibi hissettim. Çünkü tarayıcılar gerçekten aynı isimli dosyayı bir kez indirip bir daha hiç sormuyordu. Mantık basit: app.css yerine app.abc123.css gibi bir ad kullanıyorsunuz. İçerik değiştiğinde bu ‘abc123’ de değişiyor. Böylece tarayıcı yeni dosyanın farklı olduğunu, adından anlıyor.
Bunu üretmek için özel bir şey yapmanıza gerek yok, çoğu modern araç zaten destekliyor. Webpack, Vite, Rollup, Parcel, Laravel Mix benzeri toplayıcılar çıktı dosyalarının adına content hash eklemeyi birkaç ayar satırıyla hallediyor. Statik site üreticileri de aynı yolu izliyor. Sunucu tarafında tek yapmanız gereken, bu dosyalar için uzun bir max-age ve immutable vermek. HTML tarafı ise her deploy’da güncelleniyor, yeni dosya adlarına işaret ediyor.
Ben HTML’ye kısa bir max-age, hatta çoğunlukla sadece no-cache veriyorum. Böylece HTML her ziyarette kontrol ediliyor ama statik dosyalar uzun süre saklanıyor. Bir kez doğru bağ kuruldu mu, dağıtım derdi azalıyor. CDN kullanıyorsanız, versiyonlanmış dosyaları neredeyse hiçbir zaman purge etmeye gerek kalmıyor. Sadece HTML ve API yanıtlarıyla ilgileniyorsunuz.
Nginx ile Adım Adım: Hangi Dosyaya Ne Verelim?
Nginx konfigürasyonu için basit bir çatı
Genelde iki kural yazıyorum: Versiyonlanmış dosyalara uzun ömür ve immutable, versiyonlanmamışlara kısa ömür ve doğrulama. Basit bir örnek paylaşayım:
# Versiyonlanmış dosyalar: app.abc123.css, vendor.9f8e7.js gibi
location ~* \.(?:css|js|mjs|json|map|png|jpg|jpeg|gif|webp|avif|svg|ico|woff2?)$ {
if ($uri ~* "\.[0-9a-f]{8,}\.") {
add_header Cache-Control 'public, max-age=31536000, immutable';
etag off; # ETag'a gerek yok, dosya adı zaten değişiyor
expires 1y; # Bazı araçlar expires'tan hoşlanıyor, ikisini birlikte vermek sorun değil
}
}
# Versiyonlanmamış statikler: admin.css gibi
location ~* \.(?:css|js|png|jpg|jpeg|gif|svg|ico|woff2?)$ {
add_header Cache-Control 'public, max-age=300';
etag on; # Kısa ömür + doğrulama
expires 5m;
}
# HTML ve JSON sayfaları
location ~* \.(?:html)$ {
add_header Cache-Control 'no-cache';
etag on;
expires -1;
}
Ben dosya adındaki hash’i düzenli ifadeyle yakalıyorum. Uygulamanıza göre desen değişebilir. Bazı ekipler query string versiyonlama (örneğin style.css?v=123) kullanıyor. Tarayıcılar bunu da anlıyor, ama tecrübem şu: dosya adını değiştirmek hem CDN’lerle hem log analiziyle daha pürüzsüz çalışıyor.
HTTP/2, Brotli ve diğer tatlı eklemeler
İş önbellekten ibaret değil tabii. Sıkıştırma ve protokol de büyük fark yaratıyor. Nginx üzerinde modern şifreler ve Brotli’yi kurcalamak isterseniz, bizim şu rehberdeki notlarımdan epey fayda görmüştüm: Nginx’te TLS 1.3, OCSP Stapling ve Brotli Nasıl Kurulur?. Uçtan uca küçük dokunuşlar birleşince sayfa hissedilir derecede hızlanıyor.
Apache (.htaccess) ile Ayarlar: Kısa ve Net
Apache kullananlarda iş çoğu zaman .htaccess ile çözülüyor. Mod_headers ve mod_expires etkinse şu tarz bir kurulum temiz bir başlangıç yapıyor:
<IfModule mod_headers.c>
<FilesMatch '\.(css|js|mjs|png|jpg|jpeg|gif|webp|avif|svg|ico|woff2?)$'>
Header set Cache-Control 'public, max-age=300'
</FilesMatch>
<FilesMatch '\.[0-9a-f]{8,}\.(css|js|mjs|png|jpg|jpeg|gif|webp|avif|svg|ico|woff2?)$'>
Header set Cache-Control 'public, max-age=31536000, immutable'
</FilesMatch>
<FilesMatch '\.(html)$'>
Header set Cache-Control 'no-cache'
</FilesMatch>
</IfModule>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/html 'access plus 0 seconds'
ExpiresByType text/css 'access plus 5 minutes'
ExpiresByType application/javascript 'access plus 5 minutes'
</IfModule>
Apache tarafında ETag varsayılan olarak açık gelebilir. Çok sunuculu yapıda gereksiz şaşkınlık yaratıyorsa kapatmak isteyebilirsiniz. Küçük bir not: Bazı CDN’ler ETag’ı olduğu gibi taşıyor, bazıları görmezden geliyor. Davranışı test ederek karar vermek en doğrusu.
Node.js/Express ile Başlıklar: Uygulamadan Vermek
Statik dosyaları Express ile sunuyorsanız, doğru başlıkları uygulama katmanında da verebilirsiniz. Ben sık sık aşağıdaki gibi bir kurgu kuruyorum: hash’li dosyalara uzun ömür, diğerlerine temkinli yaklaşım.
const express = require('express');
const app = express();
app.use((req, res, next) => {
if (/\.[0-9a-f]{8,}\.(css|js|mjs|png|jpg|jpeg|gif|webp|avif|svg|ico|woff2?)$/i.test(req.url)) {
res.set('Cache-Control', 'public, max-age=31536000, immutable');
}
next();
});
app.use(express.static('public', {
etag: true, // Versiyonlanmamışlar için işimize yarar
lastModified: true, // Ek bir güvence
maxAge: '5m', // Genel bir varsayılan
setHeaders: (res, path) => {
if (path.endsWith('.html')) {
res.set('Cache-Control', 'no-cache');
}
}
}));
app.listen(3000);
Deploy düzeniniz Express üzerinden dönüyorsa, sıfır kesinti stratejisi ayrı bir mutluluk getiriyor. Bu konuda adım adım pratikleri toparladığım şu yazıyı sıcak bir çay eşliğinde okumanızı öneririm: Node.js’i canlıya alırken panik yapmadan sıfır kesinti deploy kurmak. Statik dosya versiyonlama ve cache ayarları, böyle bir dağıtımın yanında en iyi arkadaş olur.
S3, CloudFront ve CDN Dünyasında Kurulum
Objeleri S3 üzerinde tutuyor, önüne CloudFront veya benzeri bir CDN koyuyorsanız, oyunun kuralları aynı ama ayarların yeri değişik. S3 objesine yüklerken Cache-Control başlığını doğru verin: versiyonlanmış dosyalar için ‘public, max-age=31536000, immutable’ candır. Versiyonlanmamışlar için daha kısa bir max-age yazın, hatta kontrollü davranmak için no-cache bile mantıklı olabilir.
CloudFront tarafında cache policy seçerken ‘Origin Cache-Control’ başlığını dikkate al diyin ki, S3’e yazdığınız değerler boşa gitmesin. HTML’yi kısa tutarsanız, yeni deploy’larda kullanıcılarınız güncel içeriği hemen görür. CDN’lerde en güzel şeylerden biri de şu: versiyonlu dosyalarda purge’e neredeyse hiç gerek kalmıyor. Çünkü isim değiştiği için yeni nesne, yeni bir anahtar olarak geliyor.
WordPress gibi sistemlerde medya dosyalarını S3’e taşıyıp CDN üzerinden servis etmeyi konuştuğumuz yazıda, bu başlık ayarlarının canlı örneklerini paylaşmıştım: WordPress medyayı S3’e taşımak ve CDN tarafında akıllı önbellek geçersizleştirme. Medya dosyalarında da aynı mantık geçerli: değişmeyecekse uzun ömür, değişecekse kontrollü yaklaşım.
HTML’i Kısa Tut, Statikleri Uçur: Dağıtımın İncelikleri
İşin inceliği genelde HTML’de saklı. Çünkü o sayfa, hangi CSS ve JS’nin çağrılacağını belirliyor. Ben deploy sırasında atomik sürüm yaklaşımını seviyorum: yeni sürüm bir klasörde hazırlanır, referanslar hash’li dosyalara güncellenir, en sonda bir sembolik bağlantı ya da küçük bir config değişikliğiyle trafik yeni sürüme döner. Bu akışta, statikler zaten yeni adlarıyla geldiği için herhangi bir purge’e ihtiyaç kalmıyor.
Bu tarz bir kurgu için sıfır kesinti dağıtımı anlattığım rehber de hoşunuza gidebilir: VPS’e sıfır kesinti CI/CD kurmak. Versiyonlama ve cache başlıklarıyla birlikte düşününce, dağıtım sonrası ‘Bende eski CSS kaldı’ mesajlarının yerini, ‘Site nasıl da hızlanmış’ yorumları alıyor.
Görüntü tarafında da aynı prensip işliyor. Görselleri farklı formatlarda (AVIF/WebP) üretip uygun Cache-Control ile servis ettiğinizde, hem hız hem fatura dengeli gidiyor. Bu hattı kurgularken not aldıklarımı şurada uzun uzadıya yazmıştım: Görüntü optimizasyonu boru hattı ve akıllı cache-key. Oradaki ‘cache-key’ fikri, burada anlattığımız versiyonlama düşüncesiyle çok iyi anlaşıyor.
Test Etmeden Güvenme: DevTools, curl ve Küçük Tüyolar
Her şey bitti sanırken, tarayıcıların aslında kafasına göre davrandığını görüp şaşırdığım çok oldu. O yüzden test, test, test. Chrome DevTools’un Network sekmesinde her isteğin Response Headers kısmına bakın. Cache-Control, ETag/Last-Modified ne gelmiş, 200 mü 304 mü, hepsini görün. Özellikle ‘from disk cache’ ya da ‘memory cache’ ibareleri çok şey anlatıyor.
Terminalde de bir iki komut alışkanlık yapınca hız kazandırıyor. Mesela:
curl -I 'https://site.com/assets/app.abc123.css'
curl -H 'If-None-Match: "xyz"' -I 'https://site.com/assets/app.css'
curl -H 'Cache-Control: no-cache' -I 'https://site.com/index.html'
İlk komutta dosyanın cache başlığını görürsünüz. İkincide sunucunun ETag doğrulamasına nasıl yanıt verdiğini anlarsınız. Üçüncüde ise istemcinin ‘bana yeni sürümü kontrol et’ baskısı yarattığını görürsünüz. Küçük bir uyarı: Çok sunuculu yapıda, ETag değerinin makineye göre değişmediğinden emin olun ya da tamamen kapatın. Alternatif olarak sadece Last-Modified bırakmak, çoğu durumda zihni serin tutuyor.
Daha derli toplu anlatım ararsanız, ETag başlığının MDN sayfası sade bir özet sunuyor. Oradaki örnekleri kendinize göre uyarlayıp test etmek, ‘Tamamdır’ demeden önce güzel bir güvence oluyor.
Gerçek Bir Senaryo: Kırık CSS ve Yamalı Çözümden Kalıcı Düzen
Bir projede başta versiyonlama yoktu. CSS dosyasına orta uzunlukta bir max-age verip, yanına ETag eklemiştik. İlk haftalar her şey yolunda gözüktü. Sonra canlıda küçük bir tasarım değişikliği yaptık ve beklenmeyen bir ısrarla, bazı kullanıcılar eski stilde kaldı. ETag aslında doğru çalışıyordu, ama ara katmanda duran bir CDN, doğrulama başlıklarını farklı yönettiği için bazı istekler gereksiz yere taşınmıştı. Kısa vadeli çözüm olarak purge yaptık, ama bunun sürdürülebilir olmadığını o gün anladık.
Kalıcı çözümü şöyle kurduk: Build hattına content hash ekledik, tüm linkleri hash’li dosyalara çevirdik, bu dosyalar için ‘public, max-age=31536000, immutable’ verdik, HTML’yi ise no-cache yaptık. Bir sonraki deploy’dan sonra, benzer sorunlar kayboldu. Artık bir şey değiştiğinde dosya adı da değişiyor, tarayıcılar yeni adresi görüyor ve hiç tereddüt etmeden indiriyordu. Eski dosyalar CD’de kalsa da sorun yoktu, çünkü yeni istekler eskilere uğramıyordu.
Bu arada dağıtımı panik yapmadan, filtre kahveyi soğutmadan yapmak için süreçleri de toparladık. Geliştirme–staging–canlı yolculuğunu sıfır kesinti odağıyla anlatan rehberde bu tarafın iskeletini konuşmuştuk. Özetle, küçük ve güvenilir adımlar sonraki haftaları huzurlu kılıyor.
Sık Yapılan Hatalar: Kısa Bir Tur ve Çözüm Yolları
İlk hata genelde şu oluyor: Versiyonlanmamış bir dosyaya uzun bir max-age ve immutable veriliyor. Sonra değişiklik yapılıyor, ama kullanıcılar ısrarla eski sürümü görüyor. Çözüm basit: Ya versiyonlayın ya da kısa bir ömür verin ve doğrulamayı açık bırakın. İkinci hata, HTML’ye uzun ömür vermek. HTML, yeni referansların kapısı; kısa tutmak güven verir.
Üçüncü tuzakta ETag çok sunuculu ortamda baş ağrıtıyor. Eğer her makine farklı ETag üretirse, sırayla 304 yerine 200’ler görürsünüz. Ya ETag’ı devredışı bırakın ya da ETag’ı içerik karmasıyla sabitleyin. Dördüncü noktada da CDN’lere gereğinden fazla purge atılıyor. Versiyonlama varsa, çoğu zaman purge’e gerek yok. Sadece HTML’yi tazelemek çoğu senaryoda yeter.
Kapanış: Hafif, Hızlı ve Güvenilir Bir Dünyaya Doğru
Toparlayalım. Statik dosyalarda hayal ettiğimiz hız, aslında birkaç sağduyulu kuralın birleşimi. Versiyonlama ile dosya adlarına güven, Cache-Control ile tarayıcının davranışını yönlendir, immutable ile gereksiz kontrolleri kaldır, ETag/Last-Modified ile temkinli yerlerde emin adımlarla ilerle. Üstüne dağıtım sürecini küçük ve temiz adımlara böldüğünüzde, hem ekip huzuru artıyor hem kullanıcılar kendini iyi hissediyor.
Pratik bir başlangıç için bugün şunları yapın: Build aracınızda content hash üretmeyi açın, Nginx/Apache’de hash’li dosyaları yakalayan bir kural yazın, HTML için no-cache verin, testleri DevTools ve curl ile doğrulayın. CDN kullanıyorsanız, origin’deki Cache-Control’ü saygıyla taşıdığından emin olun. Küçük bir kontrol listesiyle başladığınızda, bir hafta içinde sayfanın nefes aldığını hissedeceksiniz.
Umarım bu yazı kafanızdaki düğümleri gevşetmiştir. Sorularınız olursa not alın, birlikte kurcalarız. Bir dahaki yazıda, bu ayarların performans ölçümünü ve gerçek trafik altında neleri değiştirdiğini konuşalım. Şimdilik, statik dosyalarınızın keyfi yerinde olsun.
“,
“focus_keyword”: “Cache-Control immutable”,
“meta_description”: “Statik dosyalarda Cache-Control immutable, ETag ve Last-Modified ayarlarını; versiyonlama ve Nginx/Apache yapılandırmalarını örneklerle kolayca öğrenin.”,
“faqs”: [
{
“question”: “Immutable ne zaman kullanılmalı?”,
“answer”: “Dosya adı içerik değiştiğinde değişiyorsa, yani fingerprinting (app.abc123.css) yapıyorsanız immutable harika çalışır. HTML gibi sık değişen içeriklerde kullanmayın.”
},
{
“question”: “ETag mi Last-Modified mı seçmeliyim?”,
“answer”: “Versiyonlama yoksa ve kısa bir ömür veriyorsanız ikisi de iş görür. Çok sunuculu yapıda ETag sorun çıkarıyorsa Last-Modified daha pratik olur. Versiyonlu dosyalarda genelde ikisine de gerek kalmaz.”
},
{
“question”: “Query string ile mi, dosya adıyla mı versiyonlamalıyım?”,
“answer”: “Her ikisi de çalışır ama dosya adını değiştirmek (app.abc123.css) CDN ve loglama tarafında daha temiz olur. Değişiklikte yeni dosya adı, tarayıcıya net bir işaret verir.”
}
]
}
