ASP.NET MVC4: Bundling và Minification
Bài đăng này đã không được cập nhật trong 8 năm
Bundling: Là một nhóm file mà có thể được tham chiếu bởi một tên duy nhất và được loaded bởi HTTP requestor.
Minification: Đó là xư lý để bỏ đi các khoảng trống dư thừa, xuống dòng và comment trong code để giảm đi cỡ và cải thiện thời gian load.
Tại sao phải dùng 2 kỹ thuật này : Cơ bản các developer sử dụng nhiều files JS và CSS files và dẫn tới vấn đề performance cho web. Bởi vì nhiều file JS và CSS files yêu cầu nhiều HTTP Requests từ trình duyệt dẫn tới suy giảm về hiệu suất và thời gian load cho web.
1/ Tạo chương trình web SP.NET MVC 4
2/ Tạo DemoController.Tôi tạo 2 view mới cho DemoController (Index.aspx và Create.aspx)
- Index.aspx sẽ tham chiếu đến JS-File-1.js, JS-File-2.js
- Create.aspx sẽ tham chiếu đến JS-File-3.js, JS-File-4.js
3/ Trước khi tiến hành kỹ thuật Bundling và Minification , hãy xem performance của web sử dụng firebug
Index.aspx:
Create.aspx:
Chúng ta có thể thấy Index.aspx tạo 2 request cho trình duyệt (JS-File-1.js, JS-File-2.js) và cỡ response là 409.9 KB, tương tự Create.aspx tạo 2 request cho trình duyệt (JS-File-3.js, JS-File-4.js) và cỡ response lại là 427.2 KB.
4/ Dùng bundle mặc định sẽ như sau
Mở file global.asax.cs và trong sự kiện Application_Start viêt những dòng sau.
BundleTable.Bundles.EnableDefaultBundles();
Bỏ tham chiếu JS/CSS trong view và thêm những dòng code sau để tham chiếu đến đường dẫn bundle bundle path.
<script src="<%: Url.Content("~/Scripts/Demo JS Files/JS") %>" type="text/javascript"></script>
Vấn đề của bundle mặc định là nó sẽ vẫn tham chiếu / download tất cả những file trong folder đó ở thời gian request trình duyệt nên performnace trông như dưới đây không cải thiện được mấy...
Index.aspx
Create.aspx
5/ Dùng custom bundle để cải thiện những điều trên
Lớp Bundle từ Microsoft.Web.Optimization được sử dụng để tạo Custom Bundles. Để tạo custom bundle chúng ta cần tạo ra đối tượng của lớp Bundle bằng cách chỉ ra đường dẫn ảo mà có thể tham chiếu đến custom bundle và loại transform là JavaScript hay là CSS.
Tôi tạo 2 bộ bundle, một cho Index.aspx và cái khác cho Create.aspx, nên tôi tạo 2 bundle trong sự kiện Application_Start .
Bundle indexBundle = new Bundle("~/IndexBundle", typeof(JsMinify));
indexBundle.AddFile("~/Scripts/Demo JS Files/JS-File-1.js");
indexBundle.AddFile("~/Scripts/Demo JS Files/JS-File-2.js");
BundleTable.Bundles.Add(indexBundle);
Bundle createBundle = new Bundle("~/CreateBundle", typeof(JsMinify));
createBundle.AddFile("~/Scripts/Demo JS Files/JS-File-3.js");
createBundle.AddFile("~/Scripts/Demo JS Files/JS-File-4.js");
BundleTable.Bundles.Add(createBundle);
Code dưới đây để tham chiếu trong view.
<script src="<%: Url.Content("~/CreateBundle") %>" type="text/javascript"></script>
Đây chúng ta chạy website và xem performance lần nữa của 2 trang Index.aspx và Create.aspx
Index.aspx
Create.aspx
Bạn có thể thấy Index.aspx làm 1 request và cỡ response lại chỉ là 217.3 KB. Truoc đó là 409.9 KB
Tương tự, Create.aspx tạo chỉ 1 request và cỡ response lại chỉ 168.2 KB nhưng trước đó là 427.2 KB.
6/ Sử dụng CDN
Mục đích : Thay vì dùng jquery local có thể dùng online được nghĩa là dùng CDN jQuery. Code sau thay thế bundle jquery trên môi trường local với CDN jQuery bundle.
public static void RegisterBundles(BundleCollection bundles)
{
//bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
// "~/Scripts/jquery-{version}.js"));
bundles.UseCdn = true; //enable CDN support
//add link to jquery on the CDN
var jqueryCdnPath = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js";
bundles.Add(new ScriptBundle("~/bundles/jquery",
jqueryCdnPath).Include(
"~/Scripts/jquery-{version}.js"));
// Code removed for clarity.
}
Trong trường hợp request từ CDN fail thì ta nên viết code như sau để lấy từ môi trường local
</footer>
@Scripts.Render("~/bundles/jquery")
<script type="text/javascript">
if (typeof jQuery == 'undefined') {
var e = document.createElement('script');
e.src = '@Url.Content("~/Scripts/jquery-1.7.1.js")';
e.type = 'text/javascript';
document.getElementsByTagName("head")[0].appendChild(e);
}
</script>
@RenderSection("scripts", required: false)
</body>
</html>
All rights reserved