Cải thiện tốc độ load trang với jQuery

Đây là một số tiêu chuẩn chung giúp bạn viết code tốt hơn với jQuery. Các tiêu chuẩn này không bao gồm các tiêu chuẩn JavaScript. Xem qua jQuery Cheatsheet để tham khảo về API.

jquery

Tải jQuery

1. Luôn cố gắng sử dụng một CDN để chứa jQuery trên trang của bạn. Lợi ích của CDN

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/jquery-2.1.1.min.js" type="text/javascript"><\/script>')</script>

Click vào đây để xem danh sách các CDN phổ biến trong jQuery.
2. Thực hiện một dự phòng cho thư viện local host của bạn cùng version như trên. Xem thêm
3. Sử dụng protocol-relative/protocol-independent URL (bỏ đi http: hoặc https:) như trên.
4. Nếu có thể, hãy giữ tất cả include JavaScript và jQuery của bạn ở dưới cùng của trang. Xem thêm và ví dụ ở HTML5 Boilerplate.
5. Sử dụng version nào?

– KHÔNG sử dụng jQuery version 2.x nếu bạn dùng Internet Explorer 6/7/8.
– Đối với các ứng dụng web, nếu bạn không gặp phải vấn đề về tương thích plugin thì nên sử dụng version jQuery mới nhất.
– Khi tải jQuery từ CDN, luôn phải xác định đầy đủ số version mà bạn muốn tải (Ví dụ: 1.11.0 khác với 1.11 hay 1).
– KHÔNG tải nhiều version jQuery.
– KHÔNG sử dụng jquery-latest.js từ jQuery CDN.

6. Nếu bạn đang sử dụng các thư viện khác như Prototype, MooTools, Zepto… mà có dùng ký tự $ thì cố gắng không dùng $ để gọi chức năng jQuery,  thay vào đó hãy sử dụng jQuery đơn giản. Bạn có thể trả về quyền kiểm soát của $ từ thư viện khác bằng cách gọi $.noConflict().
7. Để nâng cao tính năng phát hiện trình duyệt, hãy sử dụng Modernizr.

Biến trong jQuery

1. Tất cả các biến được dùng để lưu trữ/cache các đối tượng jQuery, tên biến nên bắt đầu bằng ký tự $.
2. Luôn cache selector jQuery của bạn trả về các đối tượng trong các biến để tái sử dụng.

var $myDiv = $("#myDiv");
$myDiv.click(function(){...});

3. Sử dụng camel case để đặt tên cho các biến.

Selector

1. Sử dụng selector ID bất cứ khi nào có thể, sẽ nhanh hơn vì chúng xử lý bằng cách sử dụng document.getElementById().
2. Khi dùng selector class, đừng sử dụng element type trong selector của bạn. So sánh hiệu suất

var $products = $("div.products"); // CHẬM
var $products = $(".products"); // NHANH

3. Sử dụng tìm kiếm với Id->Child lồng selector. Dùng .find() sẽ nhanh hơn vì lựa chọn đầu tiên sẽ được xử lý mà không cần thông qua công cụ selector Sizzle. Xem thêm

// DỞ, một truy vấn lồng nhau với công cụ selector Sizzle
var $productIds = $("#products div.id");

// TỐT, #products đã được chọn bằng document.getElementById() vì vậy chỉ cần dùng div.id để thông qua công cụ selector Sizzle
var $productIds = $("#products").find("div.id");

4. Cụ thể selector bên phải và ít cụ thể selector bên trái. Xem thêm

// Không tối ưu hóa
$("div.data .gonzalez");

// Tối ưu hóa
$(".data td.gonzalez");

5. Tránh dùng quá nhiều đặc tính. Xem thêm, so sánh hiệu suất

$(".data table.attendees td.gonzalez");

// Tốt hơn: bỏ phần giữa nếu có thể
$(".data td.gonzalez");

6. Cung cấp cho selector của bạn một ngữ cảnh.

// CHẬM HƠN vì nó duyệt qua toàn bộ DOM cho .class
$('.class');

// NHANH HƠN vì bây giờ nó chỉ xem xét trong class-container.
$('.class', '#class-container');

7. Tránh dùng các universal selector. Xem thêm

$('div.container > *'); // DỞ
$('div.container').children(); // TỐT HƠN

8. Tránh dùng các universal selector hàm ý vì khi bạn ra khỏi selector, universal selector vẫn mang hàm ý. Xem thêm

$('div.someclass :radio'); // DỞ
$('div.someclass input:radio'); // TỐT

9. Đừng dùng nhiều ID hoặc lồng nhiều ID khi lựa chọn một ID. Chỉ chọn ID để xử lý bằng cách sử dụng document.getElementById() nên không được kết hợp chúng với các selector khác.

$('#outer #inner'); // DỞ
$('div#inner'); // DỞ
$('.outer-container #inner'); // DỞ
$('#inner'); // TỐT, chỉ gọi document.getElementById()

Thao tác với DOM

1. Luôn detach element hiện có trước khi thao tác và attach lại sau khi thao tác xong. Xem thêm

var $myList = $("#list-container > ul").detach();
// ... nhiều thứ phức tạp trên $myList
$myList.appendTo("#list-container");

2. Sử dụng nối chuỗi hoặc array.join() trên .append(). Xem thêm
So sánh hiệu suất: http://jsperf.com/jquery-append-vs-string-concat

// DỞ
var $myList = $("#list");
for(var i = 0; i < 10000; i++)
{
     $myList.append("<li>"+i+"</li>");
}

// TỐT
var $myList = $("#list");
var list = "";
for(var i = 0; i < 10000; i++)
{
     list += "<li>"+i+"</li>";
}
$myList.html(list);

// THẬM CHÍ NHANH HƠN
var array = [];
for(var i = 0; i < 10000; i++)
{
     array[i] = "<li>"+i+"</li>";
}
$myList.html(array.join(''));

3. Đừng thao tác trên các element vắng mặt. Xem thêm

// DỞ: Code này chạy 3 function trước khi nhận ra là không có gì trong lựa chọn
$("#nosuchthing").slideUp();

// TỐT
var $mySelection = $("#nosuchthing");
if ($mySelection.length)
{
     $mySelection.slideUp();
}

Sự kiện

1. Chỉ sử dụng một trình xử lý document ready trên mỗi trang để dễ debug và theo dõi các luồng hành vi.
2. KHÔNG sử dụng các function ẩn danh để attach sự kiện vì các function ẩn danh rất khó debug, bảo trì, kiểm tra hoặc tái sử dụng. Xem thêm

$("#myLink").on("click", function(){...}); // DỞ

// TỐT
function myLinkClickHandler()
{...}
$("#myLink").on("click", myLinkClickHandler);

3. Trình xử lý sự kiện document ready không phải là một function ẩn danh.

$(function()
{ ... }); // DỞ: Bạn không bao giờ có thể sử dụng lại hoặc viết test cho function này

// TỐT
$(initPage); // hoặc $(document).ready(initPage);
function initPage()
{
     // Trang tải sự kiện, nơi bạn có thể khởi tạo giá trị và gọi các khởi tạo khác
}

4. Trình xử lý sự kiện document ready nên được include từ file bên ngoài và JavaScript inline có thể được dùng để gọi xử lý ready sau bất kỳ thiết lập ban đầu.

<script src="my-document-ready.js"></script>
<script>
     // Bất kỳ thiết lập biến toàn cục có thể cần đến
     $(document).ready(initPage); // hoặc $(initPage);
</script>

5. KHÔNG sử dụng đánh dấu hành vi trong HTML (JavaScript inline) vì chúng sẽ gây khó khăn khi debug. Luôn liên kết các sự kiện với jQuery cho phù hợp để dễ dàng attach và xóa sự kiện tự động.

<a id="myLink" href="#" onclick="myEventHandler();">my link</a> // <!-- DỞ -->
$("#myLink").on("click", myEventHandler); // TỐT

6. Khi có thể, hãy sử dụng custom namespace cho sự kiện để dễ dàng mở ra sự kiện chính xác bạn attach mà không làm ảnh hưởng đến các sự kiện khác liên kết với DOM element.

$("#myLink").on("click.mySpecialClick", myEventHandler); // TỐT
// dễ dàng mở sự kiện ra khi bạn click vào
$("#myLink").unbind("click.mySpecialClick");

7. Sử dụng sự kiện delegation khi bạn phải attach cùng một sự kiện cho nhiều element. Sự kiện delegation cho phép bạn attach một sự kiện listener đơn với một element cha mẹ, cho tất cả element con kết hợp với một selector dù là element con đó hiện đang tồn tại hay được thêm vào trong tương lai.

$("#list a").on("click", myClickHandler); // DỞ, attach một sự kiện vào tất cả các link dưới danh sách
$("#list").on("click", "a", myClickHandler); // TỐT, chỉ một trình xử lý sự kiện được attach từ cha

Ajax

1. Tránh sử dụng .getJson() hoặc .get(), chỉ sử dụng $.ajax() để lấy những gì nội bộ.
2. KHÔNG sử dụng request http trên các trang https. Nếu muốn dùng phải xóa bỏ các giao thức http/https khỏi URL.
3. KHÔNG đặt các thông số request trong URL mà gửi cho họ bằng cách sử dụng thiết lập đối tượng data.

// Khó đọc...
$.ajax({
     url: "something.php?param1=test1&param2=test2",
     ....
});

// Dễ đọc hơn...
$.ajax({
     url: "something.php",
     data: { param1: test1, param2: test2 }
});

4. Cố gắng cụ thể thiết lập dataType vì sẽ dễ dàng hơn nếu biết kiểu dữ liệu mà bạn đang làm việc. (xem ví dụ template Ajax bên dưới)
5. Sử dụng trình xử lý sự kiện Delegated để sự kiện gắn với nội dung được tải bằng cách sử dụng Ajax. Sự kiện Delegated có ưu điểm là có thể xử lý các sự kiện của các element con được thêm vào document ở thời gian sau đó (ví dụ Ajax). Xem thêm

$("#parent-container").on("click", "a", delegatedClickHandlerForAjax);

6. Sử dụng giao diện Promise: Xem các ví dụ

$.ajax({ ... }).then(successHandler, failureHandler);

// hoặc
var jqxhr = $.ajax({ ... });
jqxhr.done(successHandler);
jqxhr.fail(failureHandler);

7. Mẫu template Ajax: Xem thêm

var jqxhr = $.ajax({
     url: url,
     type: "GET", // mặc định là GET nhưng bạn có thể sử dụng các động từ khác tùy vào nhu cầu của bạn
     cache: true, // mặc định là true nhưng dùng false cho dataType 'script' và 'jsonp', do đó hãy thiết lập nó tùy vào nhu cầu
     data: {}, // thêm các thông số request trong đối tượng data
     dataType: "json", // cụ thể dataType để tham chiếu trong tương lai
     jsonp: "callback", // chỉ rõ tên của thông số callback API tương ứng được mong đợi cho request JSONP
     statusCode: // nếu bạn muốn xử lý các mã lỗi cụ thể, sử dụng các thiết lập mã trạng thái
     {
          404: handler404,
          500: handler500
     }
});
jqxhr.done(successHandler);
jqxhr.fail(failureHandler);

Hiệu ứng và hình động

1. Áp dụng phương pháp hạn chế và phù hợp để thực hiện các chức năng hình động.
2. KHÔNG NÊN làm các hiệu ứng hình ảnh động cho đến khi được yêu cầu bởi UX.

– Thử dùng show/hide đơn giản, toggle và chức năng slideUp/slideDown để chuyển đổi các element.
– Thử dùng các hình động định sẵn thời lượng như “chậm”, “nhanh” hoặc 400 (trung bình).

Plugin

1. Luôn chọn một plugin hỗ trợ tốt, có tài liệu hướng dẫn, test và hỗ trợ cộng đồng.
2. Kiểm tra khả năng tương thích của plugin với các version của jQuery mà bạn đang sử dụng.
3. Bất kỳ thành phần tái sử dụng thông thường nên được thực thi như một plugin jQuery. Click vào đây để xem code plugin jQuery Boilerplate.

Chuỗi

1. Sử dụng chuỗi thay thế cho biến cache và nhiều lời gọi selector.

$("#myDiv").addClass("error").show();

2. Khi các chuỗi có hơn 3 liên kết hoặc trở nên phức tạp vì sự kiện đưa ra, hãy sử dụng ngắt dòng phù hợp và thụt đầu dòng để đoạn code dễ đọc hơn.

$("#myLink")
     .addClass("bold")
     .on("click", myClickHandler)
     .on("mouseover", myMouseOverHandler)
     .show();

3. Đối với chuỗi dài, hãy cache đối tượng trung gian trong một biến.

Khác

1. Sử dụng object cho các thông số.

$myLink.attr("href", "#").attr("title", "my link").attr("rel", "external"); // DỞ, 3 cuộc gọi đến attr()
// TỐT, chỉ 1 cuộc gọi đến attr()
$myLink.attr({
     href: "#",
     title: "my link",
     rel: "external"
});

2. Đừng kết hợp CSS với jQuery.

$("#mydiv").css({'color':red, 'font-weight':'bold'}); // DỞ
.error { color: red; font-weight: bold; } // TỐT
$("#mydiv").addClass("error"); // TỐT

3. KHÔNG sử dụng các phương thức Deprecated. Hãy luôn để mắt tới các phương thức deprecated ở mỗi version mới và cố gắng tránh sử dụng chúng. Click vào đây để xem danh sách các phương thức deprecated.
4. Kết hợp jQuery với JavaScript tự nhiên khi cần. Xem sự khác biệt hiệu suất trong ví dụ dưới đây: http://jsperf.com/document-getelementbyid-vs-jquery/3

$("#myId"); // vẫn còn chút chậm hơn so với...
document.getElementById("myId");

Nguồn


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

×