Web sayfaları, sunucudan istemci makineye html şeklinde bir yazı olarak aktarılır. Gönderilen sayfanın büyüklüğü ve sunucunuz ile istemci arasındaki bant genişliği sayfanızın açılma süresini belirleyen önemli etkenlerdendir. Bu konuda performansı artırmak için alınabilecek tedbirlerden birisi de http sıkıştırmasıdır.
Http sıkıştırması (http compression), web sayfasının içeriğinin sıkıştırılarak -yani bir anlamda ziplenerek- daha küçük bir boyuta çekildikten sonra istemciye gönderilmesi olarak tanımlanabilir. Sayfalar, resim vb binary verileri saymazsak düz metinden oluşur ki bu da onun sıkıştırma ile çok fazla küçülebilmesini sağlar.
Peki bu mekanizma nasıl çalışıyor, sunucuda sıkıştırılan veriyi kim açıyor diyebilirsiniz. İşte tam bu noktada istemcideki internet tarayıcı programlar devreye giriyor. Tarayıcı, sunucudan gelen sıkıştırılmış içeriği açarak normal bir şekilde görüntüleyebilmemizi sağlıyor. Http sıkıştırma desteği HTTP 1.1 ile yaygınlaşmıştır ve bir çok internet tarayıcı programın yaklaşık olarak 1999' dan sonraki versiyonları bu yeteneğe sahiptir.
Sıkıştırma işleminin problemsiz bir şekilde gerçekleşebilmesi içinse http protokolünün gizli kahramanları olan header dan birisi devreye giriyor. Bahsettiğim Http Header' ı Accept-Encoding. İstemci sunucudan bir sayfayı istediğinde bu header ile desteklediği sıkıştırma şeklini (gzip, deflate, vs.) bildirir. Sunucu bu header' daki bilgiyi kullanarak sıkıştırma yapıp yapmayacağını ve yapacaksa sayfa içeriğini hangi şekilde sıkıştıracağını seçer.
Http sıkıştırması genelde faydalı bir şey olsa da özel durumlarda bir avantaj sağlamayabilir hatta belki dezavantaj olarak bile düşünülebilir. Öncelikle istemciler ile uygulama(sunucu) arasında çok geniş bir bant genişliği varsa ve sayfanın hazırlanması değil de aktarılması konusunda bir hız sıkıntısı yoksa çok da gerekli olmayabilir. Bunun üstüne bir de sıkıştırma işleminin istemci ve daha da önemlisi sunucunun işlemci saatinden azımsanamayacak bir kaynak tüketeceğini de göz önüne alırsak istemci ya da sunucunun işlemci eksikliği olduğu durumlarda da kullanılmadan önce iyice analiz edilmesi gerekir.
Şimdi işin özünü anladıktan sonra http sıkıştırmasını nasıl uygulayabileceğimizi görelim.
Öncelikle şunu hemen belirteyim ki sıkıştırma işlemini program içinden halletmek dışında web sunucunuzun ayarları ile da sağlayabilirsiniz. Örneğin IIS 6.0' da yönetim ekranında Web Siteleri (Web Sites) sekmesine sağ tıklayıp özellikler ekranında Hizmet (Service) sekmesine gelerek Http Sıkıştırması aktif hale getirebilirsiniz. Ancak şunu da belirteyim ki bu durumda işlem web sunucusunun insiyatifine kalıyor. Sebebini bilmiyorum belki benim hatamdandır ama bunu denediğimde sayfanın sıkıştırılmasını sağlayamamıştım.
Neyse ben kimseye güvenmem kendi işimi kendim görürüm :) diyenler için bu işin programdan nasıl yapılabileceğini görelim şimdi de. Asp.Net uygulamasında bu işin yapılabileceği en uygun yer Global.asax dosyası içerisinde bulabileceğiniz Application_BeginRequest kısmıdır. Eğer uygulamanızsa Global.asax dosyasını bulamıyorsanız öncelikle projeye bu dosyayı eklemeniz gerekli. Application_BeginRequest, web sitenize ya da uygulamanıza yapılan her istekte çalışır. Burada yapacağımız işlemleri şu şekilde özetleyebiliriz. Önce istemcinin sıkıştırma yeteneklerini kontrol edeceğiz ve sonrasında da bize uygun olan varsa ona göre içeriği sıkıştırılmasını sağlayacağız. Aşağıdaki örnekte framework ün kendi sıkıştırma kütüphanelerini(System.IO.Compression) kullanacağım. Ama isterseniz internette arama yaparak bulabileceğiniz başka şekillerde de sıkıştırma yapabilirsiniz.
Unutmadan son önemli bir konudan bahsedeceğim. Maalesef, ajax barındıran bir sayfada asenkron postbacklerde http sıkıştırmasını devre dışı bırakmamız gerekiyor. Bunu aşağıdaki kodda HTTP_X_MICROSOFTAJAX ifadesinin geçtiği satırda görebilirsiniz. Sayfada böyle bir değer varsa asenkron bir postback olduğunu düşünerek sıkıştırmayı devre dışı bırakıyoruz. Ayrıca ScriptResource.axd ve WebResource.axd dosyalarını da sıkıştırmamız gerekiyor. Çünkü gördüğüm kadarıyla tarayıcılar bu dosyaları sıkıştırılmış olarak aldıklarında açmıyorlar bu da sorunlara neden oluyor.
İşte küçük ama yetenekli kodumuz:
Imports System.IO
Imports System.IO.Compression
Public Class Global_asax
Inherits System.Web.HttpApplication
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim uygulama As HttpApplication = CType(sender, HttpApplication)
Dim encodingDegeri As String = uygulama.Request.Headers("Accept-Encoding")
Dim icerikStreami As Stream = uygulama.Response.Filter
If String.IsNullOrEmpty(encodingDegeri) = False AndAlso uygulama.Request.Path.EndsWith(".axd") = False Then
If String.IsNullOrEmpty(uygulama.Request("HTTP_X_MICROSOFTAJAX")) = False Then
Exit Sub
End If
encodingDegeri = encodingDegeri.ToLower() 'kıyaslamada sorun çıkmaması için küçük harfe çeviriyoruz
If encodingDegeri.Contains("gzip") Then ' gzip destekleniyorsa
uygulama.Response.Filter = New GZipStream(icerikStreami, CompressionMode.Compress)
uygulama.Response.AppendHeader("Content-Encoding", "gzip")
ElseIf (encodingDegeri.Contains("deflate")) Then 'deflate destekleniyorsa
uygulama.Response.Filter = New DeflateStream(icerikStreami, CompressionMode.Compress)
uygulama.Response.AppendHeader("Content-Encoding", "deflate")
End If
End If
End Sub
End Class
Bütün bu işlemlerden sonra yaptığıma deydi mi bari tereddütüne düşmemeniz için Fiddler ile sayfalarınızın önceki ve sonraki aktarım boyutlarını kontrol edebilirsiniz. Veya sayfanızın internetten ulaşılabilir olması halinde http://www.port80software.com/tools/compresscheck? adresinden de sayfanızın sıkıştırma ile ne kadar performans artışı sağladığını da görebilirsiniz.
Son olarak şunu da belirteyim ki bu yazıda anlatılanlar düşük bir ihtimal de olsa uygulamalarınızda beklenmedik hatalara neden olabilirler. Bu sebeple yayına geçmeden önce güzelce test edilmesini tavsiye ederim.