Fırat Esmer

Microsoft Yazılım Teknolojileri

CSS Sprite Kullanımı (HTTP İstek Sayısını Azaltarak Performans Artışı Sağlama)

Yeni bir ASP.NET performans makalesi ile karşınızdayım. Bu makalede, web uygulamamızdaki bir image üzerinden css koordinat (sprite) yöntemiyle nasıl birden fazla image'e yol verilir ve bu yöntemin avantajları nedir, kısaca açıklamalar yapacağım.

Facebook'ta bulunan küçük resimlerin  (durum, bağlantı, fotoğraf gibi) kaynağını incelediğinizde karşınıza şöyle bir resim çıkacak :

Facebook Resimleri

Gördüğünüz gibi tek büyük bir resim var. Bu tek büyük resim üzerinden parçalar alınarak, Facebook'ta bulunan diğer kesitlere image yolları veriliyor. Yapılan işlem aslında çok basit ve bir o kadar da kazançlı. Yöntem, tek resim üzerinden x ve y koordinatları verilerek diğer resimlere yol verilmesi işleminden ibaret aslında. Bu işlemi uygulayan tek şirket Facebook değil. Google Reader, Ask, µTorrent,Telerik bunlara örnek. Gelelim önemli iki noktaya. Neden böyle bir yola başvuruyoruz ve nasıl yapıyoruz?

Neden?

Sunucuya gönderilen istek sayısı azalıyor.

Eğer her resim için tek tek yol verseydiniz, bu her yol için sunucuya istek gönderilecekti. Ancak bir resim üzerinden koordinat yöntemiyle birden fazla resme yol verirseniz, sadece tek istek (büyük resim için) gidecekti. Sunucuya giden her istek tepki süresinin uzaması ve kullanıcının beklemesi demektir. Belki de koordinat yöntemiyle sunucuya giden istek sayısını azaltarak en kolay performans artışını sağlayacağız.


HTML Diğer
Yahoo! %10 %90
Google %25 %75
MySpace %9 %91
MSN %5 %95
eBay %5 %95
Amazon %38 %62
Youtube %9 %91
CNN %15 %85

Yahoo! User Interface Blog sitesinin, "Performance Research, Part 1: What the 80/20 Rule Tells Us about Reducing HTTP Requests" adlı makalesinden alıntıdır. Not : Yukarıdaki değerler, cache varsayılmadan ve ortalama 2.5 Mbps internet bağlantı hızının test sonuçlarıdır.

Yukarıdaki tablo popüler bir kaç web sitesinin sayfaları oluşturulurken harcadıkları zamanı gösteriyor. HTML belgesinin indirilmesi %5 ile %38 arasında zaman alırken, diğer parçaları (resimler, script ve style dosyaları) yüklemek %62 ile %95 arasında değişiyor. Yani HTTP istek sayısının azaltılmasıyla, gözle görünür seviyede performans artışı yaşayabiliriz. (İstatistiki bilgiler kullanıcının tarayıcı modeline ve gönderilen isteğe göre değişebilir.)

Tek resim daha az yer kaplıyor.

Birden fazla resmin kullanımı, tek bir resmin kullanımından daha dezavantajlıdır. Bunun en somut örneği; tek resmin boyutunun, diğer parçalar halinde kullanılan resimlerin boyutundan küçük olmasıdır. Böylece sayfayı yüklemek isteyen kullanıcılar daha az indirme işlemi yapıcak ve daha az bekleyeceklerdir.

Nasıl?

İşlemi 2'ye böleceğim. İlkinde resimlerin yolunu tek tek resimlerden çağırıp, sonucu inceleyeceğiz. İkincisinde ise resimlerin yollarını tek bir resimden çekip inceleyeceğiz. İncelemenin sonunda ne kazanıp, ne kaybettiğimizi analiz edip, konuyu kapatacağız (:

İLK HALİ

Bir adet table içerisine yaklaşık 9 tane kolon yerleştireceğim ve bu her kolonun içerisine CSS dosyasından resim ekleyeceğim. CSS dosyamız kısaca şöyle görünecek :

#koordinat a.item1

{

/*Direkt olarak resmin yolunu veriyoruz.*/

background-image: url(../image/image_1.png);

background-repeat: no-repeat;

margin-bottom: 30px;

}

#koordinat a.item2

{

background-image: url(../image/image_2.png);

background-repeat: no-repeat;

margin-bottom: 30px;

}

HTML tarafındaki a.item denilen kısım ise aşağıdaki gibi görünecektir.

<a class="item1" href="#" title="Gruplar">Gruplar</a>

İlk olarak buraya tıklayıp demo'yu inceleyin. Kaynak koduna bakın, öğeleri teftiş edin. Hatta HttpWatch adlı programa sahip değilseniz, buradan indirin. HttpWatch adlı program, kullanmak istediğiniz sayfanın sunucu ile ilişkisini bize detaylı bir şekilde gösterir. Bizim burada programı kullanma amacımız sunucuya kaç adet HTTP isteğinin gideceği ve tepki süresinin ne kadar süreceğini göreceğiz.

Demo'nun ekran görüntüsünü, analiziyle beraber görmek için buraya tıklayın!

Resimlerin yolunu tek tek verdiğimizde ortaya çıkan sonuç : 11 HTTP istek, 0.520 saniyelik sayfa yüklenme süresi ve 2,44KB resim dosyası boyutu.

SON HALİ

Şimdi yapacağımız işlemin, diğer örnektekinden farkı ufak dilimlere bölünmüş resim yerine hepsinin yer aldığı tek bir resim kullanmak ve CSS dosyamıda değişiklik yapmak. CSS dosyamızdaki değişiklik şöyle olacak :

#koordinat a

{

/*Bu sefer küçük resimlerin toplandığı büyük resmin yolunu veriyoruz.*/

background-image: url(../image/facebook.png);

background-repeat: no-repeat;

padding: 0 0 0 90px;

display: block;

height: 16px;

font-family:Tahoma;

}

#koordinat a.item1

{

background-position: 30px 0px;

margin-bottom: 30px;

}

#koordinat a.item2

{

/*Aşağıda yazılan css şunu açıklıyor : kesiti alınacak resmin x ve y koordinatlarını veriyoruz. Büyük resmimiz yukarıdan aşağıya olduğu için x koordinatı sabit, y ise belli aralıklarla eksi yönünde gidiyor. */

background-position: 30px -18px;

margin-bottom: 30px;

}

Web uygulamamızın son halinin demosunu görmek için buraya tıklayıp, diğer örnekte olduğu gibi inceleyin. Resimlerin tek bir resimden geldiğini göreceksiniz.

Demo'nun ekran görüntüsünü, analiziyle beraber görmek için buraya tıklayın!

Resimlerin yolunu tek bir resimden çektiğimizde çıkan sonuç : 3 HTTP istek, 0.132 saniyelik sayfa yüklenme süresi ve 1,19KB resim dosyası boyutu.

Gözle görülür şekilde performans artışı bu olsa gerek. Makalede geçen iki demo'nun da tek bir yerde toplanmış halini indirmek istiyorsanız buraya tıklayın (.NET Framework 3.5 ve Visual Studio 2010 ile hazırlandı). Yardımlarını esirgemeyen George'a teşekkürler (:

Image Optimizer Eklentisi Hakkında

Image Optimizer, resimlerin kalitesini bozmadan boyutunu küçülten yüzlerce Visıual Studio 2010 eklentisinden sadece bir tanesi, üstelik ücretsiz. Benim kullanım alanım, Visual Studio 2010 içerisinde web uygulamalarımda performans kazancı elde etmek. Nasıl mı?

Web sitenizde kullandığınız resimler, sitenizi ziyaret eden kişiler tarafından bilgisayarlarına indirildikten sonra görüntülenir. O yüzden resmin boyutu ne kadar küçük olursa kullanıcı, sayfanızı ve resimlerinizi o kadar hızlı görüntüler. Bu da performans açısından çok dikkat edilmesi gereken bir noktadır. Peki resmin kalitesini bozmadan nasıl oluyor da boyutunu küçültüyor? Resimlerde bulunan enstantane, diyafram, pozlama, fotoğraf makinesi markası, modeli gibi teknik detayları içerisinde barındıran dosyanın veri birimini (ki buna EXIF = Exchangeable image file format - Değişebilir görüntü dosyası biçimi denir) veya diğer metadata'ları siler. Böylece fotoğraf üzerinde bulunan bizim için gereksiz olan detaylar silinmiş olur ve dosyanın boyutu küçülür. Bunun yanından daha ayrıntılı algoritma var ancak detayına inmeyeceğim. Küçültme işlemi için smushit ve punypng'yi kullanan eklentinin desteklediği formatlar ise :

  • PNG,
  • GIF,
  • Animasyon GIF,
  • JPG.

NOT : Image Optimizer eklentisini kullanabilmeniz için Visual Studio 2010 kullanıyor olmalısınız.

Projenizde bulunan dosyaları ister tek tek, isterseniz de seçtiğiniz klasörün altındaki tüm dosyaları bir kerede optimize edebilirsiniz. Aşağıdaki resimde birden fazla dosyayı bir kerede optimize edeceğim. 

Image Optimizer Eklentisinin Kullanım Şekli

Karşımıza çıkacak olan sonuç ise aşağıdaki gibi olacaktır. 

Image Optimizer Eklentisinin İşlem Sonucu

İşlemimiz bu kadar. Görüntü kalitesinde değişiklik olup olmadığını merak ediyorsanız buraya tıklayarak hazırlamış olduğum örneği indirebilirsiniz (.NET Framework 3.5 ve Visual Studio 2010 ile hazırladım). Image Optimizer eklentisini indirmek veya hakkında daha fazla bilgi almak istiyorsanız buraya tıklayın. (Not : Direkt olarak Visual Studio'nun Extension Manager kısmından da indirebilirsiniz.)