Khanh Hoang - Kenn
Kenn is a user experience designer and front end developer who enjoys creating beautiful and usable web and mobile experiences.
Đã là dân làm web thì có lẽ jQuery không còn là điều xa lạ hay mới mẻ nữa. jQuery là một bộ thư viện rất hữu dụng cho việc phát triển ứng dụng web khi muốn viết javascript. Xài jQuery không khó, thậm chí rất đơn giản. Nhưng xài như thế nào để tối ưu và xài như thế nào để cải thiện tốt về tốc độ có lẽ không phải ai cũng biết. Bài viết sau của mình sẽ tóm tắt lại các kiến thức mà mình thu nhặt được giúp cải thiện tốc độ jQuery.
Trong jQuery, truy xuất đối tượng (selector) thông qua thuộc tính ID là nhanh nhất. Vì $("#id") sẽ ánh xạ trực tiếp tới hàm getElementById("id") vốn là hàm built-in của javascript. Mà đã là hàm built-in thì luôn luôn nhanh hơn hàm do người dùng định nghĩa.
Nếu muốn lấy 1 list các đối tượng, chúng ta cố gắng dùng 1 đối tượng cha có ID gần nhất, sau đó chúng ta mới lấy tập hợp con của nó. Ví dụ như chúng ta có đoạn html như bên dưới.
<ul id="den_giao_thong"> <li> <input type="radio" class="tat" name="den" value="do" /> Đỏ </li> <li> <input type="radio" class="tat" name="den" value="vang" /> Vàng </li> <li> <input type="radio" class="bat" name="den" value="xanh" /> Xanh </li> </ul>
Để lấy danh sách các <input> chúng ta có thể dùng cách sau:
var inputs = $("#den_giao_thong input");
Mức độ nhanh thứ 2 trong jQuery là lấy đối tượng theo tagName. Lý do cũng tương tự cái bên trên, đó là do nó ánh xạ trực tiếp vào hàm built-in getElementsByTagName của Javascript. Cũng với ví dụ trên, nếu chúng ta muốn lấy cái đèn nào được bật thì chúng ta sử dụng cách sau:
var denBat = $("#den_giao_thong input.bat");
Chúng ta nên sử dụng một biến để lưu trữ đối tượng jQuery nếu như đối tượng này phải thực hiện nhiều lệnh. Ví dụ chúng ta thường hay viết như sau:
$('#traffic_light input.on').click(function(){...}); $('#traffic_light input.on').css('border', '3px dashed yellow'); $('#traffic_light input.on').css('background-color', 'orange'); $('#traffic_light input.on').fadeIn('slow');
Thì chúng ta nên viết lại như sau:
var obj = $('#traffic_light input.on'); obj.click(function(){...}); obj.css('border', '3px dashed yellow'); obj.css('background-color', 'orange'); obj.fadeIn('slow');
Tuy nhiên, nếu chúng ta dùng đối tượng jQuery chỉ 1 lần duy nhất thì không nên cache đối tượng lại (lưu vào 1 biến như bên trên) vì sẽ bị tác dụng phụ đó ^^
Cũng với ví dụ ở mục 3, chúng ta có thể tối ưu thêm một bước là tận dụng sức mạnh chuỗi hàm mà jQuery đã cung cấp. Chúng ta nên viết lại như sau:
$('#traffic_light input.on').click(function(){...}) .css({ 'border': '3px dashed yellow', 'background-color': 'orange' }) .fadeIn('slow');
Hôm nay mình chia sẻ tiếp phần 2 cho loạt bài làm sao sử dụng jQuery một cách tối ưu, nhanh hơn và tiện dụng hơn. Ở đây không phải là những thứ mình phát minh ra, mà cũng tìm kiếm trên google rồi sau đó tập hợp lại để chia sẻ tới mọi người, nên có thể không thể chia sẻ nguồn cho mọi người được ^^.
Đây là điều dĩ nhiên không chỉ dành cho jQuery mà dành cho tất cả mọi ngôn ngữ lập trình. Nếu có một cách khác thay thế tốt hơn, chúng ta nên dùng vì việc gọi hàm trong vòng lặp sẽ làm chậm rất đáng kể và tốn tài nguyên khá nhiều. Ví dụ ta có đoạn code như bên dưới:
var items = [....]; // Giả sử có 100 phần tử var list = $('#list'); // Giả sử là đối tượng <select> for(var i = 0; i < items.length; i++) { list.append($('<option />').attr('value', items[i]).html(i)); }
Ở đoạn code này, chúng ta gọi tới 3 hàm trong vòng lặp. điều này hạn chế rất nhiều về mặt tốc độ. Chúng ta có thể thay thế bằng đoạn code sau:
var items = [....]; // Giả sử có 100 phần tử var list = $('#list'); // Giả sử là đối tượng <select> var str = ''; for(var i = 0; i < items.length; i++) { str += '<option value="'+i+'">'+items[i]+'</option>'; } list.html(str);
Đoạn code trên, chúng ta có thể cải tiến thêm tí nữa để tăng tốc nhanh hơn. Nhưng nếu số lượng phấn tử không quá lớn thì tốc độ giữa tip 5 và tip 6 không cách xa nhau bao nhiêu. (Tính bằng ms nên cũng không có gì đáng ngại lắm ^^)
var items = [....]; // Giả sử có 1000 phần tử var list = $('#list'); // Giả sử là đối tượng <select> var temp = []; for(var i = 0; i < items.length; i++) { temp[i] = '<option value="'+i+'">'+items[i]+'</option>'; } list.html(temp.join(''));
Trong jquery cung cấp cho chúng ta một helper $.each giúp chúng ta thực hiện vòng lặp. Helper này chậm hơn so với hàm for (hàm built-in của javascript) nhưng đây là trường hợp ngoại lệ mình khuyên các bạn nên dùng $.each thay vì dùng for. Chắc chắn các bạn sẽ có sự thắc mắc tại đây, chúng ta cùng xem sự so sánh bên dưới để hiểu rõ vì sao mình khuyên như vậy.
console.time('TestNative'); var length = myArray.length; for( i=0; i < length; i++){ myArray[i]; } console.timeEnd('TestNative'); console.time('TestjQuery'); jQuery.each(myArray, function(i, val) { val; }); console.timeEnd('TestjQuery');
Và dưới đây là kết quả test
FOR loop Array size Time ========== ====== 10,000 7ms 100,000 62ms 1,000,000 613ms jQuery .each() loop Array size Time ========== ====== 10,000 10ms 100,000 177ms 1,000,000 1100ms
Số lượng phần tử trong mảng lên tới 10.000 chỉ cách biệt nhau 3ms. Và mình chắc chắn một mảng thông thường của javascript khó có thể đạt ngưỡng 10.000 phần tử, nên sự chênh lệch này gần như không có. Vậy chúng ta cứ an tâm mà dùng $.each