Asp.Net MVC ile Html Minifier Modülü Yazalım

  • 12.08.2017
  • M.Tayyip Yetiş
  • ASP.Net

Herkese merhaba, web uygulamaları geliştirirken dikkat edilen kriterlerden biri de performans optimizasyonlarıdır. Bir web sitesinin kullanıcı dostu olmasının bir çok etkeni vardır bunlardan biri de sitenin performanslı çalışmasıdır yani isteklere hızlı cevap vermesidir. Bu hızı da etkileyen yine bir çok etken vardır; Veritabanı sorguları, resim video gibi medya dosyalarının sayısı ve boyutu, sunucu performansı ve anlık yoğunluğu, kodlamadaki gereksiz döngüler ve yoğun işlemler, javascript css gibi tarayıcı tarafında çalıştırılan dosyaların boyutu gibi kriterler sitenin hızını etkiler

Bu olumsuz durumlar için bir çok farklı çözüm geliştirilmiştir. Örneğin; Cache (Önbellekleme) sistemleri kullanarak sunucudaki yoğunluğu azaltıp performans sağlayabilirsiniz bu yolla veritabanı işlemleri dahil sunucu tarafındaki sorunları pass geçebilirsiniz. Client tarafı için ise Http Cache kullanarak, CDN kullanarak tarayıcının javascript, css gibi dosyaları tekrar tekrar çağırmasını engelleyebilirsiniz. Html sayfalar için ise OutputCache kullanarak Html içeriğin sadece belli aralıklarla güncellenmesini sağlayabilirsiniz. Fakat bazı senaryolar için alternatif yöntemler kullanmanız gerekebilir örneğin; html boyutu fazla olan bir sayfayı cache kullanarak hızlandırabilirsiniz fakat bu sayfa dinamik içerik oluşturan bir sayfa ise yapabileceğiniz en iyi şeylerden biri html dosya içerisindeki satır sonları, gereksiz boşluklar gibi karakterleri silerek kilobyte boyutunda sıkıştırma yapabilirsiniz. Bu sıkıştırma özellikle mobil cihazlarda hissedilir derecede hız artışına sebep olabilir. Sitenizin performansını ölçmek için Google Page InsightsGoogle Analysticshttps://testmysite.withgoogle.com gibi araçları kullanabilirsiniz

Javascript, CSS gibi dosyaları da sıkıştırarak tarayıcı ve sunucu arasındaki veri miktarını azaltarak performansı önemli derecede artırabilirsiniz. Sıkıştırma işlemini manuel olarak tek sefer yapabilirsiniz http://refresh-sf.com/ sitesinden bu işlemi gerçekleştirebilirsiniz. Asp.net MVC ile çalışıyorsanız Bundle kullanarak Minification işlemi yapabilirsiniz bu yolla js ve css dosyalarında değişiklik yapsanız bile mvc bu değişikliği algılayıp otomatik versiyonlayarak sıkıştırılmış halini tarayıcıya gönderir. Biz ise bu makalede Html sıkıştırma işlemi için bir modül yazacağız örnek Asp.Net MVC 4 ile Visual Studio 2012 üzerinde gerçekleştirilmiştir.

WhitespaceModule.cs

#region Using

using System;
using System.IO;
using System.Web;
using System.IO.Compression;
using System.Text.RegularExpressions;

#endregion

public class WhitespaceModule : IHttpModule
{

    #region IHttpModule Members

    void IHttpModule.Dispose()
    {

    }

    void IHttpModule.Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(context_BeginRequest);
    }

    #endregion

    void context_BeginRequest(object sender, EventArgs e)
    {
        HttpApplication app = sender as HttpApplication;
        if (app.Request.RawUrl.StartsWith("dynamicpage"))
        {
            app.Response.Filter = new WhitespaceFilter(app.Response.Filter);
        }
    }

}

WhitespaceFilter.cs

    private class WhitespaceFilter : Stream
    {

        public WhitespaceFilter(Stream sink)
        {
            _sink = sink;
        }

        private Stream _sink;
        private static Regex reg = new Regex(@"(?<=[^])\t{2,}|(?<=[>])\s{2,}(?=[<])|(?<=[>])\s{2,11}(?=[<])|(?=[\n])\s{2,}");

        #region Properites

        public override bool CanRead
        {
            get { return true; }
        }

        public override bool CanSeek
        {
            get { return true; }
        }

        public override bool CanWrite
        {
            get { return true; }
        }

        public override void Flush()
        {
            _sink.Flush();
        }

        public override long Length
        {
            get { return 0; }
        }

        private long _position;
        public override long Position
        {
            get { return _position; }
            set { _position = value; }
        }

        #endregion

        #region Methods

        public override int Read(byte[] buffer, int offset, int count)
        {
            return _sink.Read(buffer, offset, count);
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return _sink.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            _sink.SetLength(value);
        }

        public override void Close()
        {
            _sink.Close();
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            byte[] data = new byte[count];
            Buffer.BlockCopy(buffer, offset, data, 0, count);
            string html = System.Text.Encoding.Default.GetString(buffer);

            html = reg.Replace(html, string.Empty);

            byte[] outdata = System.Text.Encoding.Default.GetBytes(html);
            _sink.Write(outdata, 0, outdata.GetLength(0));
        }
        #endregion
    }

WhitespaceModule modülü ile her request'i yakalıyoruz bu request'ler içerisine her türlü dosya dahil olduğu için filtrelememiz gerekiyor ben bu örnekte url'si  "dynamicpage" ile başlayan talepler için sıkıştırma yapmasını belirttim. Daha sonra WhitespaceFilter ile customize bir Stream sınıfı oluşturuyoruz bunun sebebi normalde bu sınıfın CanSeek, CanWrite gibi özelliklerinin false olmasından dolayı yazmaya imkan vermemesidir.

Son olarak uygulamanızın yazdığınız modülü tanıması için web.config dosyasına aşağıdaki etiketleri eklemelisiniz. (IIS integrated modu için)

<system.webServer>
    <modules>
      <add name="WhitespaceModule" type="WhitespaceModule"/>
    </modules>
</system.webServer>

Aşağıda örnekteki modülün bir html parçasına etkisini görebilirsiniz

<h2>Index</h2>

<div>
    <p>
        deneme
    </p>
</div>

Sıkıştırma sonrası

<h2>Index</h2><div><p>deneme</p></div>

Kaynak: http://madskristensen.net/post/a-whitespace-removal-http-module-for-aspnet-20

Umarım faydalı olmuştur

Mustafa Tayyip Yetiş
Yazılım Geliştirme Uzmanı

Yorum Yap