Thứ Hai, 27 tháng 7, 2015

Tối ưu hóa để tăng tốc website MVC

Tối ưu hóa để tăng tốc website luôn là một vấn đề được các lập trình viên quan tâm tới bên cạnh việc tạo ra một website như ý. Hiện nay, có rất nhiều công cụ cũng như phương pháp từ đơn giản đến phức tạp nhất để tối ưu hóa website, đặc biệt là website ASP.Net MVC luôn được các lập trình viên cho là hơi "nặng" vì phải mang theo lượng lớn dll.

Tối ưu hóa để tăng tốc website ASP.Net MVC

Tôi xin giới thiệu một số phương pháp giúp chúng ta tối ưu hóa website ASP.Net MVC:

1. Nén mã CSS và Javascript
Trong ASP.Net MVC có cơ chế bundles (BundleConfig.cs), việc khai báo các file css và javascript trong file này giúp chúng ta nén các mã CSS và Javascript, từ đó giúp giảm thời gian tải trang.

2. Chuyển mã Javascript xuống cuối trang
Đây là một mẹo nhỏ rất hay tăng đáng kể tốc độ tải web. Người xem website không cần thiết phải chờ để tải hết toàn bộ mã javascript đặt ở đầu trang, cái họ cần nhìn thấy trước tiên là bố cụ trang (mã html và css) của bạn, sau đó mới đến các sự kiện phía client của javascript, vì vậy cách tối ưu nhất là hãy để chúng ở cuối trang web của bạn.

3. Chạy Release Mode
Chắc chắn là hệ thống web của bạn đang chạy trong chế độ “Release”


File file web.config:
?
1
2
3
4
<compilation debug="false" targetframework="4.0">
    <assemblies>
    </assemblies>
</compilation>
Tại sao chúng ta cần cái này: vì MVC sẽ không làm bất cứ View Look-up Caching  nếu bạn chạy ứng dụng trong chế độ Release Mode

4. Sử dụng duy nhất một View Engine Mặc định trong file global.asas.cs của chúng ta sẽ như thế này
?
1
2
3
4
5
6
protected void Application_Start()
{
   AreaRegistration.RegisterAllAreas();
   RegisterGlobalFilters(GlobalFilters.Filters);
   RegisterRoutes(RouteTable.Routes);
}
Mặc định hệ thống sẽ hỗ trợ hai engine: Razor và Aspx. Và không có lý do gì để ta phải trả phí cho cái mà ta không sử dụng, điều này sẽ làm hệ thống của chúng ta chậm, do đó chúng ta cần điều chỉnh lại, chỉ sử dụng một Engine duy nhất. Trong trường hợp này, tôi đang sử dụng Raror nên tôi sẽ add Raror Engine
?
1
2
3
4
5
6
7
8
protected void Application_Start()
{
   AreaRegistration.RegisterAllAreas();
   RegisterGlobalFilters(GlobalFilters.Filters);
   RegisterRoutes(RouteTable.Routes);
   ViewEngines.Engines.Clear();
   ViewEngines.Engines.Add(new RazorViewEngine());
}
5. Không chuyển giá trị null ViewModel đến View
Khi nào vấn đền này xảy ra
  • Bạn chuyển giá trị null ViewModel đến view dùng html helpers giống như View:
  • ?
    1
    2
    3
    4
    5
    @model PawLoyalty.ViewModels.Product  
           
    @{             
        @Html.TextBoxFor(m => m.ProductName);     
    }
  • Thường xảy ra khi Insert dữ liệu
Trong trường hợp nếu chúng ta truyền giá trị Null, thì hệ thống sẽ trả về NullReferenceException. Rõ ràng, nếu chúng ta xử lý tốt thì hệ thống sẽ không cần kiểm tra giá trị Null cho các giá trị khởi tạo, điều này gây nên sự lãng phí hệ thống
Ví dụ: khai báo này không tốt cho hệ thống
?
1
2
3
4
5
[HttpGet]
public ActionResult Add() //get empty data for user input operation
{
   return View();  //here the model instance defaults to null
}
Khai báo tốt cho hệ thống
?
1
2
3
4
5
[HttpGet]
public ActionResult Add()//get empty data for user input operation
{
   return View(new Product());//here the ViewModel Product has been sent
}
6. Sử dụng Cache khi có thể
Trong trường hợp giá trị nội dung ít thay đổi, thì việc sử dụng OutputCacheAttribute sẽ giúp các bạn tiết kiệm rất nhiều về số lượng kết nối hệ thống hoặc truy vấn dữ liệu

?
1
2
3
4
5
[OutputCache(VaryByParam = "none", Duration = 3600)]
public ActionResult Categories()
{
    return View(new Categories());
}
Trên là ví dụ mô tả cách sử dụng cache trong ASP.Net MVC. Điều này phù hợp với các ứng dụng nhỏ và sữ liệu ít thay đổi. Tuy nhiên, với các ứng dụng lớn, số lượng truy cập nhiều thì đây không phải là sự lựa chọn tốt. Khi đó các bạn nên nghĩ đến những cache khác như có memcached provider để có thể đáp ứng nhu cầu của bạn

7. Sử dụng HTTP Compression
Các bạn mở file web.config, thêm vào đoạn code sau
?
1
2
3
4
<system.webserver>
    <urlcompression dodynamiccompression="true" dostaticcompression="true" dynamiccompressionbeforecache="true">
    </urlcompression>
</system.webserver>
8. Loại bỏ những modules không sử dụng
Khi khởi tạo Project mới, khuyên các bạn nên tạo empty project để có thể loại bỏ bớt những modules (là các dll) không cần thiết so với khi tạo project dạng aplication
Các bạn khai báo thêm đoạn code sau để loại bỏ các modules không dùng
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<httpmodules>
    <remove name="WindowsAuthentication"></remove>
    <remove name="PassportAuthentication"></remove>
    <remove name="Profile"></remove>
    <remove name="AnonymousIdentification"></remove>
</httpmodules>
 
<pages buffer="true" enableviewstate="false"></pages>
 
<configuration>
    <system.web>
        <trace enabled="false"></trace>
    </system.web>
</configuration>
 
<system.web>
    <httpruntime enableversionheader="false"></httpruntime>
</system.web>
 
<httpprotocol>
    <customheaders>
    <remove name="X-Powered-By"></remove>
    </customheaders>
</httpprotocol>
Nguồn: http://www.kenhdotnet.com/
Read More »

Thứ Ba, 21 tháng 7, 2015

Sự khác nhau giữa click và on (click) jquery

The ".click" event you're using only looks for elements that were drawn during the initial page load. The "on" event looks for elements in the current state of the page.

$(document).on("click", ".remove_weight_button", function(){ //do something});
$(".remove_weight_button").click(function(){//do something});
Read More »

Thứ Hai, 20 tháng 7, 2015

How can make ajax return empty string

Khi dùng ajax gọi đến action trả về dữ liệu, nếu dữ liệu trả về là một chuỗi rỗng thì ajax sẽ nhảy đến error mà không nhảy vào success (mặc dù ko có lỗi gì trong quá trình thực thi). Điều này là bởi vì:
- ajax trông đợi dữ liệu trả về là JSON hay JSONP
- trước jquery 1.9 thì chuỗi rỗng được coi là hợp lệ nhưng từ jquery 1.9 trở đi thì chuỗi rỗng được coi là không hợp lệ.
Vì vậy nếu muốn ajax nhảy đến success thì thay vì trả về chuỗi rỗng, hãy trả về chuỗi "null".


Read More »

Thứ Hai, 13 tháng 7, 2015

One way to excute a function javascript after another function finish

If you have two function javascript (or more) named Fn1 and Fn2, and you want to excute Fn2 when Fn1 finish. This is the one way to do it.

function F1(){
      //do somthing you want
      return true;
}

function F2(){
     //do something you want
}

And then excute in your script. Example:

<script>
      $(document).ready(function(){
            if(Fn1() == true){ //this line guarantee Fn1 function finish and then Fn2 function execute
                  Fn2();
            }
      });
</script>
Read More »

Thứ Năm, 9 tháng 7, 2015

Trích từ 17 lời khuyên của Lý Gia Thành cho phụ nữ

1. Hãy nghĩ ra cách KIẾM TIỀN như thế nào chứ không phải TIẾT KIỆM TIỀN như thế nào.
2. Có BUỒN CHÁN đến mấy cũng không lớn tiếng kêu than, phải giữ được sự BÌNH TĨNH.
3. Khi thích 1 thứ gì đó, hãy TỰ NỖ LỰC kiếm tiền mà mua

4. Nói ít làm nhiều, nếu có thể thì ĐỪNG NGỒI, vận động thích hợp hơn!
6. Nếu không thích công việc hiện tại hãy THAY ĐỔI nó, còn không hãy im lặng mà làm, đừng phàn nàn.
7. Khi hiểu rõ 1 vấn đề, hãy mạnh dạn TỪ BỎ.

8. Có thể không đồng thuận, nhưng cần có sự TÔN TRỌNG
9. Khi chưa đưa ra được QUYẾT ĐỊNH, hãy để thời gian giúp bạn, nếu không có cách nào quyết định, hãy làm rồi mới nói, bằng lòng với sai lầm, không được oán hận.

13. Không nên giữ THÙ OÁN, nếu có thể không gây tổn thương cho người khác thì đừng gây, không ai ở với ai cả cuộc đời, 1 số việc không nên giữ trong lòng.
15. Không quá ĐỀ CAO khả năng của mình trước tập thể, bởi khi rời xa, bạn sẽ phát hiện ra rằng, không có bạn mặt trời vẫn chiếu soi bình thường.
16. Sự việc trong QUÁ KHỨ hãy cho nó trôi qua, nhất định phải BỎ QUA.
17. Cho dù mất đi tất cả cũng không được để mất đi NỤ CƯỜI. Tâm thái quyết định tất cả.
Read More »

Thứ Tư, 8 tháng 7, 2015

Scroll elements in div horizontally

This is the way which show how to scroll elements in div horizontally. The image bellow is the result:

1. Html:

<html>
<head>
</head>
<body>
<div id="divScroll">
<div class="divLightBox">
<img src="/images/img1.jpg" title="demo scroll"/>
</div>
<div class="divLightBox">
<img src="/images/img2.jpg" title="demo scroll"/>
</div>
<div class="divLightBox">
<img src="/images/img3.jpg" title="demo scroll"/>
</div>
<div class="divLightBox">
<img src="/images/img4.jpg" title="demo scroll"/>
</div>
<div class="divLightBox">
<img src="/images/img5.jpg" title="demo scroll"/>
</div>
<div class="divLightBox">
<img src="/images/img6.jpg" title="demo scroll"/>
</div>
<div class="divLightBox">
<img src="/images/img7.jpg" title="demo scroll"/>
</div>
<div class="divLightBox">
<img src="/images/img8.jpg" title="demo scroll"/>
</div>
<div class="divLightBox">
<img src="/images/img9.jpg" title="demo scroll"/>
</div>
<div class="divLightBox">
<img src="/images/img10.jpg" title="demo scroll"/>
</div>
</div>
</body>
</html>

2. CSS:
<style>
    #divScroll {
        width: 500px;
        height: 190px;
        overflow-y: hidden;
        overflow-x: scroll;
        position: relative;
    }
    .divLightBox {
        width: 170px;
        padding-right: 10px;
        position: absolute;
        top:0px;
    }
    .divLightBox img{
        width: 95%;
        height: 100%;
    }
</style>
3. Javascript:
<script>
    $(document).ready(function () {
        var w = $(".divLightBox").width(); --get width a divLightBox element
        var num = $(".divLightBox").length; --get number of element
        var count = 1;
        if (num != undefined && num > 1) {
            for (i = 1; i < num; i++) {
                $(".divLightBox").eq(i).css('left', w * i); --add css left to each element
            }
        }
    });

</script>
Read More »

Thứ Ba, 7 tháng 7, 2015

C# – Tìm hiểu về Lambda Expression (Biểu thức Lambda)

C# – Tìm hiểu về Lambda Expression (Biểu thức Lambda)

Có thể nói so với anonymous method, lambda expression được coi là một sự cái tiến đáng giá từ phiên bản C# 2.0 lên C# 3.0. Khi dùng anonymous method, bạn có thể tạo các hàm in-line nhằm hạn chế việc khai báo các hàm riêng lẻ không cần thiết, giúp mã lệnh ngắn gọn hơn. Nay với lambda expression, bạn có thể viết ngắn gọn và dễ dàng hơn nhờ việc cung cấp toán tử và cú pháp mới, đồng thời thể hiện sự “thông minh” của compiler bằng cách tự nhận diện kiểu của dữ liệu. Ngoài ra, đây còn là kĩ thuật để tạo ra các kiểu expression tree mà ta sẽ bàn tới khi có dịp.

1. Giới thiệu

Nếu chưa có khái niệm về gì về anonymous method, bạn có thể đọc bài hướng dẫn của tôitại đây, việc này sẽ giúp bạn tiếp cận dễ dàng hơn những vấn đề sẽ được trình bày trong bài này. Ta có thể hình dung sự cải tiến kĩ thuật từ delegate đến lambda expression theo 3 bước:
–          Delegate
–          Anonymous method
–          Lambda expression
Vì thế hãy chuẩn bị những kiến thức nền tảng trước khi tiếp tục

2. Toán tử Lambda:

Ta sẽ lấy một ví dụ tương tự trong phần bài anonymous method trước để bắt đầu. Bạn có một mảng các số nguyên kiểu int sau:
1
int[] numbers = { 10, 4, 3, 2, 8, 6, 5, 7, 9, 1 };
Ví dụ 1:
Bây giờ ta sẽ dùng anonymous method để in các phần tử trong mảng trên ra. Ta dùng phương thức tĩnh Array.ForEeach<T>(T[] array, Action<T> action), ở đây có thể bỏ đi phần định kiểu T. Compiler sẽ tự động hiểu và xác định kiểu dựa vào kiểu của tham số bạn truyền vào. Cụ thể ta viết như sau:
C# 2.0:
1
2
3
Array.ForEach(numbers, delegate(int x){
Console.WriteLine(x);
});
Trong C# 3.0 ta có thể dùng cú pháp ngắn gọn hơn nữa để thực hiện điều này với cách hoạt động tương tự như với anonymous method. Ta viết lại đoạn mã trên như sau:
C# 3.0:
Array.ForEach(numbers, (int x) => { Console.WriteLine(x); });
Nếu chỉ có một lệnh cần thực thi ta có thể bỏ cặp dấu ngoặc nhọn đi “{}”, và trong hầu hết trường hợp, compiler có thể đoán ra được kiểu dữ liệu của biến nên trong trường hợp này ta rút gọn lại như sau:
Array.ForEach(numbers, (x) => Console.WriteLine(x) );
Nếu chỉ có một tham số bạn có thể bỏ cặp dấu ngoặc đơn đi:
Array.ForEach(numbers, x => Console.WriteLine(x) );
Rõ ràng câu lệnh trên được đơn giản hóa khá nhiều so với ban đầu. Bạn có thể thấy điểm khác biệt là phần tham số và lệnh thực thi được ngăn cách với nhau bởi kí hiệu =>. Kí hiệu => này được gọi là toán tử lambda. Ta có dạng thức cơ bản của lambda expression như sau:
(parameter-list) =>  expression
Nếu không có tham số thì cú pháp sẽ như sau:
() => expression
Bây giờ ta thử làm một vài ví dụ đơn giản nữa để giúp bạn làm quen với kĩ thuật này. Mỗi ví dụ sẽ được viết với một phiên bản dùng anonymous method và sau đó là phiên bản dùng lambda expression để bạn dễ so sánh.
Ví dụ 2:
Ta sẽ sắp xếp mảng numbers trên theo thứ tự giảm dần. Ta sẽ sắp xếp bằng phương thứcArray.Sort<T>(T[] array, Comparision<T> comparision).
Delegate Comparision<T> yêu cầu 2 tham số và trả về kiểu số tương tự như phương thức CompareTo() dùng để so sánh hai đối tượng (bạn có thể dùng phép trừ ‘-‘ để thay thế, để tường minh hơn nên tôi dùng CompareTo() để so sánh).
Ta có hai phiên bản để thực hiện yêu cầu này:
– Anonymous method:
Array.Sort(numbers, delegate(int x, int y)
{
return y.CompareTo(x);
});
-Lambda expression:
Array.Sort(numbers, (x,y) => y.CompareTo(x));
Ví dụ này tương tự như ví dụ đầu tiên trong bài, ngoại trừ việc nó phải return về một giá trị để so sánh. Như bạn thấy, lambda expression không cần dùng bất kì kí hiệu hay từ khóa gì để cho thấy rằng nó trả về một giá trị. Ta chỉ có thể nhận biết điều này dựa vào kết quả mà các biểu thức phía sau toán tử => trả về. Theo một cách hiểu khác, lambda expression luôn ngầm định trả về một giá trị như là void, int,…
Bạn có thể chỉ rõ việc trả về của các biểu thức sau toán tử => với từ khóa return, tuy nhiên nhớ dùng cặp ngoặc ‘{}’ để bao chúng lại như trong anonymous method.
Ví dụ 3:
Vấn sử dụng các phương thức tĩnh trong lớp Array, ta sẽ kiểm tra xem các phần tử trong mảng numbers có tuân theo một quy luật nào đó không bằng cách sử dụng phương thứcArray.TrueForAll<T>(T[] array, Predicate<T> match). Phương thức này sẽ kiểm tra tất cả các phần tử dựa vào quy tắc của delegate Predicate mà ta truyền vào. Nếu tất cả các phần tử trong mảng đều khớp thì sẽ trả về true, ngược lại sẽ trả về false nếu có ít nhất một phần tử không khớp. Ta có hai phiên bản sau:
– Anonymous method:
bool b=Array.TrueForAll(numbers, delegate(int x){
return x<11;
});
-Lambda expression:
bool b = Array.TrueForAll(numbers, x => x < 11);
Quy tắc so sánh ta dùng ở đây là mỗi phần tử phải bé hơn 11. Dĩ nhiên kết quả của phương thức TrueForAll() sẽ luôn trả về true vì như bạn thấy các phần tử của mảng numbers chỉ có 10 là lớn nhất. Bạn có thể in biến b ra để xác thực kết quả này.

3. Delegate Func<…>:

Trong phiên bản C# 3.0, đi kèm với việc ra đời của lambda expression, Microsoft cung cấp cho ta một kiểu delegate mới linh hoạt và tiện dụng hơn, tên của kiểu delegate này là Func.
Func cho phép khai báo và tạo ra các dạng delegate với số lượng tham số và kiểu trả về khác nhau, tương tự như khi bạn tạo ra một phương thức.
Func được dùng chủ yếu để tạo và lưu trữ một anonymous method ngắn gọn bằng lambda expression và được sử dụng như những phương thức thông thường. Cú pháp để sử dụng Func là viết các kiểu của tham số và giá trị trả về vào cặp ngoặc ‘<>’, theo sau từ khóa Func.
Func<T,T,..,TResult>
Ở đây T là các kiểu của tham số cần truyền vào và TResult là kiểu của giá trị trả về. Chú ý là Func yêu cầu ít nhất một tham sô trong cặp ‘<>’, tức là phải có kiểu trả về. Bạn không để đặt void hay để một cặp ngoặc ‘<>’ rỗng khi dùng Func.
Một số ví dụ về khai báo Func:
+Yêu cầu một tham số kiểu string và trả về một giá trị int: lấy chiều dài của chuỗi.
Func<string, int> stringLength = s => s.Length;
Console.WriteLine(stringLength (“yinyang”));
+Yêu cầu 1 tham số float, 1 tham số và trả về kiểu float: tính tích của 2 số
Func<float, int, float> multiply = (x, y) => x * y;
Console.WriteLine(multiply (9f, 7));
+ Trả về max của 2 số:
Func<int, int, int> max = (x, y) => x>y?x:y;
Console.WriteLine(max(9, 7));
Như bạn thấy, nếu dùng anonymous method cho các ví dụ trên, vì là phương thức in-line nên bạn chỉ được gọi một lần duy nhất khi định nghĩa, muốn gọi ở nơi khác trong cùng một phương thức bạn phải định nghĩa lại. Nhưng ở đây Func cung cấp một cách thức để lưu trữ anonymous method cho phép bạn sử dụng nhiều lần mà không cần phải khai báo và định nghĩa phương thức bên ngoài, và tất nhiên là với cú pháp ngắn gọn hơn so với kiểu truyền thống.

4. Phần kết

Như vậy ta đã đi qua phần giới thiệu và cách sử dụng về lambda expression. Trong bài viết này, bạn đã biết được sự khác nhau giữa lambda expression với anonymous method và delegate, đồng thời thấy được sự tiện dụng của nó trong những ngữ cảnh cụ thể. Trong các bài viết tới tôi sẽ giới thiệu về expression tree để bạn nắm vững được những kĩ thuật mà công nghệ .Net đã và đang đem lại ra cho chúng ta.

Read More »