Yavaş Bir WordPress Sitesini Hızlandırmak: Gerçekte İzlediğim Sıra
Reklam
"WordPress sitemiz aşırı derecede yavaşladı", açık ara en sık aldığım taleplerden biridir. Çoğu insan için ilk içgüdü, körü körüne bir eklenti (plugin) kurmaktır. Bu genelde bir görsel optimize edici veya tek tıkla her şeyi çözeceğini yüksek sesle vaat eden bir "hızlandırıcı" eklentidir.
Bu bazen gerçekten de biraz işe yarar. Ancak o devasa, gözle görülür performans artışları neredeyse her zaman WordPress'in eklenti ekosistemiyle kesinlikle hiçbir alakası olmayan şeylerden gelir. Bunları yanlış bir sırayla yapmak; gecikmenin %90'ına neden olan asıl sunucu darboğazına (bottleneck) daha dokunmadan, sadece %10'luk bir frontend iyileştirmesi için saatlerce boşa kürek çekmek demektir.
Birinci Adım: Sorun sunucuda mı, yoksa sayfada mı?
Tek bir ayara bile dokunmadan önce, doğrudan Time to First Byte (TTFB) yani İlk Bayta Kadar Geçen Süre'yi katı bir şekilde kontrol ederim. Bu, tarayıcının tüm o ağır görselleri ve scriptleri indirip (render) işlemesinin ne kadar sürdüğünden tamamen bağımsız olarak, sunucunun yanıt vermeye başlamasının tam olarak ne kadar sürdüğünü ölçer:
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s\n" https://example.com
Çıkış yapmış (logged-out) basit bir sayfada yarım saniyenin üzerinde gezinen bir TTFB değeri, genellikle WordPress'in her bir istekte (request) umutsuzca ağır bir yük kaldırmaya çalıştığı anlamına gelir. Veritabanı aktif olarak sorgulanıyordur, PHP agresif bir şekilde yürütülüyordur ve kesinlikle hiçbir şey önbelleğe (cache) alınmıyordur.
Ateş gibi hızlı bir TTFB'nin yanında inanılmaz derecede yavaş bir sayfa yüklemesi varsa, bu doğrudan frontend sorunlarına işaret eder: aşırı büyük görseller, devasa optimize edilmemiş scriptler veya sayfa yüklemesini engelleyen (blocking) fontlar. Bu çözülmesi tamamen farklı (ve genellikle çok daha kolay) bir sorundur.
Eğer sorun sunucudaysa: Katmanlar halinde Önbellekleme (Caching)
Her bir ziyaretçiye tamamen aynı görünen, dışa açık bir WordPress sayfasının (ki çoğu sitedeki sayfaların %95'i böyledir), gelen her bir istekte PHP ve MySQL'i sıfırdan çalıştırmasına kesinlikle gerek yoktur.
Sağlam bir sayfa önbelleği (page cache)—ister WP Super Cache gibi sağlam bir eklenti aracılığıyla halledilsin, ister çok daha iyisi olan Nginx'in fastcgi_cache'i ile tamamen sunucu seviyesinde yapılsın—statik bir HTML kopyası sunar ve PHP'yi tamamen atlar. Sadece bu tek değişiklik, 800ms'lik bir TTFB ile 50ms'lik bir TTFB arasındaki o dramatik farkı yaratır. Bu, sunucuyu "WordPress'i baştan ayağa başlatmaya" zorlamak ile ondan sadece "bana bir metin dosyası ver" demek arasındaki harfi harfine o devasa farktır.
Oturum açmış kullanıcılar, WooCommerce sepetleri veya dinamik olan herhangi bir şey gibi PHP'nin gerçekten çalışmasına ihtiyaç duyan istekler için ise bir nesne önbelleği (Redis veya Memcached gibi bir object cache) zorunludur. WordPress'in veritabanı sorgularının ham sonuçlarını acımasızca önbelleğe alır. Bu sayede tekrarlanan sorgular (ki WordPress aynı sorguyu sayfa yüklenirken defalarca tekrarlar), MySQL'i dövmek yerine anında RAM'den gelir:
// wp-config.php, bir Redis nesne önbelleği (object cache) eklentisi kurduktan sonra
define('WP_REDIS_HOST', '127.0.0.1');
define('WP_REDIS_PORT', 6379);
define('WP_CACHE', true);
Son olarak, PHP'nin yerel OPcache'i doğrudan derlenmiş PHP bayt kodunun (bytecode) kendisini önbelleğe alır. Böylece tamamen aynı PHP dosyaları, gelen her bir istekte sıfırdan acı verici bir şekilde tekrar derlenmez. Bu özelliğin php.ini dosyasında kalıcı olarak etkinleştirilmesi yeterlidir. Kesinlikle hiçbir WordPress'e özel yapılandırma gerektirmez ve sunucudaki her bir PHP isteğini evrensel olarak hızlandırır.
Veritabanı sessizce ağır bir yük biriktirir
WordPress veritabanı, siteyi şiddetli bir şekilde aşağı çekene kadar gözle görülür bir şekilde ortaya çıkmayan yollarla yavaş yavaş büyür. Yazı revizyonlarını (her bir otomatik kaydetmenin sessizce yeni bir veritabanı satırı oluşturması), süresi dolmuş "transient" verilerini (çoğu zaman hiçbir zaman temizlenmeyen geçici önbelleğe alınmış veriler) ve silinmiş eklentilerin arkasında bıraktığı devasa yetim (orphaned) meta verileri düşünün.
Bunların hiçbiri yepyeni, küçük bir sitede dramatik değildir. Ancak üç yıldır çalışan yoğun bir sitede, sadece "otomatik yüklenen" (autoloaded) seçeneklerin—yani gerçekten ihtiyaç duyulup duyulmadığına bakılmaksızın her bir sayfa isteğinde agresif bir şekilde belleğe yüklenen seçeneklerin—megabaytlarca saf çöp oluşturduğu bir wp_options tablosu bulmak inanılmaz derecede yaygındır:
SELECT option_name, LENGTH(option_value) AS size
FROM wp_options
WHERE autoload = 'yes'
ORDER BY size DESC LIMIT 10;
Burada iki yıl önce silinmiş bir eklentiden kalma devasa büyüklükteki herhangi bir veri, gelen her bir isteğe eklenen saf ve acı verici bir yüktür (overhead). Bunu temizlemek körü körüne tahmin yürütmeyi gerektirmez; o SQL sorgusu size o ölü ağırlığın tam olarak nerede saklandığını acımasızca söyler.
Ardından, ve kesinlikle ancak o zaman, Frontend gelir
Sunucu nihayet hızlı bir şekilde yanıt vermeye başladığında, frontend optimizasyonu aslında üzerine bir şeyler inşa edebileceğiniz sağlam bir temele sahip olur. Görselleri gecikmeli yüklemek (lazy-load), sadece WebP gibi modern formatlar sunmak ve kritik olmayan JavaScript'leri aktif olarak ertelemek ancak o zaman bir anlam ifade eder.
Acı verici derecede yavaş, 800ms TTFB değerine sahip bir sitede kalkıp önce bu frontend işlerini yapmak; bir arabanın görünmeyen %80'i (motoru) aktif olarak yanarken, sadece dışarıdan görünen %20'sini parlatmaya benzer. Tarayıcı henüz sayfayı işlemeye başlamadan önce boşa geçen o muazzam süreye kesinlikle dokunulmamış olur.
Bu spesifik sıra neden bu kadar önemlidir?
Bu belirli adımların her biri kendi başına faydalıdır, ancak bu katı sıra (order), yavaş bir WordPress sitesinde işlem süresinin aslında tam olarak nereye gittiğini yansıtır.
Sunucu taraflı sayfa önbelleği, dışa açık (logged-out) trafiğin neden olduğu gecikmenin en büyük kısmını agresif bir şekilde çözer. Nesne önbelleği (object cache) ve OPcache, geri kalan her şey için doğrudan WordPress'in kendisinin yarattığı o acımasız işlem (compute) maliyetini ele alır. Derinlemesine bir veritabanı temizliği, her bir sayfayı aşağı çeken o birikmiş ölü ağırlığı kalıcı olarak ortadan kaldırır. Ve en son olarak, frontend optimizasyonu geriye kalan her ne varsa onu parlatır.
Sırf gözünüzün önünde, çok daha görünür olduğu için işe o listenin en altından başlamak—örneğin bir görseli sıkıştırmak veya bir scripti küçültmek (minify)—insana son derece üretken hissettirir. Ancak gerçekte yaptığınız şey, toplam yükleme süresinin olabilecek en küçük parçasını ilk önce optimize etmektir.
Reklam