Tweet

Web Sayfanızı Apache Konfigürasyonları, Php Tasarım ve Kodlama Teknikleri ile Hızlandırın

uploads/20110628-025636-1.jpgWeb Sayfanızı Apache Konfigürasyonları, Php Tasarım ve Kodlama Teknikleri ile Hızlandırın
Bu makalede web sayfamızın açılış hızını artırmak için neler yapmamız gerektiği hakkında bilgilerimi aktarmaya çalışacağım.

Web sayfamızın hızı neleri etkiliyor?
Çağımız bilgi ve iletişim çağı, internet bilgiye erişmek için en önemli araç. Haliyle internet kullanıcıları bilgiye hızlı ve doğru şekilde erişmeye çalışıyorlar. Arama motorları da aslında sitenin kalitesini belirlerken bu iki kriteri listenin en üzerinde tutmaktadır. Google, yahoo, bing, vb. arama motorları kullanıcılarına en doğru bilgiyi en hızlı şekilde ulaştırmak için sürekli algoritmalarını değiştirmekteler. İçeriğinize güveniyorsanız geriye kalan içeriğinize erişimi hızlandırmaktır. Eğer sitenizin kaliteli içeriklere sahip olduğunu düşünüyorsanız ve buna rağmen "Bounce Rate (Hemen Çıkma)" oranı çok yüksek ise bu durumun en büyük nedeni sitenizin yavaş açılması olabilir. Yapılan araştırmalara göre arama motoru kullanan kişiler bir sayfanın açılmasını (tarayıcıda ilk içerik görülünceye kadar geçen süre) ortalama 5sn kadar beklemekte. Bu durumda bize düşen sayfa açılış hızımızı bu sürenin altına çekmek olacak.[...]

Raporlama ve test araçları
Sayfa açılış hızımızı test etmek ve tavsiyeler almak için gerekli yazılım ve siteler mevcut. Ben bu makaleyi hazırlarken. Firefox için PageSpeed eklentisini ve http://www.webpagetest.org sayfasını kullandım. Bildiğiniz farklı araçlar var ise siz dilediğiniz kullanabilirsiniz.

Modifikasyonlara geçmeden öce sitemizi http://www.webpagetest.org adresinde test ederek sonuç adresini kayıt edelim. Modifikasyonlardan sonra testi bir kez daha yapacağız ve daha önce kayıt ettiğimiz sonuçlar ile karşılaştıracağız.

KeepAlive
Bir site yapılan her şeye rağmen çok yavaş ise sorun mutlaka KeepAlive özelliğinin httpd.conf dosyasında off olmasıdır. Bu özellik Off olduğunda apache her request(istek) için yeni bir connection (bağlantı) kurar. Bu durum sayfa açılış hızımızı büyük ölçüde etkiler. KeepAlive On olarak değiştirildiğinde, ilk istekten sonra her istemci için bağlantı belirli bir süre açık kalır. Her yeni istekte yeni bir bağlantı açılmaz, bunun yerine var olan bağlantı kullanılır.

(httpd.conf dosyasının yolunu vermeyeceğim çünkü her unix sürümünde farklı bir yerde tutuluyor.)

mod_deflate ve gzip
Web sayfanızın içeriklerini istemci (kullanıcı) tarafına sıkıştırılmış olarak göndererek istemcinin sayfanızı açarken indirdiği içeriğin boyutunu azaltmış olursunuz. Bu özelliği aktif etmek için web sayfamızda ve httpd.conf dosyasında bazı değişiklikler yapmamız gerekecek.

Web sayfamızın kodlarını açarak index sayfamızın ilk satırına ob_start("ob_gzhandler"); yazın. Eğer tüm sayfalarınız index sayfası içerisine include ediliyorsa yani linkleriniz dinamik çalışıyorsa bu komutu index sayfanızın ilk satırına yazmanız yeterli. Eğer harici sayfalarınız var ise örneğin : ornek.com/iletisim.php gibi, bu durumda da her bir harici sayfamızın ilk satırına ob_start("ob_gzhandler"); metodunu ekliyoruz (Not: bu method ziyaretçi sayısı arttıkça işlemciye yük bindirecektir kullanırken load averageları kontrol ediniz). Bu metot sayfanızın çıktı olarak istemciye gönderilmeden önce bufferda tutulan içeriğin gzip ile sıkıştırılarak gönderilmesini sağlayacaktır.

Gelelim httpd.conf dosyamızda mod_deflate ile yapacaklarımıza. Mod_deflate bir apache modülüdür. Bazı hostinglerde standart olarak kapalı iken bazılarında modül kullanıma açıktır. Mod_deflate i apachede aktif etmek için (apache başlarken load etmek için) httpd.conf dosyanızda

#LoadModule deflate_module modules/mod_deflate.so

Satırını bularak satırın başındaki # işaretini kaldırın. Böylece mod_deflate modülü apache restart edildiğinde yüklenecektir.

Artık modülümüz yüklendiğine göre modülümüze hangi içeriklerin sıkıştırılacağını söylememiz gerekiyor.

Httpd.conf dosyamızın son satırına gelerek aşağıdaki kodları ekleyelim.

CODE:
## DEFLATE ##
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/javascript text/css application/x-javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4.[0678] no-gzip
BrowserMatch bMSIEs(7|8) !no-gzip !gzip-only-text/html
Header set Vary *
DeflateCompressionLevel 1
</IfModule>
## DEFLATE ##


Resimleri Sıkıştırın ve Birleştirin
Sayfanızın resimleri, indirilen sayfanın büyük kısmını oluşturmaktadır. İndirilen resim dosyalarının boyutunu, resmin kalitesini bozmayacak şekilde resmi sıkıştırarak düşürebiliriz. Photoshop da "save for web" e tıklayarak resmin kalite ve dosya tipleri düzenlenebilmektedir.

Tekrar eden bölgeleri resim kesitleri ile doldurarak resmin boyutunu küçültebiliriz. Örneğin bir div'in arka planında zemin resmi kullanıyoruz ve bu resim düz bir renk. Zemin olarak kullandığımız resmin 1 pikselini crop ederek kayıt edelim ve css ile bu resmin zemin içinde tekrar etmesini sağlayalım. Böylece binlerce piksel yerine 1 piksellik bir resim dosyasına sahip oluruz. Bu dosyanın da sunucudan yüklenme süresi cok daha azdır. Örneğin bir gradient menü barımız var ve 1000X30 piksel. Bu barı bir div içerisinde background olarak kullanıyoruz. Barımız sağdan sola stil olarak tekrar etse de gradient yukarıdan aşağıya olduğu için barımız yukarıdan aşağıya kendini tekrar etmiyor. Bu durumda 1x30 piksel lik bir kesit alarak divimizin background'ının x yönünde tekrar etmesini fakat y yönünde tekrar etmemesini css ile sağlarız.

Sayfamızda kullandığımız icon ve imleri sprite haline getirerek tek resim yüklemesinde bütün gerekli icon ve imleri yükleyebiliriz. Buda bizi apache ile fazladan kurulacak bağlantılardan kurtaracaktır.

uploads/20110628-025813-1.png

Mesela bu gördüğünüz ikonlar tek bir resimde toplanarak sprite oluşturulmuş durumda.

Tasarımımızda eposta, buzz ve twitter ikonlarını kullanmak istiyoruz. İşte burada css devreye giriyor.

CODE:
<style type="text/css">
.sp_eposta{display:block;width:24px;height:24px;background:url(../images/sp1.png) 0px -272px no-repeat;}
.sp_buzz{display:block;width:24px;height:24px;background:url(../images/sp1.png) 0px -0px no-repeat;}
.sp_twitter{display:block; width:24px;height:24px;background:url(../images/sp1.png) 0px -340px no-repeat;}
</style>
<span class="sp_eposta"></span>
<span class="sp_buzz"></span>
<span class="sp_twitter"></span>


Şeklinde yazılacak css scripti ile 3 ikonu görüntüleyebiliriz. Bu kullanım sadece ikon ve imler için geçerli değildir. Siz sprite tekniğiniz dilediğiniz yerde kullanabilirsiniz. İkonlarınızı birleştirerek sprite haline getirmenize yarayacak birkaç önemli site mevcut.

Bunlar;

http://csssprites.com/
http://spritegen.website-performance.org/

Tarayıcı önbelleğini sabit içerikler için aktif edelim (Enable browser cache)
Statik içerikler için expire veya Cache-Control: max-age değerlerini http başlıklarında düzenleyerek tarayıcıların sayfaya eriştiğinde dosyayı yeniden indirmek yerine daha önce tarayıcının ön belleğine aldığı kopyasını kullanmasını sağlayacağız. Böylece hep bandwith den hem hızdan kazanacağız. Ben yöntemlerden birini kullanarak içerikler için expire date belirleyeceğim. Bunun için apache'nin "mod_expires" modülünü aktif etmem gerekiyor.

Httpd.conf dosyanızda

#LoadModule expires_module modules/mod_expires.so

satırının başındaki # karakterini sildikten sonra apache'yi yeniden başlattıktan sonra httpd.conf dosyamızı yeniden açarak dosyanın son satırına aşağıda örnek olarak verdiğim satırları kendinize göre uyarlayarak ekleyebilirsiniz. Aşağıdaki örnekte tarayıcının içerik türlerine göre içeriği minimum ne kadar süre sonra tekrar indirmesi gerektiğini belirtiyoruz. Statik yani sayfanızda sürekli değişmeyen içerikler için bu süre minimum 1 ay olması öneriliyor bu nedenle ExpiresDefault "access 1 months" satırını en sona ekledik. Ben sayfamdaki resimlerin çok fazla değişmeyeceğini düşünerek resimlere tekrar erişim süresini 1 yıl olarak belirledim. Siz bu değerleri kendi isteğinize göre değiştirebilirsiniz.

CODE:
## EXPIRES CACHING ##
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "Access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/x-javascript "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresDefault "access plus 1 months"
</IfModule>
## EXPIRES CACHING ##


ETAG'ları Kapatın. (Close ETAG)
Yeni nesil bazı tarayıcılar html başlıklarında ETAG gördüklerinde belirlemiş olduğunuz expire date leri yok sayarlar bu durumu önlemek için aşağıdaki satırları httpd.conf dosyanıza ekleyebilirsiniz. Eklemek istediğini dosya uzantısı varsa (|) ile ayırarak dosya uzantısını ekleyebilirsiniz.

CODE:
## ETAG ##
<FilesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css)$">
FileETag none
</FilesMatch>
## ETAG ##


Not: Html uzantılı dosyalar için etag kapatılmamalıdır.

Javascript ve Css dosyalarınızı Sıkıştırın ve Birleştirin.

Js ve Css dosyalarınızdaki gereksiz boşluklardan kurtularak yüklenme hızlarını arttırabilirsiniz. Birden fazla js ve css kaynağınız var ise js ve css'leri mümkün olduğu kadar tek dosyada birleştirmeye çalışın. Böylece apache'ye, dosyayı indirmek için daha az sayıda istek gelecektir. Js ve css dosyalarınız sıkıştırmak için birkaç yararlık kaynak mevcut.

Bunlar;
http://jscompress.com/
http://www.minifyjs.com/javascript-compressor/
http://fmarcia.info/jsmin/test.html
http://www.minifycss.com/css-compressor/
http://www.cssdrive.com/index.php/main/csscompressor

Çift Tırnak Yerine Tek Tırnak Kullanın
PHP ile kodlama yaparken mümkün olduğunca (') tek tırnak kullanmaya özen gözterelim belki küçük bir ayrıntı ama php scriptinizi yorumlarken çok daha hızlı çalışacaktır. Örneğin: echo 'thecoders.net '.$yas.' yaşında'; scripti echo "thecoders.net $yas yaşında"; scriptinden %50 daha hızlı çalışır.

İf Yerine Switch Case Kullanın

İf ler sistemi en çok zorlayan kod parçacıklarıdır. Mümkün olduğunca if kullanmaktan kaçınmaya çalışın. Örnek vermek gerekirse sayfaya gelecek $_GET['komut'] parametresine göre işlemler yapmamız gerekiyor diyelim. Çoğu coderın aklına hemen if kullanmak gelir fakat yapacağımız işlemler 2 den çok ise o zaman switch case kullanmakta fayda var. Örneğin:

CODE:
<?
İf($_GET[komut]=='listele'){
//islemler
}
else if(($_GET[komut]=='ekle'){
//islemler
}
else if(($_GET[komut]=='sil'){
//islemler
}
else if(($_GET[komut]=='guncelle'){
//islemler
}
else {
//islemler
}

//Yerine

Switch($_GET['komut']){
case 'listele':
//islemler
break;
case 'ekle':
//islemler
break;
case 'sil':
//islemler
break;
case 'guncelle':
//islemler
break;
default:
//islemler
break;
} ?>


Kullanmanız sayfanızın hızını arttıracaktır.

Döngülere dikkat
Kod yazarken çok fazla göze çarpmasa da döngülerin yanlış kullanımı önemli hız kayıplarına neden olabilir. Örneğin döngünün maksimum değeri mutlaka bir değişkene atılarak kullanılmalıdır. Örnek vermek gerekirse

CODE:
<?
$arr=arr('istanbul','ankara','izmir','manisa','muğla','trabzon','malatya');
for($i=0 ; $i < count($arr) ; $i++) {
} ?>


Yukarıdaki scriptte önemsiz gibi görünse de döngü her dönüşünde $arr dizisi için count() fonksiyonu ile dizi uzunluğu(eleman sayısı) hesaplanıyor. Yukarıdaki örnekte 7 elemanlı bir dizi için önemsiz görünse de 10000 elemanlı bir dizide ciddi performans kaybı yaşayacaksınız. Fakat yukarıdaki scripti aşağıdaki şekilde değiştirirsek bu sorunu çözmüş olacağız.

CODE:
<?
$arr=arr('istanbul','ankara','izmir','manisa','muğla','trabzon','malatya');
for($i=0, $c=count($arr) ; $i < $c ; $i++) {
} ?>


Yukarıda görüldüğü gibi $arr dizisinin uzunluğunu $c değişkenine atıyoruz. Döngü her dönüşünde bu değer tekrar tekrar hesaplanmayacaktır.

Sorgularınızı Sonlandırın
Listeler halinde sunduğunuz içerikler query cache de büyük alanlar kaplayacak dır. Öncelikli olarak bu tür sorgularınızı mysql_free_result() veya mssql kullanıyorsanız mssql_free_result() fonksiyonları ile sonlandırın. Uzun vadede SELECT sorgularının tümünü sonlandırmalısınız.

Veritabanında İndexleri Kullanın
Sorgularınızda where, join ve order by dan sonra yazdığınız alanlar için veritabanınızda mutlaka indexler oluşturun. Bu sayfanızda ciddi performans artışına neden olacaktır.

Son olarak www.webpagetest.org sitesinden yeni bir test yapalım ve modifikasyonlarımızın ne kadar etkili görelim.








Dia
okanatabag@gmail.com
20 Ocak 2011 03:59

İlgili Olabilecek Makaleler


Yorumlar (0)




Ziyaretçi olarak yorum yazamazsınız. Üye olmak için tıklayın Üye iseniz giriş yapın.



MENÜ » FORUM
Menü » Takip et
RSS Facebook Twitter Friendfeed
Sık Kullanılanlar Google Yahoo Live
Menü » Paylaş
E-Posta ile gönder Twitter Facebook Friendfeed
Buzz Stumbleupon Delicious Digg