Bu konuyu hiç yazmayı düşünmüyordum, Writing Efficient CSS for use in the Mozilla UI makalesini okuyan kadar. Bu makaleyi okuduğumda bir şeyleri yanlış bildiğimi gördüm ve düzeltmek için bu konu hakkında biraz araştırma yapmam gerektiğini düşündüm ve bu makale çıktı. Bende yeni çok şeyler öğrendim. Aslında makalede 10 senelik bir makale, 10 sene sonra tekrar ısıtılıp yayına konmuş.

Web sitelerini kodlarken ve kodlama sonrasında en çok önem verilen alanlardan biridir optimizasyon. Web sitelerinin optimizasyonunda çok fazla ince eleyip sık dokuyoruz. 1 Kbyte’ın bile hesabını yapar olduk. İnternete bağlanma hızları ne kadar artsa da internete bağlanan insan sayısı daha hızlı arttığı için her zaman daha optimize web siteleri önem kazanacaktır. Biz bununla alakalı olarak burada CSS Seçicilerinin optimum kullanılmasını irdeleyeceğiz. 

CSS seçici tipleri ve kullanımı hakkında [(X)HTML Sayfa Yapısı ve CSS Kullanımı][], [Özellik Seçicileri(Attribute Selectors)][] ve [Sözde-sınıflar(Pseudo-class) ve Sözde-elementler(Pseudo-elements)][] makalelerini bir göz atın.

Performanslı CSS Seçicileri Seçiminde Anahtar Seçicinin Önemi

CSS Seçicilerinin performans kazandırma çalışmalarına başlamadan önce ilk bilmemiz gereken tarayıcıların CSS seçicilerini nasıl yorumladığını bilmekten geçiyor. Ben daha önceleri ki bu makaleyi yazmadan önce diyebilirim buna, css kodu yazarken seçicilerin soldan sağa doğru okunduğunu düşünerek kodumu yazardım ama gerçek böyle değilmiş. Tarayıcılar CSS seçicilerini sağdan solda doğru okurlar. Tabi bu bilgiden sonra yazdığımız kodları buna göre düşünerek yazmalıyız.

ul li a#smUrunler{
	color:#000;
	background:url(../images/menu.png) 0 0 no-repeat;
}

Yukarıdaki tanımlamada ilk olarak tarayıcı doküman içinde geçen a#smUrunler seçicisini bulacaktır, bu seçiciye anahtar seçici deniyor. Bir bakıma elemanı yakalamak için anahtar oluyor tarayıcıya.

Bu bize gösteriyorki css kodlarımızı yazarken buna dikkat etmemiz ve buna göre kod yazmamız gerekiyor.

ul#solMenu li a{
	color:#000;
	background:url(../images/menu.png) 0 0 no-repeat;
}

şeklindeki bir tanım önerilmiyor. Bu tanımda sağdan sola doğru yorumlandığını düşünürsek dokümandaki tüm bağlantıları(<a>) arayacaktır tarayıcı. Bunun yerine

ul li a#smUrunler{
	color:#000;
	background:url(../images/menu.png) 0 0 no-repeat;
}

Tanılaması daha efektif bir sonuç verecektir. Tarayıcı direk olarak a#smUrunler seçicisi ile elemanı bulacaktır.

stevesouders.com’un test sayfasını incelersek sonucu daha iyi anlayacağız.

Aynı öneriyi bize Google’un Page Speed eklentisi test sonucuda verecektir. Google’un hıza önem verdiğini biliyoruz bu konuda [google’un önerileride][] Mozilla’dan farklı değil.

Mozilla makalesindeki önerileri sıralarsak

Evrensel kuralları önleyiniz CSS seçicilerini yazarken son tanımda evrensel bir seçici kullanmayın.

Tekil Seçicileri(id) etiketlerle nitelemeyin Tekil seçiciler zaten en hızlı erişilen seçicilerdir. Bunları tekrar etiket ile nitelemeye gerek yoktur.

a#slUrunler{...}

yerine

#smUrunler{...}

şeklinde kullanın.

Etiketler ile nitelemenin o seçiciyi kod okunurken daha anlamlı hale getirdiğini düşünüyorum. ancak Firebug ile kod takibi yaptığımız bu günlerde artık buda kabul gören bir tanım değildir. Ben kod yazarken son zamanlarda çok kullanıyordum bu tanımlamayı, artık veda edeceğiz.

Sınıf Seçicileri etiketlerle nitelemeyin Yukarıda anlattığımız gibi burası içinde geçerlidir.

td.taraftarSayi{}

yerine

.taraftarSayi{}

şeklinde kullanın.

Torun Seçiciler veya çocuk Seçicler Yerine Özel sınıflar Atayın Uzun seçici listesi kullanmak yerine daha özel bir sınıf tanımı yapın.

ul li a{...}

yerine a’ya smUrunler sınıfını atayıp

.smUrunler{...}

şeklinde kullanın.

Torun Seçicileri yerine Çocuk Seçicileri Kullanın Seçici tiplerinden torun seçicileri en yavaş yöntemlerden biridir. Çocuk seçicileri nispeten daha avantajlıdır. Daha iyisi için bir sonraki öneriye bakın.

Etiket Kategorilerinde Çocuk Seçicileri Kullanmayın Etiket tabanlı çocuk seçicileriniz yerine özel seçici kullanınız.

treehead > treerow > treecell {...}

yerine

.treecell-header {...}

kullanın.

CSS 3 ile gelen avantajlar

CSS seçicilerine CSS3 ile birlikte daha özel seçiciler geliyor. Bu seçiciler sayesinde daha optimize kodlar elde edeceğiz. Şimdilik İnternet Explorer’un mevcut sürümleri bu kullanıma izin vermese de gelecekte işimiz daha kolay olacak.

Sonuç

Yukarıdaki önerileri dikkate alarak kodlarımızı yazmalıyız. Ancak bunlar kesin kurallar değildir ve uygulamada bazen bu kurallar uymakta zorlanabiliriz. Benim önerim bu kuralları dikkate alarak yazmaya çalışalım, olmadı isede kendimizi paralamayalım.

CSS seçicilerinin etkin kullanılması küçük çaplı projelerde çok büyük etkisi olmasa da büyük projelerde performans açısından çok önemli olduğunu düşünüyorum. Tabi şöyle bir durumda var css kod yazma alışkanlığı kazanan bir arayüz geliştirici için bu küçük buna böyle yazayım bu büyük buna böyle yazayım diye bir ayrım yapmasıda pek mantıklı ve mümkün değildir. Bu nedenle kendi standardımızı en iyiye göre yapalım proje küçük olmuş, büyük olmuş bizi ilgilendirmesin.

  • developer.mozilla.org/en-US/docs/CSS/Writing_Efficient_CSS?redirect=no
  • [http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/][]
  • O’Reilly - Even Faster Websites.pdf 14. konu
  • [http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/][]
  • [http://ajaxian.com/archives/css-child-selector-performance][]
  • http://jackslocum.com/blog/2007/07/10/css-selectors-speed-myths
  • [http://hacks.mozilla.org/2009/06/dom-selectors-api/][]
  • [http://www.shauninman.com/archive/2008/05/05/css_qualified_selectors][]
  • http://blog.archive.jpsykes.com/153/more-css-performance-testing-pt-3
  • [http://www.infoq.com/news/2009/01/jquery-1.3][]
  • [http://code.google.com/speed/page-speed/docs/rendering.html][] (google’dan notlar)
  • [http://fatagnus.com/guidelines-for-writing-efficient-css-selectors/][]
  • [http://www.shauninman.com/archive/2008/05/05/css_qualified_selectors][]
  • [http://css-tricks.com/efficiently-rendering-css/][]
  • http://www.nuvographics.com/articles/efficientcss
  • css-101.org/descendant-selector/go_fetch_yourself.php

Writing Efficient CSS for use in the Mozilla UI [(X)HTML Sayfa Yapısı ve CSS Kullanımı]: http://fatihhayrioglu.com/xhtml-sayfa-yapisi-ve-css-kullanimi/ “(X)HTML Sayfa Yapısı ve CSS Kullanımı” [Özellik Seçicileri(Attribute Selectors)]: http://fatihhayrioglu.com/ozellik-secicileriattribute-selectors/ “Özellik Seçicileri(Attribute Selectors)” [Sözde-sınıflar(Pseudo-class) ve Sözde-elementler(Pseudo-elements)]: http://fatihhayrioglu.com/pseudo-siniflari-ve-pseudo-elementleri/ “Sözde-sınıflar(Pseudo-class) ve Sözde-elementler(Pseudo-elements)” [google’un önerileride]: http://code.google.com/speed/page-speed/docs/rendering.html “google’un önerileride” [http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/]: http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/ “http://www.stevesouders.com/blog/2009/06/18/simplifying-css-selectors/” [http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/]: http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/ “http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/” [http://ajaxian.com/archives/css-child-selector-performance]: http://ajaxian.com/archives/css-child-selector-performance “http://ajaxian.com/archives/css-child-selector-performance” [http://hacks.mozilla.org/2009/06/dom-selectors-api/]: http://hacks.mozilla.org/2009/06/dom-selectors-api/ “http://hacks.mozilla.org/2009/06/dom-selectors-api/” [http://www.shauninman.com/archive/2008/05/05/css_qualified_selectors]: http://www.shauninman.com/archive/2008/05/05/css_qualified_selectors “http://www.shauninman.com/archive/2008/05/05/css_qualified_selectors” [http://www.infoq.com/news/2009/01/jquery-1.3]: http://www.infoq.com/news/2009/01/jquery-1.3 “http://www.infoq.com/news/2009/01/jquery-1.3” [http://code.google.com/speed/page-speed/docs/rendering.html]: http://code.google.com/speed/page-speed/docs/rendering.html “http://code.google.com/speed/page-speed/docs/rendering.html” [http://fatagnus.com/guidelines-for-writing-efficient-css-selectors/]: http://fatagnus.com/guidelines-for-writing-efficient-css-selectors/ “http://fatagnus.com/guidelines-for-writing-efficient-css-selectors/” [http://css-tricks.com/efficiently-rendering-css/]: http://css-tricks.com/efficiently-rendering-css/ “http://css-tricks.com/efficiently-rendering-css/”

FireBug hakkında elle tutulur bir bilgi olmadığı için bu makaleyi yazmaya karar verdim. Bu yazımda FireBug Net paneli hakkında olacaktır. FireBug geliştirme ile alakalı bir makale değildir. Özellikleri hakkında genel bir bilgi içerecektir.

Web sayfalarının kodlarken bir çok yönünü düşünerek kodlarız. Erişebilirliği, esneklik, farklı tarayıcılara uyumlu olması, performans bunlardan ilk aklımıza gelenler. En önemlilerinden biri performansının iyi olmasıdır. Web sitesi sahipleri sitelerinin tarayıcılar tarafından hızlı gezilmesi için en kısa zamanda açılmasını sağlamak için uğraşır. Performans değerlendirmesi için kullanabileceğimiz araçlardan birisi Firebug’ın Net panelidir. Burada Firebug’ın Net sekmesini inceleyeceğiz. Aşağıda benim anasayfamın net panelindeki görüntüsünü görüyorsunuz.

Genel Net sekmesi görünümü

Net Panel Giriş

Net sekmesinin genel amacı kullanıcıya HTTP trafiğini kolayca göstermektir. Her satır sayfayı oluşturan bir girdinin istek/cevabını gösteren bir göstergedir.

Örnek bir sayfa ile devam edelim.

/dokumanlar/fare_degisen_resim.html

Yukarıdaki resimde sunucuya yapılan iki isteğin sıralaması ile birlikte göstermektedir. İlk istek sayfanın kendisi, ikinci istek ise degisen_resim.gif resmi.

Her girdi istek hakkında genel bir bilgiyi gösterir. Zaman çizelgeside grafiksel olarak yüklenme zamanını gösteriyor.

Net sekmesi bize fare_degisen_resim_klavye.html içeriğinin 418ms de yüklendiğini ve degisen_resim.gifresmininde 146ms de yüklendiğini gösteriyor.

Net sekmesi bize ilk bakışta aşağıdaki bilgileri verir;

  • HTTP istek metodunu (GET)
  • Cevap durumu ve açıklaması (200 OK)
  • İstem dosya ismini(fare_degisen_resim_klavye.html) ve fare imlecini üzerine getirirsek hangi adresten çektiğini gösterir.
  • Cevapların hangi barındırma hizmetinde geldiği (fatihhayrioglu.com)
  • Cevabın boyutu (778Byte)
  • Grafiksel gösterge ve yüklenme zamanı (418ms)

Birde en sondaki sonuç bilgi satırı var.

  • Sayfada 2 adet istek yapıldı
  • Bu 2 isteğin toplam boyutu 3kb ve eğer önbellekten alıyorsa ne kadarını önbellekten alıyor bilgisi.
  • Bu 2 isteğin ne kadar zamanda yüklendiği(son isteğin sonu ile ilk isteğin başı arasındaki zaman)

Her bir elemanın üzerine gelince popup ekranı ile bize daha detaylı bilgi veriyor. Her rengin bir anlamı var.

DNS Lookup: DNS çözümleme zamanı connecting: Oluşturulan TCP bağlantısı için harcanan zaman Blocking: Ağa bağlanırken tarayıcı bu istekleri belli bir sıraya dizer. Bu sırada beklerken harcadığı zaman. Eğer böyle bir zaman harcanıyorsa gösterilir, yoksa gösterilmez. Aşağıda bu konuya(Tarayıcı Sırasında Bekleme Zamanı) biraz daha ayrıntılı değineceğiz. Sending: Sunucuya gönderilecek veri için istek gönderme zamanı Waiting: Sunucudan dönen cevabın bekleme zamanı(sunucudan gelen ilk byte’ın bekleme zamanı) Receiving: Gelen cevabın indirilmesi için gereken zaman.

DOMContenLoaded:(Mavi dikey çizgi) ilk istek başladıktan +5.48s sonra DOM içeriğinin yüklenme olayı tetiklendi, anlamını taşıyor. Eğer bu değer eksi ise DOM içeriği istek başlamadan önce gönderilmiş demektir.

load:(kırmızı dikey çizgi) Bu gösterge bize yüklenme olayının ilk istek başladıktan sonra geçen süreyi gösterir. Eksi değer alması ilk istekden önce tetiklendiğini gösterir.

Tarayıcı Sırasında Bekleme Zamanı

İsteğin sunucuya gönderilmeden önce tarayıcı sırasında beklemesi sonucu iki durum orataya çıkar. Bu durumları biraz açarsak;

  • Bir web sayfasında iki adet javascript dosyası varsa bunlar aynı anda yüklenmez. İlk önce birisi yüklenir daha sonra ikincisi yüklenir. Bu nedenle mümkünse javascript dosyalarını teke indirmek bize zaman kazandıracaktır.
  • Her tarayıcının aynı anda sunucudan(her bir domain için) yapacağı istek sayısı sınırlıdır. Mesela bu sayı Firefox 3 için 6’dır. Yani bunun anlamı eğer sunucudan yapılacak istek sayısı 6’yı geçerse, altıncıdan sonrası ilk altının yüklenmesini beklemek durumunda kalacaktır. Bu nedenle CSS Sprite tekniği kullanımı önemlidir.

Net Sekmesi İstek ve Cevap Detayları

Her isteğin solundaki artı(+) işaretine tıklayarak daha ayrıntılı bilgi alabiliriz. Burada önemli bir noktayı açıklayalım: request sunucuya gönderimi response geri geleni gösterir. Eğer gösterilen öğe sunucudan veya ön bellekten geliyorsa bir adet request ve response görünecektir.

Açılan alandaki sekmeler ve anlamları;

  • Headers: HTTP istek ve cevapları
  • Response: Sunucudan dönen veri.
  • HTML: Verilen cevap HTML’in ön görünümü(sadece html ögeleri içindir.)

URL Parametreleri

Eğer sayfada kullanıcıdan veri alınmış ise Net panelinde yukarıdakine ek olarak Params sekmesi çıkar. Params sekmesinde kullanıcıdan gelen verileri görmemiz mümkündür.

http://www.softwareishard.com/firebug/introduction/net-panel/testPage1.htm?param1=value1&param2=value2

Post ve Put İstekleri

Eğer kullanıcından HTTP üzerinden veri istenmiş ise bunun için Post isimli yeni bir sekme açılacaktır ve kullanıcının gönderdiği veriler listelenecektir.

JSON Cevapları

JSON verisi olması durumunda yeni bir sekme daha açılacaktır ve json verileri bir liste halinde sıralanacaktır.

Tarayıcı Ön Belleği

Eğer sayfa ögesi tarayıcı ön belleğinde geliyorsa Cache sekmesi belirecektir. Bu sekme bize ön bellekten gelen bilgileri ayrıntısı ile gösterecektir.

Yukarıdaki ekran görüldüğü gibi listede 304 değişmedi ibaresi olan ögeler tarayıcı ön belleğinden alınıyor demektir.

Dosya Tipine Göre Yükleme Zamanları

Bazen biz sayfadaki ögelerin her biri için yüklenme zamanını bilmek isteriz, örneğin javascript veya resimler vb. Bunun biz Net sekmesine tıklayıp sonra eskiye göre üstte yenilerde alttaki sekmelerden(javascript, images) yapabiliriz. Buda bize toplam yüklenme zamanı ve farklı dosya tiplerinin yüklenme zamanı ayrımını yapma imkanı verir.

XMLHttpRequest İzleme

Şimdiye kadar yapılan istek ve cevapları inceledik. Bununla birlikte web sayfaları asenkron istekler ve cevaplarıda içermektedir, ajax olarak tanımlanan bu istek ve cevaplarıda Net panelinden izlememiz mümkündür. Bir sayfada ajax isteği olduğu durumları Net panelindeki XHR sekmesinden izleyebilir ve bilgilerini buradan alabiliriz.

http://www.janodvarko.cz/firebug/tests/BreakOnXHR/breakOnXHR.html Örnek sayfasını incelersek

Yukarıda görüldüğü gibi ajax istek ve cevapları hakkında detaylı bilgi alıyoruz. Clear düğmesi ile isteği silebiliriz.

FireBug Net Sekmesine Yardımı İle Performans Değerlendirmesi Yapmak

Benim açımdan FireBug Firefox’un en önemli eklentisidir. Bu nedenle diğer tarayıcılara geçmem şu an itibari ile imkansız. FireBug o kadar büyük bir eklentidir ki bu eklentiye bağlı çıkarılan eklentiler vardır. Bu eklentilerden bir kaçı;

  • Yahoo’bub çıkardığı YSlow
  • Google’un çıkardığı Page Speed

Bu eklentileri kullanarak web sayfalarımızın performansını ölçebiliriz. Ayrıca bu eklentiler bize sitemizdeki yavaşlamaya neden olan durumları açıkça gösterir ve düzeltmemiz için önerilerde bulunur.

Kaynaklar

Yine bir ie6 sorunu ile karşı karşıyayız. Evet proje biraz dallı budaklı olunca ie6 sorunları başa bela olmaya başladı. Normal standart site tasarımında sorunlar belli idi, ona göre kod yazıyordum, ancak şimdi proje normal site şablonlarından farklı olunca sorunlarda çalışmadığımız yerleden glemeye başladı.

Gelelim sorunun ne olduğuna; sorun şudur ki zemininden resim olan genişleyebilir alanlarda kullandığımız bir yöntem olan Sliding Doors(aynı yöntemi şurada da kullandım) yaptığım bir alanda hover efekti vermeye çalıştığımda karşılaştığım bir sorun. Daha kolay anlaşılmasıması ve benim içinde anlatması kolay olduğu için kaynaklardaki bir örneği vereceğim burada size ben.

HTML kodu

<div>
	<a href="#">foo<span>bar</span></a>
</div>

CSS Kodu

span {
	display: none;
}

a:hover span {
	display: inline;
}

Örneği görmek için tıklayınız.

Burada yapılan çok basit bir iştir. Bağlantı üzerine gelince span içindeki bar yazısını gösteriyoruz. Ancak ie6’da bu sayfaya baktığımızda bar görüntülenmeyecektir. 

Peki çözüm nedir?

Sorun hasLayout sorunu gibi görünsede genel hasLayout çözümleri pek işe yaramıyor. Haslayout sorunları ie6 ve ie7 de görülür, ancak Microsoft bu sorunu ie7 çözmüş görünüşe göre.

friendlybit.com sitesindeki çözüm yolu şöyle; a:hover elemanına padding-top:0 değeri atayıp sonrada a:hover span seçicisinede padding-top:0 değeri atayınca oluyor.

a:hover{
	padding-top:0;
}

span {
	display:none;
}

a:hover span {
	display: inline;
	padding-top:0;
}

Örneği görmek için tıklayınız.

Kaynaklar