Ana içeriğe geç

GZIP Sıkıştırma: htaccess ile %70 Boyut Azaltma

GZIP Sıkıştırma: htaccess ile %70 Boyut Azaltma - Teknik SEO Rehberi

Bir web sitesinin HTTP yanıt boyutları küçüldükçe hem tarayıcı hem de sunucu kazanır. 80 KB'lık bir CSS dosyası sıkıştırma olmadan her istek için tam ağırlığıyla transfer edilir; aynı dosya GZIP ile gönderildiğinde 15-20 KB'a iner. Bu kazanç özellikle metin tabanlı varlıklarda belirgindir: HTML, CSS, JavaScript ve JSON dosyaları, rastgele ikili veri içermedikleri için LZ77 tabanlı deflate algoritması tarafından verimli biçimde küçültülür.

Apache'de GZIP sıkıştırma için iki modül tarihsel olarak kullanılmıştır: mod_gzip (Apache 1.3 dönemi) ve mod_deflate (Apache 2.x standartı). Günümüzde neredeyse tüm kurulumlar mod_deflate üzerinde çalışır. İsim kafa karıştırıcıdır: "deflate" ifadesi, HTTP başlığında tarayıcıya gönderilen Content-Encoding: gzip değeriyle çelişir gibi görünür. Gerçekte Apache, mod_deflate ile içeriği gzip formatında sıkıştırır ve yanıt başlığına Content-Encoding: gzip yazar; "deflate" sadece modül adıdır.

mod_deflate ile GZIP: Temel Mekanizma

mod_deflate, Apache'nin çıktı filtre zincirine gzip sıkıştırmasını ekler. Filtre, yanıt içeriği istemciye gönderilmeden hemen önce devreye girer ve seçilen MIME tiplerine göre sıkıştırma uygular. Tarayıcı, isteğine Accept-Encoding: gzip başlığını eklediğinde sunucu bu başlığı okur ve sıkıştırılmış içerik gönderir; tarayıcı bu başlığı göndermezse sıkıştırma atlanır ve ham içerik transfer edilir.

Sıkıştırma işlemi tamamen sunucu tarafındadır. İstemcinin herhangi bir ek yapılandırmasına gerek yoktur. Chrome, Firefox, Safari ve Edge Accept-Encoding: gzip başlığını her istekte otomatik olarak gönderir; bu yüzden pratikte web trafiğinin büyük çoğunluğu sıkıştırmadan yararlanır. Tarayıcı yanıttaki Content-Encoding: gzip başlığını görünce içeriği bellekte açar ve ham HTML veya CSS olarak yorumlar; kullanıcı bu sürecin farkında bile olmaz.

Başlık yoksa sıkıştırma da yoktur.

.htaccess ile GZIP Yapılandırması

mod_deflate aktifse .htaccess üzerinden sıkıştırma kuralları tanımlanabilir. En yaygın yöntem AddOutputFilterByType direktifidir:

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE image/svg+xml
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE font/ttf
    AddOutputFilterByType DEFLATE font/opentype
    AddOutputFilterByType DEFLATE application/font-woff
</IfModule>

IfModule bloğu içine alınmasının nedeni basittir: mod_deflate yüklü değilse bu direktifler 500 hatası yerine sessizce atlanır. Yüklü olmayan modül için tanımlanan direktifler Apache'yi çökertemez; yalnızca etkisiz kalır.

Çalışıyor. Ama burası bitmez.

AddOutputFilterByType direktifi her MIME tipi için ayrı satır gerektirdiğinden bakım maliyeti zamanla artar; yeni bir MIME tipi eklendiğinde listeye dahil edilmesi unutulabilir ve bu MIME tipiyle sunulan dosyalar sıkıştırılmadan transfer edilmeye devam eder. Daha kompakt bir alternatif FilesMatch bloğuyla birlikte SetOutputFilter DEFLATE kullanmaktır; ancak bu yaklaşım MIME tipine değil dosya uzantısına göre çalışır ve sunucu doğru MIME tipi dönmüyorsa etkisiz kalır. MIME tabanlı yapılandırma daha güvenilirdir. Bu listeyi elle yönetmek yerine, sıkıştırma, önbellek ve güvenlik kurallarını birlikte oluşturmak için hazır bir araç bu riski ortadan kaldırır.

Sıkıştırma seviyesi için isteğe bağlı olarak DeflateCompressionLevel direktifi eklenebilir:

<IfModule mod_deflate.c>
    DeflateCompressionLevel 6
</IfModule>

1'den 9'a kadar değer alır. 1 en hızlı, en az sıkıştırma; 9 en yavaş, en çok sıkıştırmadır. Apache'nin varsayılanı 6'dır ve çoğu durumda bu değer optimale yakındır. 9'a çıkarmak CPU kullanımını artırır; sıkıştırma oranındaki kazanç ise genellikle ölçülemez düzeyde kalır.

Hangi Dosyalar Sıkıştırılmamalı

Yukarıdaki MIME listesinde JPEG, PNG, WebP, GIF veya MP4 yer almaz. Bu bir eksiklik değil, bilinçli bir tercihtir.

Görsel formatlar kendi sıkıştırma algoritmalarını içerir; kayıpsız (PNG) veya kayıplı (JPEG, WebP) olarak halihazırda verimli biçimde kodlanmıştır. Bu dosyalara mod_deflate uygulandığında sunucu CPU döngüsü harcar, transfer boyutunda anlamlı bir azalma sağlanamaz; kimi zaman dosya boyutu marjinal miktarda artar. Buna "double compression" denir: zaten sıkıştırılmış binary veri üzerine GZIP uygulamak yalnızca işlemci yükü yaratır.

woff2 formatı bu konuda özel bir yerde durur. woff2 dosyaları Brotli sıkıştırmasıyla paketlenmiş binary fontları içerir; GZIP uygulanması teorik olarak çok küçük bir kazanç sağlayabilir ama pratikte ölçülebilir bir fark yaratmaz. font/woff2 tipini GZIP listesine eklememek daha temiz bir yapılandırmadır.

Listeye dahil edilmesi gereken tek tartışmalı format SVG'dir. SVG dosyaları XML tabanlı metin içerir ve sıkıştırmadan verimli şekilde yararlanır; bu nedenle image/svg+xml MIME tipi listede bulunmalıdır. SVG'yi görsel kategorisinde değerlendirerek MIME listesinden çıkaran yapılandırma, özellikle inline olmayan ikon setlerinde ölçülebilir bir transfer büyüklüğü kaybına yol açar.

Format bilgisi olmadan liste eksik kalır.

Sıkıştırmanın Çalıştığını Doğrulama

Kural .htaccess'e yazıldı, sunucu yeniden yüklendi. Peki GZIP gerçekten aktif mi?

Doğrulama için en güvenilir yöntem curl komutudur:

curl -H "Accept-Encoding: gzip" -I https://www.ornek-site.com/style.css

Yanıtta Content-Encoding: gzip satırı görünüyorsa sıkıştırma aktiftir. Bu satır yoksa mod_deflate çalışmıyor ya da ilgili MIME tipi listede eksik demektir. -I bayrağı sadece başlıkları çeker, dosya içeriğini indirmez; bu nedenle büyük dosyalarda kontrol süresi saniyeler içinde tamamlanır.

Chrome DevTools ile de doğrulama yapılabilir: Network sekmesinde bir CSS veya JS dosyasına tıklanıp Response Headers bölümüne bakıldığında Content-Encoding: gzip satırı görünmelidir. Network sekmesindeki "Size" sütunu iki değer gösterir: transferde kullanılan sıkıştırılmış boyut ve gerçek içerik boyutu. İkisi arasındaki fark GZIP kazancını doğrudan yansıtır.

GZIP aktifken Apache yanıt başlıklarına otomatik olarak Vary: Accept-Encoding ekler. Bu başlık, ara önbellek sunucularına (CDN, proxy) sıkıştırılmış ve sıkıştırılmamış yanıtın ayrı önbellek girdileri olarak saklanması gerektiğini bildirir. Bu başlık eksikse bir ara önbellek sıkıştırılmış yanıtı kaydeder ve Accept-Encoding göndermeyen eski bir istemciye sıkıştırılmış içeriği gönderebilir; istemci bu içeriği açamaz ve sayfa bozuk görünür. curl çıktısında Vary: Accept-Encoding satırını da doğrulamak bu yüzden kontrol listesinin bir parçası olmalıdır.

Sayfa performans analizi yapılırken Lighthouse da bu konuyu denetler. Sıkıştırılmamış metin varlıkları "Enable text compression" uyarısıyla işaretlenir ve tahmin edilen tasarruf kilobayt cinsinden gösterilir. Bu uyarı alınıyorsa GZIP yapılandırmasında eksiklik var demektir.

AllowOverride Eksikse GZIP Sessizce Devre Dışı Kalır

Bu durum en sık karşılaşılan ve en uzun süre fark edilmeyen sorundur.

Apache'de .htaccess dosyalarının etkili olabilmesi için sunucu yapılandırmasında ilgili dizin için AllowOverride All ya da en azından AllowOverride Options ayarlanmış olmalıdır. Varsayılan değer AllowOverride None'dur ve bu ayarla .htaccess içindeki tüm direktifler, hata vermeksizin, sessizce görmezden gelinir. GZIP kuralı yazılır, sunucu başlatılır, yanıt başlıklarında Content-Encoding: gzip görünmez; üstelik Apache error log'unda da herhangi bir iz bırakmaz.

Paylaşımlı hosting ortamlarında AllowOverride genellikle açıktır çünkü kullanıcılar .htaccess üzerinden kendi yapılandırmalarını yönetir. Kendi sunucusunda Apache kuran geliştiriciler ise httpd.conf ya da apache2.conf içinde ilgili dizin bloğunu kontrol etmelidir:

<Directory /var/www/html>
    AllowOverride All
</Directory>

mod_deflate'in yüklü olup olmadığı Apache 2.4'te şu komutla kontrol edilir:

apache2ctl -M | grep deflate

Çıktıda deflate_module (shared) veya deflate_module (static) görünüyorsa modül aktiftir. Debian/Ubuntu sistemlerde modül yüklü değilse sudo a2enmod deflate && sudo systemctl reload apache2 komutuyla etkinleştirilir. CentOS/RHEL tabanlı sistemlerde ise modül genellikle varsayılan kurulumda statik olarak derlenir; bu sistemlerde ayrıca etkinleştirme gerekmez.

Farklı bir hata senaryosu önbellek kaynaklıdır. CDN veya ters proxy katmanı devredeyse GZIP, .htaccess kuralından bağımsız olarak CDN tarafından uygulanıyor olabilir. Bu durumda curl komutu yine Content-Encoding: gzip döner; ancak kaynak sunucudan yanıt alındığında sıkıştırma olmadığı ortaya çıkar. CDN bypass edilerek kaynak IP adresine doğrudan curl atılması bu ayrımı netleştirir.

İkisi farklı başarısızlık; ikisi de sessiz.

GZIP bant genişliği maliyetini azaltır ve ilk bayt süresini (TTFB) etkiler; ama temel performans göstergeleri olan LCP, FCP ve CLS üzerindeki etkisi dolaylıdır. Sıkıştırılmış bir CSS dosyası daha hızlı indirilir, bu da render-blocking süresini kısaltır ve LCP değerini iyileştirir. Transfer öncesi kaynak boyutunu düşürmek için ise CSS ve JS dosyalarını minify etmek ayrı bir adımdır; iki kazanım toplamlıdır, ama farklı katmanlarda gerçekleşir. Büyük render-blocking JS dosyaları veya optimize edilmemiş görseller GZIP'ten bağımsız sorunlardır; GZIP bu sorunları örtmez, yalnızca metin transferini hafifletir.