Saf PHP ile 3 Milisaniyede Sayfa Açmak
Framework kullanmadan saf PHP ile yazdığım bu sitede sayfalar 3 milisaniyede açılıyor. Sırrı statik HTML cache mimarisinde.
Giriş: Neden 3 Milisaniye?
Kullanıcı bir siteye girdiğinde, ilk 3 saniyede ne olursa olsun, siteyi ya sever ya da kapatır. Google da bunu biliyor — Core Web Vitals'ı sıralama faktörü yaptı. Ama işin aslı şu: 3 saniye değil, 3 milisaniye.
Bu siteyi (bilginsayar.com) framework kullanmadan, saf PHP ile yazdım. Sunucu tarafında sayfa üretimi ortalama 3 milisaniye sürüyor. Bu yazıda, bu hızın nasıl elde edildiğini, hangi mimariyi kullandığımı ve kodun nasıl çalıştığını anlatacağım.
Framework'süz bir yaklaşımın en büyük avantajı şu: Kullanmadığın hiçbir şeyi taşımıyorsun. Ne ORM, ne template engine, ne de routing kütüphanesi. Sadece ihtiyacın olan kod.
Statik HTML Cache Nedir?
Klasik bir PHP sitesinde her istek şu yolu izler:
- PHP çalışır
- Veritabanına bağlanır
- Sorgular çalışır
- HTML üretilir
- Kullanıcıya gönderilir
Bu zincir her seferinde tekrarlanır. 10-30 ms sürer tipik olarak. Ama içerik değişmediği sürece bu işi tekrar yapmanın anlamı yok.
Statik HTML cache tam burada devreye giriyor:
- İlk istek: PHP çalışır, HTML üretilir, diske yazılır
- Sonraki istekler: HTML doğrudan diskten okunur, PHP hiç çalışmaz
Bu sitenin sistem/cache.php dosyası, bu işi yaklaşık 120 satırda yapıyor.
Mimari: cache.php Nasıl Çalışıyor?
Cache sisteminin çalışma akışı şöyle:
Bu fonksiyon, sayfa her yüklendiğinde router.php tarafından çağrılır. Eğer cache dosyası varsa, doğrudan gönderilir ve exit ile PHP sonlandırılır. Yoksa, çıktı tamponlanır, hem kullanıcıya gönderilir hem de diske yazılır.
Cache Anahtarının Üretimi
Cache dosya adı, istek URL'sinden türetilir:
Bu sayede her benzersiz URL için bir cache dosyası oluşur. Query string varsa cache sunulmaz — çünkü ?v=1, ?sayfa=2 gibi parametreler farklı içerik üretir.
Cache'in Atlanması Gereken Durumlar
Her istek cache'lenemez. Örneğin:
- POST istekleri — kullanıcı verisi gönderiyor
- Oturum açmış kullanıcılar — kişiselleştirilmiş içerik
- Query string içeren URL'ler — dinamik parametre var
- Admin panel istekleri — gerçek zamanlı veri gerekli
Kod içinde bu kontroller şöyle yapılır:
Araç sayfaları gibi özel durumlarda, araç sınıfı $GLOBALS['bscacheyok'] = true; atayarak cache'i devre dışı bırakabilir.
Brotli + Gzip: Çift Sıkıştırma
Statik cache tek başına yeterli değil. HTML dosyası 40-80 KB olabilir. Bunu kullanıcıya sıkıştırılmış göndermek gerekir.
Sistem iki katmanlı sıkıştırma kullanıyor:
- Brotli (
.bruzantılı) — modern tarayıcılar için, ~%75 sıkıştırma - Gzip (
.gzuzantılı) — yedek olarak, ~%70 sıkıştırma
Cache yazıldığında, her iki versiyon da üretilir:
.htaccess dosyası, tarayıcının Accept-Encoding başlığına göre doğru dosyayı sunar:
Bu sayede:
- Chrome/Firefox/Edge → Brotli alır (~%75 küçülür)
- Eski tarayıcılar → Gzip alır (~%70 küçülür)
- Desteklemeyen → Ham HTML alır (nadir)
.htaccess ile Doğrudan Servis
Cache'in asıl gücü burada ortaya çıkıyor. .htaccess kuralları sayesinde PHP hiç devreye girmiyor — Apache/LiteSpeed doğrudan dosyayı sunuyor.
Bu, sunucunun işlemciyi yormasını engelliyor. 1000 eşzamanlı ziyaretçi gelse bile, PHP-FPM havuzu tükenmiyor. Çünkü sadece dosya okuma yapılıyor.
İşte public_html/.htaccess içindeki kritik kurallar:
filemtime ile Cache Busting
Statik cache'in klasik sorunu: içerik güncellendiğinde kullanıcı hâlâ eski cache'i görür.
Çözüm: filemtime(). CSS ve JS dosyalarının URL'sine, dosyanın son değişiklik zamanı eklenir:
Bu sayede stil.css dosyasını değiştirdiğinde, URL otomatik olarak stil.css?v=1791516324 olur. Tarayıcı yeni URL'yi yeni dosya olarak algılar ve cache'i atlar.
HTML cache için ise farklı bir strateji kullanılır: admin panelden içerik kaydedildiğinde, registershutdownfunction ile ilgili cache dosyaları silinir. Otomatik bildirim sistemi de tetiklenir — Google ve Bing 1 dakika içinde haberdar olur.
Gerçek Ölçüm: 3 ms Nasıl Ölçüldü?
Lafı bırakalım, rakamlara bakalım. Chrome DevTools → Network sekmesi → "Disable cache" kapalıyken:
| Sayfa | TTFB | Toplam | Boyut (Brotli) |
|---|---|---|---|
| Ana sayfa | 3.2 ms | 11.4 ms | 8.9 KB |
| Blog yazı | 3.8 ms | 12.1 ms | 11.2 KB |
| Araç sayfası | 4.1 ms | 14.3 ms | 13.5 KB |
TTFB (Time To First Byte) — yani sunucudan ilk byte'ın gelme süresi — 3-4 ms arasında. Bu, sunucunun PHP'yi hiç çalıştırmadığının kanıtı. Nginx/Apache neredeyse anında dosyayı gönderiyor.
Karşılaştırma için: Ortalama bir WordPress sitesi 150-400 ms TTFB verir. Bu site, o sitelerden 50-100 kat daha hızlı.
Lighthouse: 100/100/100/100
Performans sadece TTFB değil. Lighthouse 4 kategorisinin tamamında 100 puan almak için şunları da yaptık:
- Harici CDN yok — font, JS, CSS hepsi kendi sunucumuzda
- Inline CSS/JS yok — tek dosya, minify, Brotli
- Görsel pipeline — AVIF + WebP + JPEG × 4 boyut = 13 dosya, tarayıcı en uygunu seçer
- Font optimizasyonu —
font-display: swap+ subset - Kritik CSS — ilk render için gerekli kısım
<head>içinde
Lighthouse'un "100" vermesi bir gurur vesilesi değil aslında — sadece temel hijyen. Ama ne yazık ki web'in %90'ı bu hijyene sahip değil.
Özet: 7 Adımda 3 ms
Bu yazının özeti şu:
- Statik HTML cache — PHP'yi atla
- Brotli + Gzip — çift sıkıştırma
.htaccessdoğrudan servis — sunucu işlemcisini koru- filemtime cache busting — kullanıcı güncel içeriği görsün
- Harici CDN yok — tek sunucu, tek sorumluluk
- Görsel pipeline — AVIF/WebP/JPEG × 4 boyut
- Lighthouse 100 — hijyen, gurur değil
Framework kullanmadan da modern, hızlı ve güvenli bir site yazmak mümkün. Hatta — kendi deneyimime dayanarak söylüyorum — çoğu zaman daha hızlı ve daha az sorunlu.
Son Bir Not
Bu mimariyi beğendiyseniz ve kendi projeniz için uyarlamak isterseniz — bir müşteri işi, kişisel blog, kurumsal site fark etmez — benimle iletişime geçebilirsiniz. Framework'süz, özel kodlu çözümler üretiyorum.
Bir sonraki yazıda, AI arama motorlarının Türkçe içerikleri nasıl okuduğunu ve llms.txt standardını anlatacağım.
Bu yazıyı faydalı buldunuz mu?
Yeni analiz, blog yazısı veya araç yayınladığımızda kısa bir e-posta gönderiyoruz. Reklam yok, spam yok, istediğiniz an tek tıkla çıkabilirsiniz.