Bir gün sitenizin kaynak kodunu açıp bakarsınız ve yazdığınız hiçbir şeye benzemediğini görürsünüz: CSS dosyalarınız birleşip A.style.css.pagespeed.cf.xTk3.css gibi tuhaf isimler almış, HTML'den boşluklar ve yorumlar silinmiş, resimlerin bir kısmı WebP'ye dönmüş, üstelik sayfanın içine sizin yazmadığınız bir satır JavaScript girmiş. Panikleyip sunucuya bakarsınız; suçlu Apache'nin mod_pagespeed modülüdür ve büyük ihtimalle sunucuyu kuran kişi ya da hosting sağlayıcısı onu varsayılan olarak açık bırakmıştır. mod_pagespeed, siz hiçbir kod satırına dokunmadan sayfalarınızı yeniden yazan bir optimizasyon katmanıdır; doğru kullanıldığında gerçekten hızlandırır, yanlış kullanıldığında ise haftalarca teşhis edemeyeceğiniz hatalar üretir.
Bu rehberde mod_pagespeed'in ne yaptığını, hangi filtrelerin gerçekten değer kattığını, hangilerinin bugünün web'inde zararlı olduğunu ve en kritik iki riski — Content Security Policy çakışması ile yıllarca canlı kalan agresif kaynak önbelleği — gerçek çıktı örnekleriyle anlatacağım. Ayrıca modülün açık olup olmadığını nasıl anlarsanız, tek bir sayfada nasıl devre dışı bırakırsınız ve modern alternatiflerin ne olduğunu göstereceğim. Amaç modülü kötülemek değil; ne zaman işinize yarayacağını, ne zaman sizi yavaşlatmak yerine sadece riske sokacağını ayırt edebilmeniz.
mod_pagespeed Ne Yapar ve Nerede Devreye Girer#
mod_pagespeed, Apache'nin çıktı filtresi (output filter) olarak çalışır. Yani PHP ya da hangi uygulama katmanı sayfayı üretirse üretsin, sonuç tarayıcıya gitmeden hemen önce modülün elinden geçer. Modül HTML'i ayrıştırır, içindeki CSS, JavaScript ve görsel referanslarını bulur, bunları arka planda indirir, optimize eder, kendi disk önbelleğine yazar ve HTML'deki referansları optimize edilmiş yeni sürümlere çevirir. Bu yüzden uygulamanızda hiçbir değişiklik yapmadan sonuç alırsınız — ve bu yüzden yaptığı şeyi kontrol etmek zordur.
Kritik nokta şudur: mod_pagespeed sadece HTML'i değil, kaynakları da yerinde optimize eder. in_place_resource_optimization açıkken siz /assets/logo.png isteseniz bile modül kendi optimize ettiği sürümü döner, dosya adı hiç değişmemiş olsa dahi. Bunu yanıt başlıklarından anlayabilirsiniz:
# Modül açık mı, hangi sürüm çalışıyor?
curl -sI https://firmaniz.com/ | grep -i 'x-mod-pagespeed\|x-page-speed'
# X-Mod-Pagespeed: 1.13.35.2-0
# Bir görselin gerçekten modülden mi geldiğine bakın
curl -sI https://firmaniz.com/assets/logo.png | grep -Ei 'etag|content-length|cache-control'
# etag: W/"PSA-abcd1234"
# x-original-content-length: 86539
# cache-control: max-age=31536000
PSA- ön ekli bir ETag ve x-original-content-length başlığı gördüyseniz, o dosyayı size Apache'nin diskteki hâli değil, mod_pagespeed'in kendi önbelleği veriyor demektir. Bu ayrım ileride anlatacağım "değiştirdim ama değişmedi" tuzağının tam merkezindedir. Sunucu tarafındaki diğer önbellek katmanlarının nasıl sıralandığını sunucu tarafı önbellekleme katmanları yazısında bulabilirsiniz; mod_pagespeed bu zincirde uygulamanın çıkışına en yakın halkadır.
Kurulum ve Temel Yapılandırma#
Debian ve Ubuntu tarafında modül Google'ın yayınladığı .deb paketiyle gelir; kurulum sonrası Apache'ye pagespeed modülü olarak eklenir. Kurulduktan sonra ilk yapmanız gereken şey açıp bırakmak değil, kapalı başlatıp bilinçli filtre açmaktır:
# /etc/apache2/mods-available/pagespeed.conf
<IfModule pagespeed_module>
# Genel anahtar. "unplugged" tamamen devre dışı bırakır.
ModPagespeed on
# Optimize edilmiş kaynakların tutulduğu disk önbelleği
ModPagespeedFileCachePath "/var/cache/mod_pagespeed/"
ModPagespeedFileCacheSizeKb 1048576 # ~1 GB
ModPagespeedFileCacheCleanIntervalMs 3600000 # saatte bir temizlik
# Varsayılan filtre setini KAPAT, sadece istediklerini aç
ModPagespeedRewriteLevel PassThrough
ModPagespeedEnableFilters collapse_whitespace,remove_comments
ModPagespeedEnableFilters rewrite_css,rewrite_javascript
ModPagespeedEnableFilters recompress_images,convert_jpeg_to_webp
# Yönetim arayüzü — dışarıya AÇIK BIRAKMAYIN
<Location /pagespeed_admin>
Require ip 127.0.0.1
</Location>
</IfModule>
ModPagespeedRewriteLevel PassThrough satırı en önemli tercihtir. Varsayılan seviye CoreFilters'tır ve tek satır yazmadan onlarca filtreyi birden açar; bir sorun çıktığında hangisinin sebep olduğunu bulmak saatlerinizi alır. PassThrough ile başlayıp filtreleri tek tek ekleyerek her adımda ölçüm yapmak çok daha sağlıklıdır. Yapılandırmayı değiştirdikten sonra söz dizimini doğrulayıp Apache'yi nazikçe yeniden yükleyin:
# Yapılandırma söz dizimi kontrolü
apachectl configtest
# Syntax OK
# Bağlantıları kesmeden yeniden yükle
systemctl reload apache2
# Modül gerçekten yüklü mü
apachectl -M | grep -i pagespeed
# pagespeed_module (shared)
Filtreler: Hangisi Değer Katar, Hangisi Bugün Zararlı#
Filtrelerin hepsi eşit değildir. Bazıları tamamen güvenli ve ölçülebilir kazanç sağlar; bazıları ise HTTP/2 ve modern tarayıcı davranışlarıyla birlikte anlamsızlaştı, hatta ters etki yapar hâle geldi. Aşağıdaki tablo sahada gördüğüm davranışın özetidir:
| Filtre | Ne yapar | Değerlendirme |
|---|---|---|
collapse_whitespace | HTML'deki fazla boşlukları siler | Güvenli, küçük ama bedava kazanç |
remove_comments | HTML yorumlarını siler | Güvenli; sunucu tarafı yorumlarına dikkat |
rewrite_css | CSS'i küçültür, yeniden yazar | Genelde güvenli, kaynak haritalarını bozar |
recompress_images | JPEG/PNG'yi yeniden sıkıştırır | Faydalı; CPU maliyeti var |
convert_jpeg_to_webp | Uygun tarayıcıya WebP döner | Faydalı; Vary başlığını doğrulayın |
extend_cache | Dosya adına hash ekleyip 1 yıl önbellekler | Güçlü ama en riskli filtre |
combine_css / combine_javascript | Dosyaları tek dosyada birleştirir | HTTP/2'de gereksiz, çoğu zaman zararlı |
defer_javascript | Script'leri erteler ve inline kod ekler | CSP kırar, çalışma sırasını bozar |
lazyload_images | Görselleri geciktirir, inline JS ekler | Yerine loading="lazy" kullanın |
inline_preview_images | Düşük çözünürlüklü ön izleme gömer | Inline beacon ekler, CSP kırar |
Buradaki en önemli mesaj şudur: combine_css ve combine_javascript HTTP/1.1 dünyasının çözümleridir. O dönemde tarayıcı aynı ana bilgisayara aynı anda altı bağlantı açabildiği için dosya sayısını azaltmak gerçekten hızlandırıyordu. HTTP/2 ve HTTP/3 ile birlikte tek bağlantı üzerinden çoklama (multiplexing) geldi; artık dosyaları birleştirmek küçük bir CSS değişikliğinde koca bir paketin önbellekten düşmesine yol açar, yani net zarardır. Aynı şekilde lazyload_images filtresine de bugün gerek yoktur; tarayıcıların kendi loading="lazy" özelliği hem daha hızlı hem de JavaScript gerektirmiyor. Görsel ve düzen kaynaklı yavaşlıkları ölçmek için LCP nasıl iyileştirilir ve CLS düzen kayması nasıl düzeltilir yazılarındaki yöntemler mod_pagespeed'in "otomatik" vaadinden çok daha kalıcı sonuç verir.
En Büyük Risk: CSP ve Inline Script Çakışması#
mod_pagespeed'in bazı filtreleri iş yapabilmek için sayfaya kendi JavaScript'ini gömer. lazyload_images, defer_javascript, inline_preview_images ve kritik CSS filtreleri, ürettikleri HTML'e satır içi (inline) script blokları ve hatta onload= gibi olay öznitelikleri ekler. Eğer sitenizde bir Content Security Policy varsa — ki modern bir kurulumda olmalı — bu inline kodlar politikayı ihlal eder ve tarayıcı tarafından bloklanır. Sonuç, tarayıcı konsolunda şuna benzer hatalardır:
Refused to execute inline script because it violates the following
Content Security Policy directive: "script-src 'self' 'sha256-...'".
Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce is required.
Refused to execute inline event handler because it violates the following
Content Security Policy directive: "script-src ...".
Bu tuzağın sinsi tarafı şudur: CSP'yi build sırasında üretilen bir hash ile kurduysanız, mod_pagespeed'in eklediği kod build'den sonra doğduğu için hiçbir hash onu kapsayamaz. Olay özniteliklerini (onload=, onerror=) hash ile kapsamak zaten mümkün değildir; onları izin vermenin tek yolu 'unsafe-inline' ya da 'unsafe-hashes' eklemektir ki bu da CSP'nin varlık sebebini ortadan kaldırır. Yani "biraz hız için" politikanızı delmiş olursunuz.
Doğru karar sırası şudur:
- Önce CSP hatalarının gerçekten modülden gelip gelmediğini doğrulayın: aynı sayfayı
?PageSpeed=offsorgu parametresiyle açın ve konsolu karşılaştırın. - Hatalar kayboluyorsa, inline kod üreten filtreleri kapatın (
defer_javascript,lazyload_images,inline_preview_images, kritik CSS filtreleri). - Sorun sürüyorsa modülü tamamen kapatın ve optimizasyonu uygulama katmanına taşıyın.
# Sadece belirli bir sanal sunucuda modülü tamamen devre dışı bırak
<VirtualHost *:443>
ServerName firmaniz.com
ModPagespeed unplugged
</VirtualHost>
ModPagespeed off ile ModPagespeed unplugged arasındaki fark önemlidir: off modülü pasif hâle getirir ama ?PageSpeed=on ile tekil olarak açılabilir durumda bırakır; unplugged ise tamamen devre dışı bırakır ve o sanal sunucuda hiçbir şekilde çalışmaz. Kalıcı kapatma için unplugged kullanın.
Önbellek Riski: Bir Yıl Yaşayan Eski Dosyalar#
İkinci büyük risk sessizdir ve genellikle bir dosya değiştirdiğinizde ortaya çıkar. extend_cache filtresi ve yerinde kaynak optimizasyonu, dosyaları kendi diskindeki önbelleğe alır ve Cache-Control: max-age=31536000 ile, yani bir yıl boyunca geçerli olacak şekilde sunar. Sunucudaki dosyayı değiştirdiğinizde modül bunu er ya da geç fark eder; ancak arada, deploy ettiğiniz yeni logonun ya da paylaşım görselinin eski hâlinin sunulduğu bir pencere vardır — ve bu pencere bazı yapılandırmalarda hiç kapanmaz.
Bu tam olarak şu senaryoda can yakar: sosyal medya paylaşım görselini (og:image) değiştirirsiniz, deploy başarılı olur, dosyayı sunucuda ls -l ile görürsünüz, ama WhatsApp ya da LinkedIn önizlemesinde hâlâ eski görsel çıkar. Çünkü paylaşım robotları dosyayı Apache'den değil, mod_pagespeed'in yıl boyu geçerli önbelleğinden alır. Teşhis basittir:
# Diskteki gerçek dosya boyutu
ls -l /var/www/firmaniz.com/assets/og-image.png
# -rw-r--r-- 1 www-data www-data 78412 Aug 25 10:12 og-image.png
# Ağdan dönen boyut — farklıysa araya bir optimize edici girmiş demektir
curl -sI https://firmaniz.com/assets/og-image.png | grep -Ei 'content-length|etag'
# content-length: 86539
# etag: W/"PSA-9f2c11ab"
ls ile curl farklı boyut söylüyorsa ve ETag PSA- ile başlıyorsa, kesinlikle mod_pagespeed önbelleğine bakıyorsunuz. Çözüm önbelleği boşaltmaktır:
# Modülün tüm önbelleğini geçersiz kıl (dosyaları silmeden)
touch /var/cache/mod_pagespeed/cache.flush
# Ya da doğrudan silip yeniden oluştur
systemctl stop apache2
rm -rf /var/cache/mod_pagespeed/*
mkdir -p /var/cache/mod_pagespeed && chown -R www-data:www-data /var/cache/mod_pagespeed
systemctl start apache2
cache.flush dosyasına dokunmak modüle "elindeki her şeyi bayat kabul et" demenin resmi yoludur ve Apache'yi durdurmanızı gerektirmez; günlük operasyonda tercih edilen yöntem budur. Statik dosya önbelleğini .htaccess üzerinden bilinçli olarak yönetmeyi öğrenmek isterseniz htaccess önbellek ve sıkıştırma yazısı, aynı işi modülün sürprizleri olmadan yapmanın yolunu gösterir.
Sık Yapılan Hatalar ve Teşhis Yöntemleri#
Sahada tekrar tekrar gördüğüm hataların listesi kısadır ama pahalıdır. Birincisi, modülün açık olduğunu bilmemek. Birçok hazır sunucu imajı ve panel kurulumu mod_pagespeed'i varsayılan filtrelerle açar. Sitenizde açıklayamadığınız bir davranış varsa ilk kontrol edeceğiniz şey X-Mod-Pagespeed başlığıdır; sonra aynı sayfayı ?PageSpeed=off ile açıp farkı karşılaştırmaktır. Bu iki adım, "kodumda olmayan script nereden geliyor" sorusunun cevabını genellikle bir dakikada verir.
İkincisi, JavaScript sırasının bozulması. combine_javascript ve defer_javascript filtreleri script'leri birleştirir ve erteler. Kodunuz belirli bir yükleme sırasına bağlıysa — örneğin bir kütüphane global bir değişkeni tanımlıyor ve sonraki script onu kullanıyorsa — birleştirme sonrası ReferenceError alırsınız. Bu hata her sayfada değil, yalnızca belirli sayfalarda ve bazen yalnızca belirli tarayıcı sürümlerinde ortaya çıkar; bu yüzden teşhis edilmesi çok zordur.
Üçüncüsü, ölçüm yapmadan açık bırakmak. Modülü açtınız, "hızlandı herhalde" dediniz ve bir daha bakmadınız. Oysa recompress_images ve WebP dönüşümü CPU harcar; yoğun trafikte PHP-FPM ile aynı çekirdekleri paylaşan bir Apache süreci bu işi yaparken yanıt süreleri artabilir. Önce ve sonra ölçmeden hiçbir filtreyi kalıcı bırakmayın; ölçüm için GTmetrix ile WordPress hız testi yazısındaki yöntem iyi bir başlangıçtır.
Dördüncüsü, yönetim arayüzünü açık bırakmak. /pagespeed_admin ve /pagespeed_global_admin yolları modülün istatistiklerini, yapılandırmasını ve önbellek içeriğini gösterir. Erişimi IP ile kısıtlamazsanız, sunucunuzun iç yapılandırması hakkında dışarıya bilgi vermiş olursunuz. Yukarıdaki örnek yapılandırmadaki Require ip 127.0.0.1 satırı bu yüzden vardır.
Beşinci ve en gözden kaçan tuzak: arka planda bir HTML yeniden yazıcının olması, hesaplanmış hiçbir bütünlük güvencesini geçerli bırakmaz. Alt kaynak bütünlüğü (SRI) kullanıyorsanız ve modül o dosyayı yeniden yazıyorsa hash tutmaz, tarayıcı dosyayı bloklar. Aynı mantık build sırasında üretilen CSP hash'leri için de geçerlidir. Deterministik bir build üretiyorsanız, çıktısını sonradan değiştiren bir katman eklemek doğası gereği çelişkidir.
mod_pagespeed Yerine Ne Kullanmalı#
Şunu açıkça söylemek gerekir: Google, PageSpeed modüllerinin aktif geliştirmesini durdurdu ve depoyu arşivledi. Yani yeni bir Apache sürümüyle uyum sorunu ya da bir güvenlik açığı çıktığında bunu düzeltecek bir üst akış yoktur. Yeni bir kurulumda mod_pagespeed'i seçmek için güçlü bir sebebiniz olmalı; çoğu senaryoda yoktur.
Bugün aynı kazanımları çok daha öngörülebilir biçimde şu katmanlardan alırsınız:
| İhtiyaç | Modern karşılığı |
|---|---|
| Metin sıkıştırma | Web sunucusunda gzip/brotli (mod_deflate, mod_brotli) |
| Statik dosya önbelleği | Cache-Control başlıkları + içerik hash'li dosya adları |
| Görsel optimizasyonu | Build adımında WebP/AVIF üretimi ya da CDN görsel dönüşümü |
| CSS/JS küçültme | Uygulamanın build aracı (esbuild, Vite, webpack) |
| Tam sayfa önbelleği | FastCGI cache, LiteSpeed cache ya da ters vekil |
| Kritik CSS | Build sırasında üretilip şablona gömülen kritik CSS |
Bu listenin ortak özelliği şudur: hepsi build zamanında ya da açıkça yapılandırılmış bir katmanda olur, çalışma zamanında HTML'i sürpriz biçimde yeniden yazmaz. Böylece CSP'niz geçerli kalır, SRI hash'leriniz tutar, önbelleğiniz dosya adına gömülü hash sayesinde kendiliğinden tazelenir. Nginx tarafında aynı işi nasıl kurduğunuzu Nginx sıkıştırma ve statik önbellek yazısında, LiteSpeed karşılaştırmasını LiteSpeed vs Apache yazısında bulabilirsiniz.
Sıkça Sorulan Sorular#
mod_pagespeed açık mı nasıl anlarım#
En hızlı yol yanıt başlıklarına bakmaktır: curl -sI https://firmaniz.com/ | grep -i pagespeed komutu X-Mod-Pagespeed ya da X-Page-Speed başlığı döndürüyorsa modül aktiftir. İkinci bir işaret, HTML kaynağında .pagespeed. içeren dosya adları görmenizdir. Üçüncü kesin yöntem ise sunucuda apachectl -M | grep pagespeed komutunu çalıştırmaktır; modül yüklüyse listede görünür.
Tek bir sayfada mod_pagespeed'i nasıl kapatırım#
Herhangi bir URL'nin sonuna ?PageSpeed=off ekleyerek o istek için modülü devre dışı bırakabilirsiniz. Bu, bir hatanın modülden mi yoksa kendi kodunuzdan mı kaynaklandığını anlamanın en hızlı yoludur. Kalıcı olarak kapatmak isterseniz sanal sunucu bloğuna ModPagespeed unplugged satırını ekleyip Apache'yi yeniden yükleyin; off yerine unplugged kullanmak sorgu parametresiyle tekrar açılmasını da engeller.
mod_pagespeed siteyi gerçekten hızlandırır mı#
Optimize edilmemiş bir sitede evet, ölçülebilir bir kazanç sağlar; özellikle sıkıştırılmamış görseller ve küçültülmemiş CSS varsa fark belirgindir. Ancak zaten build adımında küçültme yapan, görsellerini WebP üreten ve önbellek başlıklarını doğru gönderen bir sitede kazanç neredeyse sıfırdır, buna karşılık CSP ve önbellek riskleri aynen durur. Kararı ölçerek verin: filtreleri açıp kapatarak aynı sayfayı test edin.
mod_pagespeed CSP hatalarına neden olur mu#
Evet, ve bu en yaygın şikâyettir. defer_javascript, lazyload_images ve ön izleme görseli ekleyen filtreler sayfaya satır içi script ve olay öznitelikleri gömer; katı bir script-src politikası bunları bloklar. Olay özniteliklerini hash ile izin vermek mümkün olmadığı için tek çıkış unsafe-inline eklemektir, bu da politikayı işlevsiz bırakır. Doğru çözüm inline kod üreten filtreleri kapatmaktır.
Görselimi değiştirdim ama eski hâli görünüyor, ne yapmalıyım#
Önce curl -sI ile dosyanın ETag'ine bakın; PSA- ile başlıyorsa dosyayı size mod_pagespeed'in önbelleği veriyordur. Bu durumda touch /var/cache/mod_pagespeed/cache.flush komutuyla önbelleğin tamamını geçersiz kılın; Apache'yi durdurmanız gerekmez. Sorun sürerse önbellek dizinini boşaltıp Apache'yi yeniden başlatın ve o dosya için önbellek uzatma filtresini kapatmayı düşünün.
mod_pagespeed hâlâ geliştiriliyor mu#
Hayır. Google PageSpeed modüllerinin aktif geliştirmesini sonlandırdı ve depo arşivlendi. Modül çalışmaya devam eder ama yeni Apache sürümleriyle uyum, yeni görsel biçimleri desteği ya da güvenlik düzeltmesi beklemeyin. Yeni kurulumlarda optimizasyonu build adımına ve web sunucusunun kendi sıkıştırma/önbellek direktiflerine taşımak daha sürdürülebilir bir tercihtir.
Nginx kullanıyorum, benzer bir modül var mı#
Nginx için ngx_pagespeed adında eşdeğer bir modül vardır ve aynı motoru kullanır, dolayısıyla aynı avantajları ve aynı riskleri taşır; o da arşivlenmiş durumdadır. Nginx tarafında gzip/brotli, expires direktifleri ve FastCGI önbelleği ile aynı kazanımların büyük kısmını sürpriz olmadan elde edebilirsiniz. Yapılandırmayı sunucu bloğunda açıkça yazmak, çalışma zamanında HTML'i yeniden yazan bir katmandan her zaman daha öngörülebilirdir.
Kapanış#
mod_pagespeed, hızlandırma işini uygulamadan alıp sunucuya taşıma fikrinin iyi bir örneğidir; ama bu fikrin bedeli, çıktınızın artık tam olarak sizin ürettiğiniz şey olmamasıdır. Aklınızda kalması gereken dört alışkanlık şudur: modülü PassThrough seviyesinde başlatıp filtreleri tek tek açmak, inline kod üreten filtrelerden CSP kullanan sitelerde uzak durmak, bir dosya değiştirdiğinizde curl -sI ile ağdan dönen boyutu diskteki boyutla karşılaştırmak ve şüphelendiğiniz her sayfayı ?PageSpeed=off ile bir kez daha açıp farkı görmek. Bu dört refleks, modülün ürettiği sorunların neredeyse tamamını dakikalar içinde teşhis etmenizi sağlar.
Performans işini otomatik bir modüle bırakmak yerine sağlam bir altyapı üzerine kurmak isterseniz Clou.TR tarafında bu işi büyük ölçüde sizin yerinize üstlenen seçenekler var. Yüksek trafikli siteler için ayarları hazır gelen kurumsal hosting ve WordPress hosting paketlerimizde önbellek ve sıkıştırma katmanları optimize edilmiş biçimde çalışır; kendi Apache ya da Nginx yapılandırmanızı baştan kurmak isterseniz tam root erişimli VDS sunucularımızı tercih edebilir, yapılandırmayı bize bırakmak isterseniz sunucu yönetimi hizmetimizden yararlanabilirsiniz.