{"id":1552,"date":"2025-11-08T20:39:58","date_gmt":"2025-11-08T17:39:58","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/nereden-baslamaliyiz-bir-css-dosyasinin-pesinde\/"},"modified":"2025-11-08T20:39:58","modified_gmt":"2025-11-08T17:39:58","slug":"nereden-baslamaliyiz-bir-css-dosyasinin-pesinde","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/nereden-baslamaliyiz-bir-css-dosyasinin-pesinde\/","title":{"rendered":"Nereden Ba\u015flamal\u0131y\u0131z? Bir CSS Dosyas\u0131n\u0131n Pe\u015finde"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><p>{<br \/>\n  &#8220;title&#8221;: &#8220;Statik Dosyalar \u0130\u00e7in Cache-Control immutable, ETag ve Last-Modified ile Versiyonlama Nas\u0131l Kurulur?&#8221;,<br \/>\n  &#8220;content&#8221;: &#8220;<\/p>\n<p>Hi\u00e7 ba\u015f\u0131n\u0131za geldi mi? Canl\u0131ya yeni bir tasar\u0131m att\u0131n\u0131z, sizde her \u015fey harika g\u00f6r\u00fcn\u00fcyor ama kullan\u0131c\u0131 &#8216;Butonlar yamulmu\u015f&#8217; diye yaz\u0131yor. Ekran\u0131 yeniliyor, taray\u0131c\u0131y\u0131 kapat\u0131p a\u00e7\u0131yor, yine ayn\u0131. O an anl\u0131yorsunuz ki kullan\u0131c\u0131 eski CSS&#8217;e tak\u0131l\u0131 kalm\u0131\u015f. Benzer bir g\u00fcn\u00fc ben de ya\u015fad\u0131m; da\u011f\u0131t\u0131mdan sonra renk paleti g\u00fcncellenmi\u015fti, ama taray\u0131c\u0131lar \u0131srarla eskisini kullan\u0131yordu. O ak\u015fam, statik dosyalar i\u00e7in <strong>Cache-Control<\/strong>, <strong>immutable<\/strong>, <strong>ETag<\/strong>, <strong>Last-Modified<\/strong> ve <strong>versiyonlama<\/strong> konular\u0131n\u0131 masaya yat\u0131rd\u0131m.<\/p>\n<p>O g\u00fcn \u00f6\u011frendi\u011fim \u015fey \u015fu oldu: Statik dosyalarda h\u0131z ve do\u011fruluk aras\u0131nda kurdu\u011fumuz denge, k\u00fc\u00e7\u00fck ayarlarla bamba\u015fka bir yere ta\u015f\u0131n\u0131yor. Mesela \u015f\u00f6yle d\u00fc\u015f\u00fcn\u00fcn, bir kere indirilen bir logoyu bir y\u0131l ayn\u0131 \u015fekilde sunmak m\u00fcmk\u00fcnken, HTML gibi s\u0131k de\u011fi\u015fen i\u00e7erikleri daha tetikte tutmak gerekiyor. Bu yaz\u0131da, bu dengeyi nas\u0131l kurdu\u011fumu ve canl\u0131 sistemlerde nas\u0131l uygulad\u0131\u011f\u0131m\u0131 anlataca\u011f\u0131m. Ad\u0131m ad\u0131m, \u00f6rneklerle, gereksiz jargon olmadan ilerleyelim.<\/p>\n<p>\u00d6nce taray\u0131c\u0131n\u0131n nas\u0131l d\u00fc\u015f\u00fcnd\u00fc\u011f\u00fcn\u00fc \u00e7\u00f6zece\u011fiz, sonra &#8216;immutable&#8217; dedikleri sihirli anahtar\u0131 do\u011fru yerde nas\u0131l kullan\u0131r\u0131z onu konu\u015faca\u011f\u0131z. Ard\u0131ndan ETag ile Last-Modified aras\u0131ndaki farklara dokunaca\u011f\u0131z; son durakta da versiyonlama, yani dosya adlar\u0131na parmak izi ekleme meselesini, Nginx\/Apache\/S3-CloudFront ve Node.js taraf\u0131nda nas\u0131l kurar\u0131z, hepsini birlikte ba\u011flayaca\u011f\u0131z.<\/p>\n<div id=\"toc_container\" class=\"toc_transparent no_bullets\"><p class=\"toc_title\">\u0130&ccedil;indekiler<\/p><ul class=\"toc_list\"><li><a href=\"#Tarayici_Ne_Istiyor_Hiz_Netlik_ve_Guvence\"><span class=\"toc_number toc_depth_1\">1<\/span> Taray\u0131c\u0131 Ne \u0130stiyor? H\u0131z, Netlik ve G\u00fcvence<\/a><\/li><li><a href=\"#ETag_mi_Last-Modified_mi_Hangisini_Ne_Zaman_Kullanmali\"><span class=\"toc_number toc_depth_1\">2<\/span> ETag m\u0131, Last-Modified m\u0131? Hangisini Ne Zaman Kullanmal\u0131?<\/a><\/li><li><a href=\"#Immutable_Ne_Zaman_Harika_Ne_Zaman_Sakincali\"><span class=\"toc_number toc_depth_1\">3<\/span> Immutable Ne Zaman Harika, Ne Zaman Sak\u0131ncal\u0131?<\/a><\/li><li><a href=\"#Versiyonlama_Fingerprinting_Her_Seyi_Bir_Dosya_Adina_Sigdirmak\"><span class=\"toc_number toc_depth_1\">4<\/span> Versiyonlama (Fingerprinting): Her \u015eeyi Bir Dosya Ad\u0131na S\u0131\u011fd\u0131rmak<\/a><\/li><li><a href=\"#Nginx_ile_Adim_Adim_Hangi_Dosyaya_Ne_Verelim\"><span class=\"toc_number toc_depth_1\">5<\/span> Nginx ile Ad\u0131m Ad\u0131m: Hangi Dosyaya Ne Verelim?<\/a><ul><li><a href=\"#Nginx_konfigurasyonu_icin_basit_bir_cati\"><span class=\"toc_number toc_depth_2\">5.1<\/span> Nginx konfig\u00fcrasyonu i\u00e7in basit bir \u00e7at\u0131<\/a><\/li><li><a href=\"#HTTP2_Brotli_ve_diger_tatli_eklemeler\"><span class=\"toc_number toc_depth_2\">5.2<\/span> HTTP\/2, Brotli ve di\u011fer tatl\u0131 eklemeler<\/a><\/li><\/ul><\/li><li><a href=\"#Apache_htaccess_ile_Ayarlar_Kisa_ve_Net\"><span class=\"toc_number toc_depth_1\">6<\/span> Apache (.htaccess) ile Ayarlar: K\u0131sa ve Net<\/a><\/li><li><a href=\"#NodejsExpress_ile_Basliklar_Uygulamadan_Vermek\"><span class=\"toc_number toc_depth_1\">7<\/span> Node.js\/Express ile Ba\u015fl\u0131klar: Uygulamadan Vermek<\/a><\/li><li><a href=\"#S3_CloudFront_ve_CDN_Dunyasinda_Kurulum\"><span class=\"toc_number toc_depth_1\">8<\/span> S3, CloudFront ve CDN D\u00fcnyas\u0131nda Kurulum<\/a><\/li><li><a href=\"#HTMLi_Kisa_Tut_Statikleri_Ucur_Dagitimin_Incelikleri\"><span class=\"toc_number toc_depth_1\">9<\/span> HTML\u2019i K\u0131sa Tut, Statikleri U\u00e7ur: Da\u011f\u0131t\u0131m\u0131n \u0130ncelikleri<\/a><\/li><li><a href=\"#Test_Etmeden_Guvenme_DevTools_curl_ve_Kucuk_Tuyolar\"><span class=\"toc_number toc_depth_1\">10<\/span> Test Etmeden G\u00fcvenme: DevTools, curl ve K\u00fc\u00e7\u00fck T\u00fcyolar<\/a><\/li><li><a href=\"#Gercek_Bir_Senaryo_Kirik_CSS_ve_Yamali_Cozumden_Kalici_Duzen\"><span class=\"toc_number toc_depth_1\">11<\/span> Ger\u00e7ek Bir Senaryo: K\u0131r\u0131k CSS ve Yamal\u0131 \u00c7\u00f6z\u00fcmden Kal\u0131c\u0131 D\u00fczen<\/a><\/li><li><a href=\"#Sik_Yapilan_Hatalar_Kisa_Bir_Tur_ve_Cozum_Yollari\"><span class=\"toc_number toc_depth_1\">12<\/span> S\u0131k Yap\u0131lan Hatalar: K\u0131sa Bir Tur ve \u00c7\u00f6z\u00fcm Yollar\u0131<\/a><\/li><li><a href=\"#Kapanis_Hafif_Hizli_ve_Guvenilir_Bir_Dunyaya_Dogru\"><span class=\"toc_number toc_depth_1\">13<\/span> Kapan\u0131\u015f: Hafif, H\u0131zl\u0131 ve G\u00fcvenilir Bir D\u00fcnyaya Do\u011fru<\/a><\/li><\/ul><\/div>\n<h2 id='section-2'><span id=\"Tarayici_Ne_Istiyor_Hiz_Netlik_ve_Guvence\">Taray\u0131c\u0131 Ne \u0130stiyor? H\u0131z, Netlik ve G\u00fcvence<\/span><\/h2>\n<p>Taray\u0131c\u0131lar\u0131n tek derdi var: Daha \u00f6nce indirdi\u011fin dosyay\u0131 tekrar indirme. Ama kafas\u0131n\u0131 kar\u0131\u015ft\u0131ran \u015fey, &#8216;Bu dosya de\u011fi\u015fti mi?&#8217; sorusu. \u0130\u015fte burada iki mekanizma devreye giriyor: biri s\u00fcreye g\u00fcvenmek, di\u011feri kontrol etmeyi s\u00fcrd\u00fcrmek. S\u00fcreye g\u00fcvenmek dedi\u011fim, <strong>Cache-Control: max-age<\/strong> gibi bir ayarla &#8216;Bu dosyay\u0131 \u015fu kadar zaman hi\u00e7 kurcalama&#8217; demek. Kontrol etmek dedi\u011fim, &#8216;Belki de\u011fi\u015fmi\u015f olabilir, bir sor bakay\u0131m&#8217; diyerek taray\u0131c\u0131n\u0131n sunucuya &#8216;De\u011fi\u015fti mi?&#8217; diye yoklama yapmas\u0131.<\/p>\n<p>S\u00fcre ayarlad\u0131\u011f\u0131n\u0131zda i\u015fler h\u0131zlan\u0131yor, \u00e7\u00fcnk\u00fc taray\u0131c\u0131 dosyay\u0131 diskten ya da RAM&#8217;den \u00e7ekiyor. Ama bir sorun var: O s\u00fcre boyunca dosya de\u011fi\u015firse, eski g\u00f6r\u00fcn\u00fcmle ya\u015famak zorunda kal\u0131yorsunuz. Burada <strong>immutable<\/strong> devreye giriyor. S\u00f6z\u00fcn \u00f6z\u00fc, taray\u0131c\u0131ya &#8216;Bu dosya de\u011fi\u015fmeyecek, hi\u00e7 sorma bile&#8217; diyorsunuz. Bu cesur c\u00fcmleyi sadece ger\u00e7ekten de\u011fi\u015fmeyecek dosyalara s\u00f6yleyebiliriz. Peki hangi dosyalar de\u011fi\u015fmez? Versiyonlanm\u0131\u015f olanlar.<\/p>\n<p>Kontrol etmeyi se\u00e7ti\u011finizde ise <strong>ETag<\/strong> ve <strong>Last-Modified<\/strong> yard\u0131ma ko\u015fuyor. Taray\u0131c\u0131 &#8216;Bende \u015fu etiketli s\u00fcr\u00fcm var, ayn\u0131s\u0131ysa bo\u015funa g\u00f6ndermeyelim&#8217; diye haber yolluyor. Sunucu &#8216;Ayn\u0131, 304 Not Modified&#8217; diyerek yan\u0131tl\u0131yor ve a\u011fdan veri indirilmeden i\u015f \u00e7\u00f6z\u00fcl\u00fcyor. Bu da \u015f\u0131k bir y\u00f6ntem, ama her istekte minik de olsa bir tur sunucuya u\u011frama maliyeti var. \u00d6zetle, taray\u0131c\u0131ya do\u011fru yerde do\u011fru s\u00f6zleri s\u00f6ylemek, sayfay\u0131 hem h\u0131zl\u0131 hem g\u00fcncel tutuyor.<\/p>\n<h2 id='section-3'><span id=\"ETag_mi_Last-Modified_mi_Hangisini_Ne_Zaman_Kullanmali\">ETag m\u0131, Last-Modified m\u0131? Hangisini Ne Zaman Kullanmal\u0131?<\/span><\/h2>\n<p>ETag, dosyan\u0131n bir t\u00fcr kimlik kart\u0131 gibi. \u0130\u00e7erik de\u011fi\u015fti mi, ETag de de\u011fi\u015fiyor. Taray\u0131c\u0131 &#8216;If-None-Match&#8217; ba\u015fl\u0131\u011f\u0131yla sunucuya &#8216;Bende \u015fu etiket var&#8217; diyor. Sunucu da &#8216;Ayn\u0131&#8217; derse 304 d\u00f6n\u00fcyor, &#8216;De\u011fi\u015fti&#8217; derse yeni i\u00e7eri\u011fi g\u00f6nderiyor. <strong>Last-Modified<\/strong> ise dosyan\u0131n son de\u011fi\u015fim tarihine g\u00fcveniyor. Taray\u0131c\u0131 &#8216;If-Modified-Since&#8217; diyerek &#8216;\u015eu tarihten sonra de\u011fi\u015fti mi?&#8217; diye soruyor. Yani biri i\u00e7erik temelli, di\u011feri zaman temelli d\u00fc\u015f\u00fcn\u00fcyor.<\/p>\n<p>Ger\u00e7ek hayatta ben \u015f\u00f6yle yap\u0131yorum: Versiyonlanmam\u0131\u015f ama <strong>nadiren de\u011fi\u015fen<\/strong> dosyalarda k\u0131sa bir max-age verip ETag veya Last-Modified ile kontrol\u00fc a\u00e7\u0131k b\u0131rak\u0131yorum. \u00d6rne\u011fin y\u00f6netim panelinde kullan\u0131lan bir ikon seti aylard\u0131r ayn\u0131ysa, taray\u0131c\u0131 s\u0131k s\u0131k indirmesin, ama arada de\u011fi\u015firse de fark etsin. <strong>Versiyonlanm\u0131\u015f<\/strong> dosyalarda ise ETag ile u\u011fra\u015fm\u0131yorum; \u00e7\u00fcnk\u00fc dosya ad\u0131 zaten de\u011fi\u015fiyor ve taray\u0131c\u0131 yeni dosyay\u0131 yeni ad\u0131ndan tan\u0131yor. Bu durumda uzun bir max-age ve <strong>immutable<\/strong> \u015fahane \u00e7al\u0131\u015f\u0131yor.<\/p>\n<p>Mevzu \u00e7ok sunuculu ortamlara geldi\u011finde ETag bazen s\u00fcrpriz yapabiliyor. Farkl\u0131 makineler farkl\u0131 ETag \u00fcretirse, y\u00fck dengeleyici hangi makineye denk gelirse gelsin taray\u0131c\u0131y\u0131 gereksiz yere &#8216;de\u011fi\u015fti&#8217; diye d\u00fc\u015f\u00fcnd\u00fcrebilir. Bu y\u00fczden, ya ETag&#8217;\u0131 devre d\u0131\u015f\u0131 b\u0131rak\u0131p Last-Modified&#8217;la devam ediyorum ya da ETag&#8217;\u0131 i\u00e7erik karmas\u0131yla stabil hale getiriyorum. Basit tutmak \u00e7o\u011fu zaman daha huzurlu bir uyku getiriyor.<\/p>\n<h2 id='section-4'><span id=\"Immutable_Ne_Zaman_Harika_Ne_Zaman_Sakincali\">Immutable Ne Zaman Harika, Ne Zaman Sak\u0131ncal\u0131?<\/span><\/h2>\n<p><strong>immutable<\/strong> direktifi, taray\u0131c\u0131ya \u00e7ok net bir s\u00f6z verdiriyor: S\u00fcre dolana kadar tekrar sorma. Bu direktifi seviyorum, \u00e7\u00fcnk\u00fc i\u015fe yarad\u0131\u011f\u0131 yerde harikalar yarat\u0131yor. \u00d6rne\u011fin dosya ad\u0131 hash i\u00e7eriyor ve de\u011fi\u015fmeyecekse, immutable ile <strong>uzun bir max-age<\/strong> birlikte verdi\u011fimde, sayfa ikinci ziyarette resmen u\u00e7uyor.<\/p>\n<p>Ama her g\u00fczel \u015fey gibi, yanl\u0131\u015f yerde kullan\u0131rsan\u0131z ters teper. HTML dok\u00fcman\u0131na immutable verirseniz, kullan\u0131c\u0131n\u0131z yeni deploy&#8217;u g\u00fcnlerce g\u00f6rmeyebilir. Ayn\u0131 \u015fekilde versiyonlanmam\u0131\u015f bir CSS dosyas\u0131nda immutable riskli, \u00e7\u00fcnk\u00fc ufak bir d\u00fczeltme yapt\u0131\u011f\u0131n\u0131zda taray\u0131c\u0131 onu asla sormayabilir. Kural basit: <strong>Dosya ad\u0131 de\u011fi\u015fti\u011finde i\u00e7eri\u011fin de de\u011fi\u015fti\u011finden emin misiniz?<\/strong> Evetse immutable, hay\u0131rsa kontroll\u00fc bir strateji daha mant\u0131kl\u0131.<\/p>\n<p>Bu arada immutable modern taray\u0131c\u0131lar taraf\u0131ndan iyi destekleniyor. Yine de davran\u0131\u015flar\u0131n ayr\u0131nt\u0131lar\u0131n\u0131 okumak isterseniz, <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Cache-Control\" rel=\"nofollow noopener\" target=\"_blank\">Cache-Control ba\u015fl\u0131\u011f\u0131n\u0131n MDN sayfas\u0131ndaki a\u00e7\u0131klamalar<\/a> kafay\u0131 sakinle\u015ftiriyor. Baz\u0131 CDN&#8217;ler de buna \u00f6zel iyile\u015ftirmeler yap\u0131yor; mesela <a href=\"https:\/\/blog.cloudflare.com\/announcing-support-for-cache-control-immutable\/\" rel=\"nofollow noopener\" target=\"_blank\">Cache-Control immutable deste\u011fini anlatan Cloudflare yaz\u0131s\u0131<\/a> pratik \u00f6rneklerle ho\u015f bir kaynak.<\/p>\n<h2 id='section-5'><span id=\"Versiyonlama_Fingerprinting_Her_Seyi_Bir_Dosya_Adina_Sigdirmak\">Versiyonlama (Fingerprinting): Her \u015eeyi Bir Dosya Ad\u0131na S\u0131\u011fd\u0131rmak<\/span><\/h2>\n<p>Versiyonlamay\u0131 ilk kez d\u00fczg\u00fcn kurdu\u011fum projede, sanki trafik yar\u0131 yar\u0131ya azalm\u0131\u015f gibi hissettim. \u00c7\u00fcnk\u00fc taray\u0131c\u0131lar ger\u00e7ekten ayn\u0131 isimli dosyay\u0131 bir kez indirip bir daha hi\u00e7 sormuyordu. Mant\u0131k basit: <strong>app.css<\/strong> yerine <strong>app.abc123.css<\/strong> gibi bir ad kullan\u0131yorsunuz. \u0130\u00e7erik de\u011fi\u015fti\u011finde bu &#8216;abc123&#8217; de de\u011fi\u015fiyor. B\u00f6ylece taray\u0131c\u0131 yeni dosyan\u0131n farkl\u0131 oldu\u011funu, ad\u0131ndan anl\u0131yor.<\/p>\n<p>Bunu \u00fcretmek i\u00e7in \u00f6zel bir \u015fey yapman\u0131za gerek yok, \u00e7o\u011fu modern ara\u00e7 zaten destekliyor. Webpack, Vite, Rollup, Parcel, Laravel Mix benzeri toplay\u0131c\u0131lar \u00e7\u0131kt\u0131 dosyalar\u0131n\u0131n ad\u0131na <strong>content hash<\/strong> eklemeyi birka\u00e7 ayar sat\u0131r\u0131yla hallediyor. Statik site \u00fcreticileri de ayn\u0131 yolu izliyor. Sunucu taraf\u0131nda tek yapman\u0131z gereken, bu dosyalar i\u00e7in uzun bir max-age ve immutable vermek. HTML taraf\u0131 ise her deploy&#8217;da g\u00fcncelleniyor, yeni dosya adlar\u0131na i\u015faret ediyor.<\/p>\n<p>Ben HTML&#8217;ye k\u0131sa bir max-age, hatta \u00e7o\u011funlukla sadece <strong>no-cache<\/strong> veriyorum. B\u00f6ylece HTML her ziyarette kontrol ediliyor ama statik dosyalar uzun s\u00fcre saklan\u0131yor. Bir kez do\u011fru ba\u011f kuruldu mu, da\u011f\u0131t\u0131m derdi azal\u0131yor. CDN kullan\u0131yorsan\u0131z, versiyonlanm\u0131\u015f dosyalar\u0131 neredeyse hi\u00e7bir zaman <em>purge<\/em> etmeye gerek kalm\u0131yor. Sadece HTML ve API yan\u0131tlar\u0131yla ilgileniyorsunuz.<\/p>\n<h2 id='section-6'><span id=\"Nginx_ile_Adim_Adim_Hangi_Dosyaya_Ne_Verelim\">Nginx ile Ad\u0131m Ad\u0131m: Hangi Dosyaya Ne Verelim?<\/span><\/h2>\n<h3><span id=\"Nginx_konfigurasyonu_icin_basit_bir_cati\">Nginx konfig\u00fcrasyonu i\u00e7in basit bir \u00e7at\u0131<\/span><\/h3>\n<p>Genelde iki kural yaz\u0131yorum: Versiyonlanm\u0131\u015f dosyalara uzun \u00f6m\u00fcr ve immutable, versiyonlanmam\u0131\u015flara k\u0131sa \u00f6m\u00fcr ve do\u011frulama. Basit bir \u00f6rnek payla\u015fay\u0131m:<\/p>\n<pre class=\"language-nginx line-numbers\"><code class=\"language-nginx\"># Versiyonlanm\u0131\u015f dosyalar: app.abc123.css, vendor.9f8e7.js gibi\nlocation ~* \\.(?:css|js|mjs|json|map|png|jpg|jpeg|gif|webp|avif|svg|ico|woff2?)$ {\n    if ($uri ~* &quot;\\.[0-9a-f]{8,}\\.&quot;) {\n        add_header Cache-Control 'public, max-age=31536000, immutable';\n        etag off;        # ETag'a gerek yok, dosya ad\u0131 zaten de\u011fi\u015fiyor\n        expires 1y;      # Baz\u0131 ara\u00e7lar expires'tan ho\u015flan\u0131yor, ikisini birlikte vermek sorun de\u011fil\n    }\n}\n\n# Versiyonlanmam\u0131\u015f statikler: admin.css gibi\nlocation ~* \\.(?:css|js|png|jpg|jpeg|gif|svg|ico|woff2?)$ {\n    add_header Cache-Control 'public, max-age=300';\n    etag on;             # K\u0131sa \u00f6m\u00fcr + do\u011frulama\n    expires 5m;\n}\n\n# HTML ve JSON sayfalar\u0131\nlocation ~* \\.(?:html)$ {\n    add_header Cache-Control 'no-cache';\n    etag on;\n    expires -1;\n}\n<\/code><\/pre>\n<p>Ben dosya ad\u0131ndaki hash&#8217;i d\u00fczenli ifadeyle yakal\u0131yorum. Uygulaman\u0131za g\u00f6re desen de\u011fi\u015febilir. Baz\u0131 ekipler <strong>query string versiyonlama<\/strong> (\u00f6rne\u011fin style.css?v=123) kullan\u0131yor. Taray\u0131c\u0131lar bunu da anl\u0131yor, ama tecr\u00fcbem \u015fu: <strong>dosya ad\u0131n\u0131<\/strong> de\u011fi\u015ftirmek hem CDN&#8217;lerle hem log analiziyle daha p\u00fcr\u00fczs\u00fcz \u00e7al\u0131\u015f\u0131yor.<\/p>\n<h3><span id=\"HTTP2_Brotli_ve_diger_tatli_eklemeler\">HTTP\/2, Brotli ve di\u011fer tatl\u0131 eklemeler<\/span><\/h3>\n<p>\u0130\u015f \u00f6nbellekten ibaret de\u011fil tabii. S\u0131k\u0131\u015ft\u0131rma ve protokol de b\u00fcy\u00fck fark yarat\u0131yor. Nginx \u00fczerinde modern \u015fifreler ve Brotli&#8217;yi kurcalamak isterseniz, bizim \u015fu rehberdeki notlar\u0131mdan epey fayda g\u00f6rm\u00fc\u015ft\u00fcm: <a href=\"https:\/\/www.dchost.com\/blog\/nginxte-tls-1-3-ocsp-stapling-ve-brotli-nasil-kurulur-hizli-ve-guvenli-httpsnin-sicacik-rehberi\/\">Nginx\u2019te TLS 1.3, OCSP Stapling ve Brotli Nas\u0131l Kurulur?<\/a>. U\u00e7tan uca k\u00fc\u00e7\u00fck dokunu\u015flar birle\u015fince sayfa hissedilir derecede h\u0131zlan\u0131yor.<\/p>\n<h2 id='section-7'><span id=\"Apache_htaccess_ile_Ayarlar_Kisa_ve_Net\">Apache (.htaccess) ile Ayarlar: K\u0131sa ve Net<\/span><\/h2>\n<p>Apache kullananlarda i\u015f \u00e7o\u011fu zaman .htaccess ile \u00e7\u00f6z\u00fcl\u00fcyor. Mod_headers ve mod_expires etkinse \u015fu tarz bir kurulum temiz bir ba\u015flang\u0131\u00e7 yap\u0131yor:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">&lt;IfModule mod_headers.c&gt;\n  &lt;FilesMatch '\\.(css|js|mjs|png|jpg|jpeg|gif|webp|avif|svg|ico|woff2?)$'&gt;\n    Header set Cache-Control 'public, max-age=300'\n  &lt;\/FilesMatch&gt;\n\n  &lt;FilesMatch '\\.[0-9a-f]{8,}\\.(css|js|mjs|png|jpg|jpeg|gif|webp|avif|svg|ico|woff2?)$'&gt;\n    Header set Cache-Control 'public, max-age=31536000, immutable'\n  &lt;\/FilesMatch&gt;\n\n  &lt;FilesMatch '\\.(html)$'&gt;\n    Header set Cache-Control 'no-cache'\n  &lt;\/FilesMatch&gt;\n&lt;\/IfModule&gt;\n\n&lt;IfModule mod_expires.c&gt;\n  ExpiresActive On\n  ExpiresByType text\/html 'access plus 0 seconds'\n  ExpiresByType text\/css 'access plus 5 minutes'\n  ExpiresByType application\/javascript 'access plus 5 minutes'\n&lt;\/IfModule&gt;\n<\/code><\/pre>\n<p>Apache taraf\u0131nda ETag varsay\u0131lan olarak a\u00e7\u0131k gelebilir. \u00c7ok sunuculu yap\u0131da gereksiz \u015fa\u015fk\u0131nl\u0131k yarat\u0131yorsa kapatmak isteyebilirsiniz. K\u00fc\u00e7\u00fck bir not: Baz\u0131 CDN&#8217;ler ETag&#8217;\u0131 oldu\u011fu gibi ta\u015f\u0131yor, baz\u0131lar\u0131 g\u00f6rmezden geliyor. Davran\u0131\u015f\u0131 test ederek karar vermek en do\u011frusu.<\/p>\n<h2 id='section-8'><span id=\"NodejsExpress_ile_Basliklar_Uygulamadan_Vermek\">Node.js\/Express ile Ba\u015fl\u0131klar: Uygulamadan Vermek<\/span><\/h2>\n<p>Statik dosyalar\u0131 Express ile sunuyorsan\u0131z, do\u011fru ba\u015fl\u0131klar\u0131 uygulama katman\u0131nda da verebilirsiniz. Ben s\u0131k s\u0131k a\u015fa\u011f\u0131daki gibi bir kurgu kuruyorum: hash&#8217;li dosyalara uzun \u00f6m\u00fcr, di\u011ferlerine temkinli yakla\u015f\u0131m.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">const express = require('express');\nconst app = express();\n\napp.use((req, res, next) =&gt; {\n  if (\/\\.[0-9a-f]{8,}\\.(css|js|mjs|png|jpg|jpeg|gif|webp|avif|svg|ico|woff2?)$\/i.test(req.url)) {\n    res.set('Cache-Control', 'public, max-age=31536000, immutable');\n  }\n  next();\n});\n\napp.use(express.static('public', {\n  etag: true,              \/\/ Versiyonlanmam\u0131\u015flar i\u00e7in i\u015fimize yarar\n  lastModified: true,      \/\/ Ek bir g\u00fcvence\n  maxAge: '5m',            \/\/ Genel bir varsay\u0131lan\n  setHeaders: (res, path) =&gt; {\n    if (path.endsWith('.html')) {\n      res.set('Cache-Control', 'no-cache');\n    }\n  }\n}));\n\napp.listen(3000);\n<\/code><\/pre>\n<p>Deploy d\u00fczeniniz Express \u00fczerinden d\u00f6n\u00fcyorsa, s\u0131f\u0131r kesinti stratejisi ayr\u0131 bir mutluluk getiriyor. Bu konuda ad\u0131m ad\u0131m pratikleri toparlad\u0131\u011f\u0131m \u015fu yaz\u0131y\u0131 s\u0131cak bir \u00e7ay e\u015fli\u011finde okuman\u0131z\u0131 \u00f6neririm: <a href=\"https:\/\/www.dchost.com\/blog\/node-jsi-canliya-alirken-panik-yapma-pm2-systemd-nginx-ssl-ve-sifir-kesinti-deploy-nasil-kurulur\/\">Node.js\u2019i canl\u0131ya al\u0131rken panik yapmadan s\u0131f\u0131r kesinti deploy kurmak<\/a>. Statik dosya versiyonlama ve cache ayarlar\u0131, b\u00f6yle bir da\u011f\u0131t\u0131m\u0131n yan\u0131nda en iyi arkada\u015f olur.<\/p>\n<h2 id='section-9'><span id=\"S3_CloudFront_ve_CDN_Dunyasinda_Kurulum\">S3, CloudFront ve CDN D\u00fcnyas\u0131nda Kurulum<\/span><\/h2>\n<p>Objeleri S3 \u00fczerinde tutuyor, \u00f6n\u00fcne CloudFront veya benzeri bir CDN koyuyorsan\u0131z, oyunun kurallar\u0131 ayn\u0131 ama ayarlar\u0131n yeri de\u011fi\u015fik. S3 objesine y\u00fcklerken <strong>Cache-Control<\/strong> ba\u015fl\u0131\u011f\u0131n\u0131 do\u011fru verin: versiyonlanm\u0131\u015f dosyalar i\u00e7in &#8216;public, max-age=31536000, immutable&#8217; cand\u0131r. Versiyonlanmam\u0131\u015flar i\u00e7in daha k\u0131sa bir max-age yaz\u0131n, hatta kontroll\u00fc davranmak i\u00e7in no-cache bile mant\u0131kl\u0131 olabilir.<\/p>\n<p>CloudFront taraf\u0131nda <em>cache policy<\/em> se\u00e7erken &#8216;Origin Cache-Control&#8217; ba\u015fl\u0131\u011f\u0131n\u0131 dikkate al diyin ki, S3&#8217;e yazd\u0131\u011f\u0131n\u0131z de\u011ferler bo\u015fa gitmesin. HTML&#8217;yi k\u0131sa tutarsan\u0131z, yeni deploy&#8217;larda kullan\u0131c\u0131lar\u0131n\u0131z g\u00fcncel i\u00e7eri\u011fi hemen g\u00f6r\u00fcr. CDN&#8217;lerde en g\u00fczel \u015feylerden biri de \u015fu: <strong>versiyonlu dosyalarda purge&#8217;e neredeyse hi\u00e7 gerek kalm\u0131yor<\/strong>. \u00c7\u00fcnk\u00fc isim de\u011fi\u015fti\u011fi i\u00e7in yeni nesne, yeni bir anahtar olarak geliyor.<\/p>\n<p>WordPress gibi sistemlerde medya dosyalar\u0131n\u0131 S3&#8217;e ta\u015f\u0131y\u0131p CDN \u00fczerinden servis etmeyi konu\u015ftu\u011fumuz yaz\u0131da, bu ba\u015fl\u0131k ayarlar\u0131n\u0131n canl\u0131 \u00f6rneklerini payla\u015fm\u0131\u015ft\u0131m: <a href=\"https:\/\/www.dchost.com\/blog\/wordpress-medyani-s3e-tasiyalim-mi-cdn-imzali-url-ve-onbellek-gecersizlestirme-adim-adim\/\">WordPress medyay\u0131 S3\u2019e ta\u015f\u0131mak ve CDN taraf\u0131nda ak\u0131ll\u0131 \u00f6nbellek ge\u00e7ersizle\u015ftirme<\/a>. Medya dosyalar\u0131nda da ayn\u0131 mant\u0131k ge\u00e7erli: de\u011fi\u015fmeyecekse uzun \u00f6m\u00fcr, de\u011fi\u015fecekse kontroll\u00fc yakla\u015f\u0131m.<\/p>\n<h2 id='section-10'><span id=\"HTMLi_Kisa_Tut_Statikleri_Ucur_Dagitimin_Incelikleri\">HTML\u2019i K\u0131sa Tut, Statikleri U\u00e7ur: Da\u011f\u0131t\u0131m\u0131n \u0130ncelikleri<\/span><\/h2>\n<p>\u0130\u015fin inceli\u011fi genelde HTML&#8217;de sakl\u0131. \u00c7\u00fcnk\u00fc o sayfa, hangi CSS ve JS&#8217;nin \u00e7a\u011fr\u0131laca\u011f\u0131n\u0131 belirliyor. Ben deploy s\u0131ras\u0131nda <strong>atomik s\u00fcr\u00fcm<\/strong> yakla\u015f\u0131m\u0131n\u0131 seviyorum: yeni s\u00fcr\u00fcm bir klas\u00f6rde haz\u0131rlan\u0131r, referanslar hash&#8217;li dosyalara g\u00fcncellenir, en sonda bir sembolik ba\u011flant\u0131 ya da k\u00fc\u00e7\u00fck bir config de\u011fi\u015fikli\u011fiyle trafik yeni s\u00fcr\u00fcme d\u00f6ner. Bu ak\u0131\u015fta, statikler zaten yeni adlar\u0131yla geldi\u011fi i\u00e7in herhangi bir purge&#8217;e ihtiya\u00e7 kalm\u0131yor.<\/p>\n<p>Bu tarz bir kurgu i\u00e7in s\u0131f\u0131r kesinti da\u011f\u0131t\u0131m\u0131 anlatt\u0131\u011f\u0131m rehber de ho\u015funuza gidebilir: <a href=\"https:\/\/www.dchost.com\/blog\/vpse-sifir-kesinti-ci-cd-nasil-kurulur-rsync-sembolik-surumler-ve-systemd-ile-sicacik-bir-yolculuk\/\">VPS\u2019e s\u0131f\u0131r kesinti CI\/CD kurmak<\/a>. Versiyonlama ve cache ba\u015fl\u0131klar\u0131yla birlikte d\u00fc\u015f\u00fcn\u00fcnce, da\u011f\u0131t\u0131m sonras\u0131 &#8216;Bende eski CSS kald\u0131&#8217; mesajlar\u0131n\u0131n yerini, &#8216;Site nas\u0131l da h\u0131zlanm\u0131\u015f&#8217; yorumlar\u0131 al\u0131yor.<\/p>\n<p>G\u00f6r\u00fcnt\u00fc taraf\u0131nda da ayn\u0131 prensip i\u015fliyor. G\u00f6rselleri farkl\u0131 formatlarda (AVIF\/WebP) \u00fcretip uygun Cache-Control ile servis etti\u011finizde, hem h\u0131z hem fatura dengeli gidiyor. Bu hatt\u0131 kurgularken not ald\u0131klar\u0131m\u0131 \u015furada uzun uzad\u0131ya yazm\u0131\u015ft\u0131m: <a href=\"https:\/\/www.dchost.com\/blog\/goruntu-optimizasyonu-boru-hatti-nasil-kurulur-avif-webp-origin-shield-ve-akilli-cache-key-ile-cdn-faturaniza-nefes-aldirin\/\">G\u00f6r\u00fcnt\u00fc optimizasyonu boru hatt\u0131 ve ak\u0131ll\u0131 cache-key<\/a>. Oradaki &#8216;cache-key&#8217; fikri, burada anlatt\u0131\u011f\u0131m\u0131z versiyonlama d\u00fc\u015f\u00fcncesiyle \u00e7ok iyi anla\u015f\u0131yor.<\/p>\n<h2 id='section-11'><span id=\"Test_Etmeden_Guvenme_DevTools_curl_ve_Kucuk_Tuyolar\">Test Etmeden G\u00fcvenme: DevTools, curl ve K\u00fc\u00e7\u00fck T\u00fcyolar<\/span><\/h2>\n<p>Her \u015fey bitti san\u0131rken, taray\u0131c\u0131lar\u0131n asl\u0131nda kafas\u0131na g\u00f6re davrand\u0131\u011f\u0131n\u0131 g\u00f6r\u00fcp \u015fa\u015f\u0131rd\u0131\u011f\u0131m \u00e7ok oldu. O y\u00fczden test, test, test. Chrome DevTools&#8217;un Network sekmesinde her iste\u011fin <strong>Response Headers<\/strong> k\u0131sm\u0131na bak\u0131n. Cache-Control, ETag\/Last-Modified ne gelmi\u015f, 200 m\u00fc 304 m\u00fc, hepsini g\u00f6r\u00fcn. \u00d6zellikle &#8216;from disk cache&#8217; ya da &#8216;memory cache&#8217; ibareleri \u00e7ok \u015fey anlat\u0131yor.<\/p>\n<p>Terminalde de bir iki komut al\u0131\u015fkanl\u0131k yap\u0131nca h\u0131z kazand\u0131r\u0131yor. Mesela:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">curl -I 'https:\/\/site.com\/assets\/app.abc123.css'\ncurl -H 'If-None-Match: &quot;xyz&quot;' -I 'https:\/\/site.com\/assets\/app.css'\ncurl -H 'Cache-Control: no-cache' -I 'https:\/\/site.com\/index.html'\n<\/code><\/pre>\n<p>\u0130lk komutta dosyan\u0131n cache ba\u015fl\u0131\u011f\u0131n\u0131 g\u00f6r\u00fcrs\u00fcn\u00fcz. \u0130kincide sunucunun ETag do\u011frulamas\u0131na nas\u0131l yan\u0131t verdi\u011fini anlars\u0131n\u0131z. \u00dc\u00e7\u00fcnc\u00fcde ise istemcinin &#8216;bana yeni s\u00fcr\u00fcm\u00fc kontrol et&#8217; bask\u0131s\u0131 yaratt\u0131\u011f\u0131n\u0131 g\u00f6r\u00fcrs\u00fcn\u00fcz. K\u00fc\u00e7\u00fck bir uyar\u0131: \u00c7ok sunuculu yap\u0131da, ETag de\u011ferinin makineye g\u00f6re de\u011fi\u015fmedi\u011finden emin olun ya da tamamen kapat\u0131n. Alternatif olarak sadece Last-Modified b\u0131rakmak, \u00e7o\u011fu durumda zihni serin tutuyor.<\/p>\n<p>Daha derli toplu anlat\u0131m ararsan\u0131z, <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/ETag\" rel=\"nofollow noopener\" target=\"_blank\">ETag ba\u015fl\u0131\u011f\u0131n\u0131n MDN sayfas\u0131<\/a> sade bir \u00f6zet sunuyor. Oradaki \u00f6rnekleri kendinize g\u00f6re uyarlay\u0131p test etmek, &#8216;Tamamd\u0131r&#8217; demeden \u00f6nce g\u00fczel bir g\u00fcvence oluyor.<\/p>\n<h2 id='section-12'><span id=\"Gercek_Bir_Senaryo_Kirik_CSS_ve_Yamali_Cozumden_Kalici_Duzen\">Ger\u00e7ek Bir Senaryo: K\u0131r\u0131k CSS ve Yamal\u0131 \u00c7\u00f6z\u00fcmden Kal\u0131c\u0131 D\u00fczen<\/span><\/h2>\n<p>Bir projede ba\u015fta versiyonlama yoktu. CSS dosyas\u0131na orta uzunlukta bir max-age verip, yan\u0131na ETag eklemi\u015ftik. \u0130lk haftalar her \u015fey yolunda g\u00f6z\u00fckt\u00fc. Sonra canl\u0131da k\u00fc\u00e7\u00fck bir tasar\u0131m de\u011fi\u015fikli\u011fi yapt\u0131k ve beklenmeyen bir \u0131srarla, baz\u0131 kullan\u0131c\u0131lar eski stilde kald\u0131. ETag asl\u0131nda do\u011fru \u00e7al\u0131\u015f\u0131yordu, ama ara katmanda duran bir CDN, do\u011frulama ba\u015fl\u0131klar\u0131n\u0131 farkl\u0131 y\u00f6netti\u011fi i\u00e7in baz\u0131 istekler gereksiz yere ta\u015f\u0131nm\u0131\u015ft\u0131. K\u0131sa vadeli \u00e7\u00f6z\u00fcm olarak purge yapt\u0131k, ama bunun s\u00fcrd\u00fcr\u00fclebilir olmad\u0131\u011f\u0131n\u0131 o g\u00fcn anlad\u0131k.<\/p>\n<p>Kal\u0131c\u0131 \u00e7\u00f6z\u00fcm\u00fc \u015f\u00f6yle kurduk: Build hatt\u0131na <strong>content hash<\/strong> ekledik, t\u00fcm linkleri hash&#8217;li dosyalara \u00e7evirdik, bu dosyalar i\u00e7in &#8216;public, max-age=31536000, immutable&#8217; verdik, HTML&#8217;yi ise no-cache yapt\u0131k. Bir sonraki deploy&#8217;dan sonra, benzer sorunlar kayboldu. Art\u0131k bir \u015fey de\u011fi\u015fti\u011finde dosya ad\u0131 da de\u011fi\u015fiyor, taray\u0131c\u0131lar yeni adresi g\u00f6r\u00fcyor ve hi\u00e7 teredd\u00fct etmeden indiriyordu. Eski dosyalar CD&#8217;de kalsa da sorun yoktu, \u00e7\u00fcnk\u00fc yeni istekler eskilere u\u011fram\u0131yordu.<\/p>\n<p>Bu arada da\u011f\u0131t\u0131m\u0131 panik yapmadan, filtre kahveyi so\u011futmadan yapmak i\u00e7in s\u00fcre\u00e7leri de toparlad\u0131k. <a href=\"https:\/\/www.dchost.com\/blog\/gelistirme-staging-canli-yolculugu-wordpress-ve-laravelde-sifir-kesinti-dagitim-nasil-gercekten-olur\/\">Geli\u015ftirme\u2013staging\u2013canl\u0131 yolculu\u011funu s\u0131f\u0131r kesinti oda\u011f\u0131yla anlatan rehberde<\/a> bu taraf\u0131n iskeletini konu\u015fmu\u015ftuk. \u00d6zetle, k\u00fc\u00e7\u00fck ve g\u00fcvenilir ad\u0131mlar sonraki haftalar\u0131 huzurlu k\u0131l\u0131yor.<\/p>\n<h2 id='section-13'><span id=\"Sik_Yapilan_Hatalar_Kisa_Bir_Tur_ve_Cozum_Yollari\">S\u0131k Yap\u0131lan Hatalar: K\u0131sa Bir Tur ve \u00c7\u00f6z\u00fcm Yollar\u0131<\/span><\/h2>\n<p>\u0130lk hata genelde \u015fu oluyor: Versiyonlanmam\u0131\u015f bir dosyaya uzun bir max-age ve immutable veriliyor. Sonra de\u011fi\u015fiklik yap\u0131l\u0131yor, ama kullan\u0131c\u0131lar \u0131srarla eski s\u00fcr\u00fcm\u00fc g\u00f6r\u00fcyor. \u00c7\u00f6z\u00fcm basit: Ya versiyonlay\u0131n ya da k\u0131sa bir \u00f6m\u00fcr verin ve do\u011frulamay\u0131 a\u00e7\u0131k b\u0131rak\u0131n. \u0130kinci hata, HTML&#8217;ye uzun \u00f6m\u00fcr vermek. HTML, yeni referanslar\u0131n kap\u0131s\u0131; k\u0131sa tutmak g\u00fcven verir.<\/p>\n<p>\u00dc\u00e7\u00fcnc\u00fc tuzakta ETag \u00e7ok sunuculu ortamda ba\u015f a\u011fr\u0131t\u0131yor. E\u011fer her makine farkl\u0131 ETag \u00fcretirse, s\u0131rayla 304 yerine 200&#8217;ler g\u00f6r\u00fcrs\u00fcn\u00fcz. Ya ETag&#8217;\u0131 devred\u0131\u015f\u0131 b\u0131rak\u0131n ya da ETag&#8217;\u0131 i\u00e7erik karmas\u0131yla sabitleyin. D\u00f6rd\u00fcnc\u00fc noktada da CDN&#8217;lere gere\u011finden fazla purge at\u0131l\u0131yor. Versiyonlama varsa, \u00e7o\u011fu zaman purge&#8217;e gerek yok. Sadece HTML&#8217;yi tazelemek \u00e7o\u011fu senaryoda yeter.<\/p>\n<h2 id='section-14'><span id=\"Kapanis_Hafif_Hizli_ve_Guvenilir_Bir_Dunyaya_Dogru\">Kapan\u0131\u015f: Hafif, H\u0131zl\u0131 ve G\u00fcvenilir Bir D\u00fcnyaya Do\u011fru<\/span><\/h2>\n<p>Toparlayal\u0131m. Statik dosyalarda hayal etti\u011fimiz h\u0131z, asl\u0131nda birka\u00e7 sa\u011fduyulu kural\u0131n birle\u015fimi. <strong>Versiyonlama<\/strong> ile dosya adlar\u0131na g\u00fcven, <strong>Cache-Control<\/strong> ile taray\u0131c\u0131n\u0131n davran\u0131\u015f\u0131n\u0131 y\u00f6nlendir, <strong>immutable<\/strong> ile gereksiz kontrolleri kald\u0131r, <strong>ETag\/Last-Modified<\/strong> ile temkinli yerlerde emin ad\u0131mlarla ilerle. \u00dcst\u00fcne da\u011f\u0131t\u0131m s\u00fcrecini k\u00fc\u00e7\u00fck ve temiz ad\u0131mlara b\u00f6ld\u00fc\u011f\u00fcn\u00fczde, hem ekip huzuru art\u0131yor hem kullan\u0131c\u0131lar kendini iyi hissediyor.<\/p>\n<p>Pratik bir ba\u015flang\u0131\u00e7 i\u00e7in bug\u00fcn \u015funlar\u0131 yap\u0131n: Build arac\u0131n\u0131zda content hash \u00fcretmeyi a\u00e7\u0131n, Nginx\/Apache&#8217;de hash&#8217;li dosyalar\u0131 yakalayan bir kural yaz\u0131n, HTML i\u00e7in no-cache verin, testleri DevTools ve curl ile do\u011frulay\u0131n. CDN kullan\u0131yorsan\u0131z, origin&#8217;deki Cache-Control&#8217;\u00fc sayg\u0131yla ta\u015f\u0131d\u0131\u011f\u0131ndan emin olun. K\u00fc\u00e7\u00fck bir kontrol listesiyle ba\u015flad\u0131\u011f\u0131n\u0131zda, bir hafta i\u00e7inde sayfan\u0131n nefes ald\u0131\u011f\u0131n\u0131 hissedeceksiniz.<\/p>\n<p>Umar\u0131m bu yaz\u0131 kafan\u0131zdaki d\u00fc\u011f\u00fcmleri gev\u015fetmi\u015ftir. Sorular\u0131n\u0131z olursa not al\u0131n, birlikte kurcalar\u0131z. Bir dahaki yaz\u0131da, bu ayarlar\u0131n performans \u00f6l\u00e7\u00fcm\u00fcn\u00fc ve ger\u00e7ek trafik alt\u0131nda neleri de\u011fi\u015ftirdi\u011fini konu\u015fal\u0131m. \u015eimdilik, statik dosyalar\u0131n\u0131z\u0131n keyfi yerinde olsun.<\/p>\n<p>&#8220;,<br \/>\n  &#8220;focus_keyword&#8221;: &#8220;Cache-Control immutable&#8221;,<br \/>\n  &#8220;meta_description&#8221;: &#8220;Statik dosyalarda Cache-Control immutable, ETag ve Last-Modified ayarlar\u0131n\u0131; versiyonlama ve Nginx\/Apache yap\u0131land\u0131rmalar\u0131n\u0131 \u00f6rneklerle kolayca \u00f6\u011frenin.&#8221;,<br \/>\n  &#8220;faqs&#8221;: [<br \/>\n    {<br \/>\n      &#8220;question&#8221;: &#8220;Immutable ne zaman kullan\u0131lmal\u0131?&#8221;,<br \/>\n      &#8220;answer&#8221;: &#8220;Dosya ad\u0131 i\u00e7erik de\u011fi\u015fti\u011finde de\u011fi\u015fiyorsa, yani fingerprinting (app.abc123.css) yap\u0131yorsan\u0131z immutable harika \u00e7al\u0131\u015f\u0131r. HTML gibi s\u0131k de\u011fi\u015fen i\u00e7eriklerde kullanmay\u0131n.&#8221;<br \/>\n    },<br \/>\n    {<br \/>\n      &#8220;question&#8221;: &#8220;ETag mi Last-Modified m\u0131 se\u00e7meliyim?&#8221;,<br \/>\n      &#8220;answer&#8221;: &#8220;Versiyonlama yoksa ve k\u0131sa bir \u00f6m\u00fcr veriyorsan\u0131z ikisi de i\u015f g\u00f6r\u00fcr. \u00c7ok sunuculu yap\u0131da ETag sorun \u00e7\u0131kar\u0131yorsa Last-Modified daha pratik olur. Versiyonlu dosyalarda genelde ikisine de gerek kalmaz.&#8221;<br \/>\n    },<br \/>\n    {<br \/>\n      &#8220;question&#8221;: &#8220;Query string ile mi, dosya ad\u0131yla m\u0131 versiyonlamal\u0131y\u0131m?&#8221;,<br \/>\n      &#8220;answer&#8221;: &#8220;Her ikisi de \u00e7al\u0131\u015f\u0131r ama dosya ad\u0131n\u0131 de\u011fi\u015ftirmek (app.abc123.css) CDN ve loglama taraf\u0131nda daha temiz olur. De\u011fi\u015fiklikte yeni dosya ad\u0131, taray\u0131c\u0131ya net bir i\u015faret verir.&#8221;<br \/>\n    }<br \/>\n  ]<br \/>\n}<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>{ &#8220;title&#8221;: &#8220;Statik Dosyalar \u0130\u00e7in Cache-Control immutable, ETag ve Last-Modified ile Versiyonlama Nas\u0131l Kurulur?&#8221;, &#8220;content&#8221;: &#8220; Hi\u00e7 ba\u015f\u0131n\u0131za geldi mi? Canl\u0131ya yeni bir tasar\u0131m att\u0131n\u0131z, sizde her \u015fey harika g\u00f6r\u00fcn\u00fcyor ama kullan\u0131c\u0131 &#8216;Butonlar yamulmu\u015f&#8217; diye yaz\u0131yor. Ekran\u0131 yeniliyor, taray\u0131c\u0131y\u0131 kapat\u0131p a\u00e7\u0131yor, yine ayn\u0131. O an anl\u0131yorsunuz ki kullan\u0131c\u0131 eski CSS&#8217;e tak\u0131l\u0131 kalm\u0131\u015f. Benzer bir g\u00fcn\u00fc [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1553,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-1552","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknoloji"],"_links":{"self":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts\/1552","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/comments?post=1552"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts\/1552\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media\/1553"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media?parent=1552"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/categories?post=1552"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/tags?post=1552"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}