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 :

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 (: