Sayfa Yüklenme Hızını Optimize Edin (Güncellendi)

Tarayıcınıza bir internet adresi yazıp enter tuşuna bastığınız anda, 3 adımda gerçekleşen bir olay zinciri tetiklenir. Sayfa yüklenme hızı bir çok faktöre bağlıdır ve sitenin sunucu üzerinden son kullanıcıya servis edilmesi (sitenin açılması) için bir takım bağlantı protokollerinin kurulması gerekir. Bu bağlantılar oluşturulduktan sonra da veri aktarımı başlar.

Bir siteyi açmak için yapılan her istek ve bu isteğe geri dönen yanıt arasında geçen süreye round-trip times (yazıda bundan sonra RTT olarak bahsedilecektir) denilir ve HTTP’nin response ettiği ilk byte’lık datanın alımına kadar sürer. İnternet teknolojilerinde RTT terimini bir ping süresi olarak da düşünebilirsiniz. Bir çok web sitesinin açılması için düzinelerce RTT’ye ihtiyaç vardır. Fakat öncesinde ilk RTT’ye odaklanmak istiyorum.

İlk RTT DNS çözümlemesi için kullanılır, 2. RTT bir TCP bağlantısının kurulması için ve 3. RTT HTTP üzerinden yapılan istek ve buna verilen yanıtta kullanılır. 3. RTT, HTTP’den alınan ilk byte’lık datanın alımına kadar sürer. Şu aşamada TCP’nin ve RTT ne olduğu anlamamız gerekiyor. Kısaca:

Bilgisayarlar ile veri iletme/alma birimleri arasında organizasyonu sağlayan, böylece bir yerden diğerine veri iletişimini olanaklı kılan pek çok veri iletişim protokolüne verilen genel addır. (Yani, TCP/IP protokolleri bilgisayarlar arası veri iletişiminin kurallarını koyar). Bu protokollere örnek olarak, dosya alma/gönderme protokolü FTP (File Transfer Protocol), elektronik posta iletişim protokolü SMTP (Simple Mail Transfer Protocol), TELNET protokolü (Internet üzerindeki başka bir bilgisayarda etkileşimli çalışma için geliştirilen *login* protokolü) verilebilir.

TCP hakkında daha fazla bilgi için ise TCP/IP Protokolü Nedir yazısından faydalanabilirsiniz.

RTT süresi bir LAN (Local Area Network) ortamında genelde 1 MS’den daha kısa sürer. Fakat bazı durumlarda 1 SN’nin üzerine çıkabiliyor. Bu duruma örnek olarak bir istemci modemin yer aldığı kıta ile sunucunun başka bir kıtada yer alması olabilir. Bu yüzden RTT sürelerinin kısa tutulması adına sunucunun hizmet verdiğiniz bölgeye yakın olmasında fayda var.

Ayrıca istemciye gönderilecek veri aktarımı ne kadar fazla paralel hat üzerinden gerçekleştirilirse, site o denli daha hızlı açılır. Bu bağlamda en ucuz ve pratik olan yöntem bir subdomaini CNAME olarak tanımlanması ve ardından resim, CSS ya da JS dosyalarını bu subdomainden yükletmektir.

Burada dikkat edilmesi gereken nokta bazen bir CNAME üzerinden 25-30’un üzerinde bir istek kümesi yaratmanız, iyileştirmeden çok kötüleştirme (veya nötr) yaratabilir. Örneğin sitenizin açılması için bir istemci 240 HTTP isteğinde bulunuyor ve siz bunun 40’ını ana domain, 200’ünü de tek bir CNAME üzerinden yapıyorsanız çok da fazla yararlı olmayacaktır. Çünkü tarayıcı sadece 80 talebi paralel olarak yükleyecek, kalan 160 isteği tek bir hat üzerinden yüklemeye devam edecektir. Bu gibi durumlarda sitenize ait dosyaları (resim, javascript kütüphaneleri, sitil dosyaları vb.) çok iyi bir şekilde organize etmeniz ve ihtiyaç halinde CNAME olarak tanımlı subdomain sayısının artırmanız gerekebilir. Paralel hatları artırarak bu sorunu çözümlemiş olursunuz. Fakat burada da genelde 4 CNAME üzerinde tanımlamanın pozitif bir etki yaratmaması yani maksimumum 4 adet CNAME subdomain yaratmanız yeterlidir. Profesyonel anlamda ise bir CDN servisi kullanabilirsiniz fakat biraz bütçe isteyen bir konudur.

Yüklenme Hızı

RTT Sürelerini Kısaltmak?

RTT sürelerini kısaltmak için bir takım iyileştirme çalışmaları yapılabilir. Bu konuda Google Pagespeed yardım dokümanları size çok iyi bir şekilde kaynaklık edecektir. Ayrıca Yahoo Developer Network sayfalarına da göz atabilirsiniz. Yazımın kalan kısmında da bu dokümanlardan biraz faydalandım.

RTT’nin ne demek olduğunu kavradığımıza göre HTTP isteklerini en aza indirgemek ve gelen isteklerinin hızlı bir şekilde yanıtlamanın ne kadar önemli olduğunun da farkına vardık. Şimdi de yapabileceklerimize bi’ bakalım:

DNS Sorgularını Azaltın

Bir HTTP isteği eğer farklı bir domain üzerinden veri istiyorsa, bu domaine ait DNS çözümlemesinin tarayıcı tarafından yapılması gerekir. Farklı domainler üzerinden dosya çağırıyorsanız, verinin gelmesi için DNS sorgusunun yapılması ve doğru adresin bulunması gerekir. Özellikle çok fazla sayıda ve farklı domainler üzerinden kaynak çağırılması genellikle bu yüzden maliyetlidir. Bu sebeple sayfada kullanılan her türlü dosyaların kendi sunucunuz üzerinde olması önerilir.

Yönlendirmeleri En Aza İndirgeyin

Her yönlendirme, tarayıcı üzerinden ek süreler harcadığı için mümkünse yönlendirmeye uğrayan kaynak barındırmamaya çalışın. Sayfalarınızda kullandığınız kaynakların 301 veya 302 yönlendirmesi üzerinden gelmemesi gerekir.

Yanıt Dönmeyen Sorgulardan Uzak Durun

404 veren kaynakları sayfalarınızdan kaldırın veya düzeltin. Bu tür kırık linkler üzerinden tarayıcı kaynağı çekmeye çalışırken gereksiz yere zaman harcar.

JS Dosyalarınızı Tek Bir Dosyada Birleştirin

RTT konusundan bahsederken her bir dosyanın yüklenmesi için bir takım protokollerin el sıkışmasının gerektiği, her bir isteğin bir HTTP üzerinden gelmesinin maliyetlerinden bahsetmiştik.

Günümüz internet teknolojilerinde sanıyorum çeşitli JS kütüphanesi kullanmayan ya da ihtiyaçlar doğrultusunda JS kullanmayan site yoktur. Bu farklı JS dosyalarını tek bir dosyada birleştirmek HTTP istek sayılarını azaltacağı için otomatik olarak sayfaların daha hızlı açılmasını sağlayacaktır.

CSS Dosyalarınız Tek Bir Dosyada Birleştirin

Tıpkı JS dosyalarının birleştirilmesinde anlattığım üzere sayfada yapılan toplam HTTP isteklerini azaltmak için CSS dosyalarınızı da tek bir dosyada birleştirmeniz önerilir.

CSS Sprite Tekniği ile Resim Dosyalarınızı Tek Bir Tuvalde Birleştirin

Sitil ve script dosyaların sıralamasını optimize edilmesi (Head içerisinde önce css daha sonra javascriptleri ekleyin; mümkünse JS’leri footerdan çağırın.)

JS “document.write” ‘dan Uzak Durun

Bu metod tarayıcıların ilgili alanı tarayıcı üzerinde tekrar render etmesine sebep olduğu için minör seviyede sayfanın ekranda tam anlamıyla yüklenmesini geciktirmekte. Bu yüzden her ne sebeple olursa olsun JS ile bu metodla veri basmamaya özen göstermek gerekli.

CSS Dosyalarını @import ile Siteye Eklemeyin

Tarayıcı sonradan yüklenen veya çağırılan CSS tanımlamaları için ilgili alanın tekrar render edilmesi için baştan hesaplama yapabilir. Tüm bu yeniden hesaplamalar sayfanın ekranda geç gösterilmesine, sayfa yüklenme hızında gecikmelere neden olur.

JS Dosyalarının Asenkron Yükletilmesi

Waterfall analizinde dikkatinizi çekmiş olabilir, genellikle kaynaklar ardısıra yüklenir. Asenkron metodunda ise bu kaynaklar (JS dosyaları) browser tarafından paralel olarak çağırılır ve sunucu da datayı push eder. Dolayısıyla paralel yüklenen kaynaklar, sayfaların çok daha hızlı açılmasına olanak sağlar. Senkron ve Asenkron JS’in farkının detayları için burayı tıklayın.

Kaynakların Paralelize Edilmesi (CNAME)

Yeni bir subdomain açtıktan sonra ve subdomain kaydını CNAME olarak tanımladığınızda, tarayıcı bu subdomain üzerinden gelecek olan statik dosyaları paralel olarak yükleyebilir. En efektif kullanım için maksimum 4 CNAME tanımlı subdomain kullanmanız önerilir. Ardından statik dosyalarınızı (görsel, CSS vs.) eşit sayıda olmasına özen göstererek bu subdomainlerinize dağıtır, sonra da buralardan çağırmanız gerekir.

CDN Kullanımı

CDN, Content Delivery Network’ün kısaltmasıdır. Türkçe anlamı “İçerik Dağıtım Ağı” ‘dır. İçerik Dağıtım Ağı (CDN) dünyanın bir çok yerine dağıtılmış sunucuların oluşturduğu bir alt yapıdır ve CDN’nin amacı ziyaretçilere, site içeriği en hızlı şekilde ulaştırmaktır. Örneğin Amerika’dan internet sitenizi ziyaret eden bir kişi urun.jpg dosyasını görüntelemek istediğinde aslında sunucuza değil, önce en yakın CDN’e başvurur. CDN, istenen dosya kendisinde zaten varsa sunucunuza hiç sormadan direkt olarak kendisindeki kopyayı kullanıcıya döndürür. Eğer dosya kendisinde yoksa sunucunuza bağlanır, dosyanın bir kopyasını kendi üzerine alır ve yine kullanıcıya döner.

Bunlara ek olarak font tiplerini dışarıdan almak ve cufon, siFR gibi uygulamaları kullanmak sayfaların yüklenme süresini artıracaktır. Aynı zamanda cross-browsing yaparken “filter:” kullanmak tarayının sitenizi render etmesini zorlaştıracak, haliyle yüklenme süresini de uzatacaktır. Bu yüzden olabildiğince standartlara uymaya çalışmak gerekli.

SEO uygulayıcıları, bir sayfanın W3 validasyonundan geçmiş olmasını bir SEO kriteri olarak uzun bir süre kabul ettiler ama sonrasında bunun bir faktör olmadığı savunuldu. Bunun nedeni olarak da çok kritik kelimelerde üst sıralarda yer alan sitelerin w3 valid olmadıkları gösterildi. Fakat w3 validation, her zaman dediğim gibi, dün de, bugün de, yarın da, dolaylı olarak bir SEO kriteri olarak ele alınmalı. İster konuya kullanıcı deneyimi (UX), ister erişebilirlik, isterseniz de tarayıcıda hızlı render edilmesine bağlı olarak sitenin hızlı açılması açısından bakın, hiç farketmez. Elinizden geldiğince sitelerinizi w3 validator’den geçirmeye çalışın.

HTTP/2 ile Gelen Güç!

Veya şu ana kadar anlattığım çoğu şeyi bir kenara bırakıp sunucunuza HTTP/2 modülünü, SSL sertifikanızla birlikte kurar ve altyapısını Google’ın SPDY protokolü ile attığı ve sonrasında kendisini HTTP 2.0 olarak karşımızda gördüğümüz yeni teknolojiye ayak uydurursunuz. Böylece HTTP 2.0 ile gelen multiplexed özelliği ile domain sharding, CSS sprite, CNAME subdomainler yaratma gibi zahmetlere de gerek kalmıyor.

Chrome 40. sürüm, Firefox 36. sürüm ve Microsoft’un yeni internet tarayıcısı Spartan HTTP/2’yi destekliyor.

HTTP 2.0’a geçiş için NGINX kullanıyorsanız buradan, Apache kullanıyorsanız burayı tıklayarak nasıl kuruldığunu öğrenebilir; eğer bir sunucu hizmeti alıyorsanız yer sağlayıcı firmadan kurulum  için talep geçebilirsiniz.

HTTP/2 ile Neler Değişti?

  • HTTP/2 verileri binary formatta transfer ediyor ve yöntem bilgilerin daha hızlı taşınmasına neden oluyor.
  • HTTP/2 sayfaların header bilgilerini sıkıştırıyor (header compression); böylece transfer edilen sayfa boyutları azalıyor.
  • HTTP/1.1’de tarayıcıdan sunucuya yapılan eş zamanlı çağrılar limitleniyordu ve en fazla 3-8 arası talep gönderiliyordu. HTTP/2 ile bu limit kaldırıldı ve daha fazla sayıda çağrı gönderilebiliyor (multiplexed). Yukarıda bahsettiğim HTTP 1.0’da CNAME ile yapılan aksiyonlar bu özellikle birlikte tarih oluyor.
  • Web sunucuları artık talep gelmeden istemcilere veri gönderebiliyor (server push).

Ufak Bir İpucu

Eğer PHP tabanlı bir web siteniz varsa RTT sürelerini kısaltmak ve daha hızlı response vermek için bir ipucu verelim. Sanırım flush(); fonksiyonunu biliyorsunuzdur; bilmiyorsanız da php manuel’in flush fonksiyonu hakkındaki dokümantasyona göz gezdirebilirsiniz.

Bir kullanıcı sunucudan bir HTML sayfasını talep ettiğinde, sunucunun HTML sayfa ile birlikle yanıt vermesi 500ms’yi bulabiliyor ve hatta saniyeleri bulup geçebiliyor. Bu süre içerisinde tarayıcı, dataların gelmesi için boşta bekliyor. Fakat flush fonksiyonu ile tarayıcının boşta beklemesi yerine, diğer bileşenleri almaya başlamasını sağlayabilirsiniz. “flush” fonksiyonunu </head> etiketinden hemen sonrasında kullanarak, sunucu gelen istekleri işlerken diğer dosyaları tarayıcının alıp işlemesini sağlarsınız. Binevi seri olarak ilerleyen süreci, paralelleştirmiş olursunuz. Bunun için yapmanız gereken </head> ‘den hemen sonra aşağıdaki kodu sitenize eklemenizdir:

<?php flush(); ?>

Ufak bir hatırlatma yapmakta fayda var. Özellikle session kullanımına göre bu fonksiyon bazı sitelerde problem yaratabilir. Bu yüzden iyi bir şekilde test etmeniz gerekir.

2021 Dijital Pazarlama Trendleri ve İç Görülerim

2020 sanıyorum kimsenin öngöremediği bir pandemi kasırgası ile sonlanmak üzereyken, globalde yaşanan bu durum birçok şirketin çalışma şeklini de etkiledi. Aşının bulunma haberi, panik havasını ve ekonomide yaşanan stresleri gevşetirken insanlar üzerindeki korkunun hemen geçmesi…

COVID-19 Hakkında Platin Dergisi ile Yaptığım Söyleyişi

1-Korona sonrası dönemde hedef kitle, gönüllü karantina döneminde. Çoğu kişi artık sokağa çıkmaktansa her alışverişini online yapmayı tercih ediyor. Sizce bundan sonraki süreçte, markalar hedef kitleye ulaşabilmek ve satın alma süreçlerine hız kazandırabilmek adına ne…

19 yorum

    kimse bişey yazmamış, bari ben yazayım, fakat yazın kaliteli değil, tam açıklama yapmamışsın, şuradan bakın, buradan bakın diye link vermişsin, olmamış yegen

    Teşekkür ederim . kodu muhteşem sitenin tema html sinde altına girdim. Açılış hızlandı. Emeğinize sağlık.

    Kesinlikle güzel bir konuya değinmişsiniz seo ile ilgilenen herkezin bildiği gibi kişi bir sözcük üzerinde arama yapıyor karşısına çıkan siteleri geziyor ve 1 sitede aradığını buluyor ve o sözcük üzerinde olan aramasını sonlandırıyorsa demekki o site başarılıbir sitedir.
    Eğer kişi sayfaya girdi ve sayfa açılışı ve kişi gezerken zorlanıyorsa eğer o sayfada faydalı bir içerik olsa bile kişi kapatır ve aramasına devam eder.
    Bu nedenle sayfanın açılış hızı çok öenmidir Makale için teşekkürler.

    Teşekkürler. Faydalı bir yazı olmuş. Sayfa açılış süresini azaltmak için yavaş yavaş uygulamaya çalışacam.

    Kodu bazı scriptlerin mobil versiyonlarında sorun olabiliyor gibi. Ancak kesin olarak “böyledir” diyemem. Herkes iyice test etsin öyle kullansın. Yazı genel olarak faydalı ama daha detaylı olsaymış keşke. Gene de emeğinize sağlık.

    @sukru bey, ilk fırsatta yazıyı detaylandıracağım o halde 🙂
    @mutludent , eklentiler wp sisteminde yavaşlık yaratacaktır. Haklısınız, fakat WP için konuşursak olabildiğince işlerinizi eklentisiz halletmeye çalışın 🙂 Her halükarda w3 total cache eklentisi bir çok konuda rahatlık sağlıyor. Konfigürasyonunu düzgün yaparsanız tabii..

    apache, php den gelen flush komutu ile sayfa dönüşünü oldukça hızlı sağlıyor. litespeed ise bunu otomatik olarak yapıyor, bu sebeple apache ye oranla oldukça hızlı yüklenme süresi var. yazınız için teşekkürler.

    Süpersin kardeşim kodu kullandım, wordpress sitemde başımı ağrıtan page speed olayı birden değişti. Ulan ufacık kod nelere kadir miş. açılış hızı tek kodla %85 oldu 🙂 teşekkür ederim gerçekten

    Uğur veya Yusuf arkadaşım. bu kodu wordpress’de hangi dosyaya eklememiz gerekiyor acaba? bende de aynı sıkıntı var. 3,6 saniye hiç bişey yapmadan bekliyor. sonrasında tıkır tıkır anında açıyor siteyi. anasayfa yani index.php ye mi ekleyeceğiz?

    Appearance >Edit Themes>Editor> Theme Header (header.php)
    Bunun için yapmanız gereken ‘den hemen sonra aşağıdaki kodu sitenize eklemenizdir:

    ______ wordpress için böyle bir yol izlemeniz gerekmektedir. 2015 yılındaki soruya cevap vererek, faydalananların sayısını artırmak istedim.

    Merhaba
    Yazı için çok teşekkür ederim, parantezlere ve detaya indirgemişsiniz, benim gibi acemi kişiler için fazlaca açıklayıcı 😉

    Yalnız benim bir problemim var, site açılış değerlerim desktop olarak yüksek (google speed92) ancak mobilde pek de öyle değil. Aldığım hata ise js/css leri head den sonrasına entegre etmem gerekiyor sanırım. Bunu yapabilecek eklenti de buldum (bu arada wp kullanıyorum) ancak bu sefer de site içerisinde googlemaps,carusel,lightbox tarzı araçlar çalışmamaya başladı.

    Sizce ne yapmalıyım, önerebileceğiniz eklenti var mı?

    @Ahmet; dostum o kodu header.php de body nin hemen üstüne ya da hemen içine ekleyebilirsin.

    Teşekkür ederim çok güzel anlatım olmuş uygularsak güzel sonuçlar verir sanırım test ettikten sonra faydalarını bende sizlerle paylaşmak isterim.

    Dostum çok bir kod bilgim yok .3 gündür %77 olan site hızımı arttırmaya çalışıyorum.. Tek kod ile ” ” 77 olan hızımı 90 yaptın . Çok teşekkür ederim adamın dibisin =)

    Merhaba, bu kodu siteme uyguladım, site hızım çok yükseldi ama tek bir sıkıntım var sitenin üst tarafında sadece bilgisayardan bakınca görünen “” yazısı çıktı. biliyozdakonusuyoz . com burdan da bakabilirsin. Bunu nasıl kaldırabilirim yardımcı olur musun?

    Baktım ama göremedim. Gözden kaçırdığınız bir karakter ya da encoding sorunu kaynaklı olabilir mi?

    Uğur Bey merhaba, asp.net mvc de yanıt (response) head bölgesine müdehale edebiliyor muyuz ? Misal, tarih alanı kaldırma ya da diğer alanları kaldırma gibi bir şey yapılabilir mi ?

    Teşekkürler…

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir