Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 7 của 7
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    Kỹ thuật nén website MVC , Webform tăng tốc website

    Download mã nguồn ví dụ Tại Đây

    1. Nén nội dung HTML là gì

    - Các bạn truy cập website sau : LapTrinhViet
    - Xem mã nguồn website ( nhấn phím F12) ta thấy mã html được nén lại ( các khoảng trắng , commenr được xóa bỏ ) như hình sau :


    - Trong các phiên bản IIS6 , IIS 8 , IIS 8 ... có các tính năng Compress nén html rồi mới trả lại cho Browser .Và các trình duyệt hiện đại cũng hỗ trợ nội dung nén
    - Một vấn đề được đặt ra để dùng các tính năng Compress thì cần bật tính năng này trong IIS ( mà không phải nhà cung cấp hosting nào cũng bật tính năng này )
    - Ngoài ra với các trình duyệt không hỗ trợ nội dung nén thì vẫn sẽ hiển thị nội dung chưa được nén
    - Đồng thời chúng ta không quản lý được mã cũng như nội dung được nén
    - Vì thế chúng ta tìm tới giải pháp là viết 1 đoạn code nhỏ dùng để xóa các commnet , khoảng trẳng ngay trong mã nguồn của chúng ta hơn là sử dụng tính năng nén của IIS
    - Dưới đây chúng tôi hướng dẫn cách xóa khoảng trắng , commnet trong Webform và MVC

    2. Nén nội dung trong ứng dụng MVC

    2.1 Nén toàn bộ website

    - Đây thực chất là thêm 1 tính năng xóa comment , khoảng trắng cho RazorViewEngine
    - Tạo class nén file html như sau :

    Mã:
    using System.IO;using System.Text;using System.Text.RegularExpressions;using System.Web.Mvc;namespace VinaWebBase.Optimization{    // System.Web.WebPages.dll    public abstract class MinifyZipHtml<TModel> : System.Web.Mvc.WebViewPage<TModel>    {        static Regex REGEX_TAGS = new Regex(@">\s+<", RegexOptions.Compiled);        static Regex REGEX_ALL = new Regex(@"\s+|\t\s+|
    \s+|
    \s+", RegexOptions.Compiled);              public override void Write(object value)        {            if (value != null)            {                var html = value.ToString();                html = REGEX_TAGS.Replace(html, "> <");                html = REGEX_ALL.Replace(html, " ");                if (typeof(MvcHtmlString) == value.GetType())                {                    value = new MvcHtmlString(html);                }                else                    value = html;                          }            base.Write(value);        }        public override void WriteLiteral(object value)        {            if (value != null)            {                var html = value.ToString();                html = REGEX_TAGS.Replace(html, "> <");                html = REGEX_ALL.Replace(html, " ");                if (typeof(MvcHtmlString) == value.GetType())                {                    value = new MvcHtmlString(html);                }                else                    value = html;                          }            base.WriteLiteral(value);        }           }}
    Khai báo sử dụng lớp trên để nén các View được trả về trong các resquest
    - Tại file cấu hình web.config của View ( View/web.config)
    Ta đổi đoạn mã sau :


    Mã:
    <system.web.webPages.razor>    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />    <!--<pages pageBaseType="System.Web.Mvc.WebViewPage">      <namespaces>        <add namespace="System.Web.Mvc" />        <add namespace="System.Web.Mvc.Ajax" />        <add namespace="System.Web.Mvc.Html" />        <add namespace="System.Web.Optimization"/>        <add namespace="System.Web.Routing" />      <amespaces>    </pages>-->    <pages pageBaseType="VinaWebBase.Optimization.MinifyZipHtml">      <namespaces>        <add namespace="System.Web.Mvc" />        <add namespace="System.Web.Mvc.Ajax" />        <add namespace="System.Web.Mvc.Html" />        <add namespace="System.Web.Optimization"/>        <add namespace="System.Web.Routing" />      <amespaces>    </pages>  </system.web.webPages.razor>
    - Chú ý cần khai báo chính xác cả namespace lớp MinifyZipHtml
    - Khi sử dụng tính năng bundled của MVC 4 thì cần tham chiếu tới file css , script ảo như file vật lý thông thường , không dùng được các khái báo : @Styles.Render , @Scripts.Render
    - Ta có thể khai báo trực tiếp các file CSS , Script ảo như nhứng file css , script thật như sau :
    <link href="~/Content/css" rel="stylesheet" />
    <script src="~/bundles/modernizr"></script>
    <script src="~/bundles/jquery"></script>

    - Khi chạy ứng dụng các mã html được zip lại như hình sau :

    Download mã nguồn cho MVC chạy Project được kết quả như hình sau :



    Kiểm tra mã nguồn ta được kết quả như hình sau :



    2.2 Tạo Attribute nén nội dung cho Action của Controller bất kỳ

    - Với việc tạo thêm tính năng cho Razor View ở trên thì toàn bộ website sẽ bị nén
    - Ta có thể khai báo tính năng nén cho 1 Action cần thiết nào đó như sau :
    Tạo lớp Attribute :


    Mã:
    using System.IO;using System.Text;using System.Text.RegularExpressions;using System.Web.Mvc;namespace VinaWebBase.Optimization{        //using System.Web.Mvc;    public class MinifyHtmlFilter : ActionFilterAttribute    {        public override void OnActionExecuting(ActionExecutingContext filterContext)        {            var response = filterContext.HttpContext.Response;            response.Filter = new MinifiedStream(response.Filter);        }    }    public class MinifiedStream : MemoryStream    {        private readonly Stream _output;        public MinifiedStream(Stream stream)        {            _output = stream;        }        private static readonly Regex Whitespace = new Regex(@"(?<=[^])\t{2,}|(?<=[>])\s{2,}(?=[<])|(?<=[>])\s{2,11}(?=[<])|(?=[
    ])\s{2,}", RegexOptions.Compiled);        public override void Write(byte[] buffer, int offset, int count)        {            var html = Encoding.UTF8.GetString(buffer);            html = Whitespace.Replace(html, string.Empty);            html = html.Trim();            _output.Write(Encoding.UTF8.GetBytes(html), offset, Encoding.UTF8.GetByteCount(html));        }    }}
    Khai báo sử dụng Attribute trong Controller :

    Mã:
        [VinaWebBase.Optimization.MinifyZipHtmlFilter]    public class HomeController : Controller    {        public ActionResult Index()        {                      return View();        }    }
    - Có thể khai báo sử dụng cho từng Action như sau :


    Mã:
        public class HomeController : Controller    {       [VinaWebBase.Optimization.MinifyZipHtmlFilter]        public ActionResult Index()        {                      return View();        }    }

    3. Nén nội dung trong WebForm


    - Đơn giản hơn trong MVC , trong webform các bạn chỉ cần khai báo phương thức sau trong code behind
    // Khai báo phương thức sau trong code behind


    Mã:
            protected override void Render(HtmlTextWriter writer)        {                       if (this.Request.Headers["X-MicrosoftAjax"] != "Delta=true")            {                System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(@"<script[^>]*>[\w|\t|
    |\W]*?</script>");                System.Text.StringBuilder sb = new System.Text.StringBuilder();                System.IO.StringWriter sw = new System.IO.StringWriter(sb);                HtmlTextWriter hw = new HtmlTextWriter(sw);                base.Render(hw);                string html = sb.ToString();                System.Text.RegularExpressions.MatchCollection mymatch = reg.Matches(html);                html = reg.Replace(html, string.Empty);                reg = new System.Text.RegularExpressions.Regex(@"(?<=[^])\t{2,}|(?<=[>])\s{2,}(?=[<])|(?<=[>])\s{2,11}(?=[<])|(?=[
    ])\s{2,}|(?=[
    ])\s{2,}");                html = reg.Replace(html, string.Empty);                reg = new System.Text.RegularExpressions.Regex(@"</body>");                string str = string.Empty;                foreach (System.Text.RegularExpressions.Match match in mymatch)                {                    str += match.ToString();                }                html = reg.Replace(html, str + "</body>");                writer.Write(html);            }            else                base.Render(writer);        }
    Chạy ứng dụng webform ta được kết quả tương tự như ví dụ về MVC

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    - Chắc bác chưa thực hiện cũng như đọc kỹ bài viết của em .Với webform thì có lẽ như bác nói , ta thực hiện zip trong mỗi lần request .Với MVC thì khác cũng như tính năng bundled , ta custom View Engine ( Razor) và chỉ zip 1 lần trước khi có sự thay đổi dữ liệu .
    - Bác cứ yên tâm , chỉ cần zip nội dung nào chỉ cần 2 - 3 trang màn hình thôi sẽ thấy dung lượng giảm đáng kể .
    - Đây là 1 tính năng mình covert lại từ trang asp.net , yên tâm đi rất nhiều người đã sử dụng .
    Thư viện bundled của MVC4 thực ra trước phiên bản MVC 3 cũng có rất nhiều người dùng như 1 thư viện bên ngoài .Khi thấy nhiều người dùng thì MS mới tích hợp vào MVC4 thôi .
    - Cũng có thể có lý do để MS chưa tích hợp đó là bản thân IIS cũng có tính năng zip này rồi .Tuy nhiên không phải hosting nào cũng bật tính năng này .

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Đúng là chưa đọc thật [IMG]images/smilies/laughing.gif[/IMG] (tại cũng ko có nhu cầu cài đặt [IMG]images/smilies/1.gif[/IMG] ), chỉ ngó sơ, với lại thấy cái protected override void Render bên Web Form thì đoán là nó nén trên từng request ( trên lý thuyết cũng là như vậy mà ) [IMG]images/smilies/18.gif[/IMG]. Để mai mốt rãnh cài , write ra debug đàng hoàng xem sao

    Mà chả nhẽ bên asp.net họ ko có cách nào để vừa nén đc html vừa xài đc bundle à, thấy cái dòng "không dùng được các khái báo : @Styles.Render , @Scripts.Render", oải quá [IMG]images/smilies/21.gif[/IMG]

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Chọi đá tí xíu nha [IMG]images/smilies/laughing.gif[/IMG]
    Mình thấy cái này chỉ thuần túy mang tính trình diễn kỹ thuật chứ hiệu quả thực tế ko cao. Tại sao vậy ? Bởi vì không giống như mã javascript, mã html ko có nhiều thứ để nén. Cụ thể chỉ là xóa khoảng trắng, và xóa comment phải ko nhỉ, nói chung là nén ko được nhiều

    Điểm mấu chốt là để đạt được hiệu quả nén đó, bất kỳ trang web nào được phát sinh ra đều phải trải qua 1 khâu xử lý lọc và thay thế chuỗi khá là phức tạp trước khi được trả về cho client. Điều đó có nghĩa là để đạt được 1 chút cải thiện về băng thông client-server, chúng ta phải đánh đổi bằng việc thực hiện thêm những xử lý ở Server ( khổ thân CPU server [IMG]images/smilies/mad.png[/IMG] )

    Cái này hoàn toàn khác với chức năng bundle mới của MVC 4. Cái mà bundle nén chính là những file javascript và css, mà những file này lại hoàn toàn cố định => điều đó có nghĩa là thao tác "nén" sẽ chỉ cần thực hiện duy nhất 1 lần, sau đó mỗi khi có truy vấn, chỉ cần trả nội dung nén về cho client, cực kỳ hiệu quả

    Trong trường hợp nén HTML ở đây, do trang web của ta là web động, nội dung luôn biến đổi, nên đòi hỏi phải nén trên từng request. Tất nhiên, nếu sử dụng cơ chế cache thì chức năng nén này cũng có thể hiệu quả, nhưng nhìn chung nếu ko cache thì theo mình nén là ko cần thiết, cứ tốn thêm chút băng thông để cpu nó thở hay hơn [IMG]images/smilies/smile.png[/IMG])

    Những hạn chế này theo mình chính là lý do mà microsoft cho ra đời bundle cho css, javascript, nhưng lại ko có bundle cho html [IMG]images/smilies/18.gif[/IMG]

  5. #5
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Bác cho em hỏi trong webform thì trang nào trong code behind cũng thêm cái code đấy ạ ? Nếu thế thì thật là oải .

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trích dẫn Gửi bởi thvnhn
    Bác cho em hỏi trong webform thì trang nào trong code behind cũng thêm cái code đấy ạ ? Nếu thế thì thật là oải .
    Nếu bạn muốn áp dụng cái render này vào tất cả các Web Form thì bạn xây dựng 1 lớp BasePage mới kế thừ từ Page và cài đặt phương thức Render ở trên. Tất cả các các WebForm của bạn sẽ kế thừa từ BasePage thay vì Page [IMG]images/smilies/daydreaming.gif[/IMG]

  7. #7
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Trích dẫn Gửi bởi Sounj
    Đúng là chưa đọc thật [IMG]images/smilies/laughing.gif[/IMG] (tại cũng ko có nhu cầu cài đặt [IMG]images/smilies/1.gif[/IMG] ), chỉ ngó sơ, với lại thấy cái protected override void Render bên Web Form thì đoán là nó nén trên từng request ( trên lý thuyết cũng là như vậy mà ) [IMG]images/smilies/18.gif[/IMG]. Để mai mốt rãnh cài , write ra debug đàng hoàng xem sao

    Mà chả nhẽ bên asp.net họ ko có cách nào để vừa nén đc html vừa xài đc bundle à, thấy cái dòng "không dùng được các khái báo : @Styles.Render , @Scripts.Render", oải quá [IMG]images/smilies/21.gif[/IMG]
    Vẫn có thể dùng được .Bạn chỉ cần khai báo trực tiếp đường dẫn tới các file zip ảo này như 1 file vật lý mà không thông qua @Styles.Render , @Scripts.Render .
    Khai báo @Styles.Render , @Scripts.Render chỉ nhằm phân biệt đây là file được zip mà thôi

 

 

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •