2009-12-10 43 views
32

Tôi đang lặp lại rất thường xuyên trên các mảng đối tượng và đã sử dụng jQuery.each(). Tuy nhiên, tôi đang gặp vấn đề về tốc độ và bộ nhớ và một trong những phương pháp được gọi nhiều nhất theo profiler của tôi là jQuery.each(). Từ trên đường về hiệu suất của nó là gì? Tôi có nên chuyển sang vòng lặp đơn giản không? Tất nhiên tôi cũng đang sửa nhiều vấn đề trong mã của riêng tôi.Tôi có nên sử dụng jQuery.each() không?

+2

lưu ý về trình thu thập thông tin, rất nhiều hoạt động được xây dựng trong jQuery sử dụng $ .each() nội bộ để thực hiện công việc của họ. –

+0

là câu hỏi của bạn về jQuery.each() hoặc jQuery(). Each()? .. biểu mẫu đầu tiên (những gì bạn hỏi) về - số tiền cho một vòng lặp đơn giản. –

+0

Trước đây. Tốt để biết. – pr1001

Trả lời

14

Mã nguồn của jQuery từng là như sau (Cảm ơn bạn John Resig và MIT License):

each: function(object, callback, args) { 
    var name, i = 0, length = object.length; 

    if (args) { 
     if (length === undefined) { 
      for (name in object) 
       if (callback.apply(object[ name ], args) === false) 
        break; 
     } else 
      for (; i < length;) 
       if (callback.apply(object[ i++ ], args) === false) 
        break; 

    // A special, fast, case for the most common use of each 
    } else { 
     if (length === undefined) { 
      for (name in object) 
       if (callback.call(object[ name ], name, object[ name ]) === false) 
        break; 
     } else 
      for (var value = object[0]; 
       i < length && callback.call(value, i, value) !== false; value = object[++i]){} 
    } 

    return object; 
} 

Như bạn có thể theo dõi và thấy, trong nhiều trường hợp nó được sử dụng một cơ sở cho vòng lặp nơi mà chi phí duy nhất thực sự chỉ là chính cuộc gọi lại. Không nên tạo sự khác biệt về hiệu suất.

CHỈNH SỬA: Điều này xảy ra với việc nhận ra rằng phí trên bộ chọn đã xảy ra và bạn được cung cấp một dải dân cư object.

+4

Bạn đã sử dụng IE6 chưa? – ChaosPandion

+0

Tất nhiên. Và giống như hầu hết chúng ta hối hận như vậy. Nhưng điểm của bạn đặc biệt là gì? Quan điểm của tôi là trái tim của "mỗi" chỉ là một vòng lặp for. Tôi rời khỏi chi phí bạn nhận được từ instantiating một đối tượng jQuery và chọn các yếu tố dom một mình. –

+4

Điều tôi đang nói là đừng đánh giá thấp chi phí của các cuộc gọi hàm. – ChaosPandion

6

Một cách để đảm bảo bạn đang tận dụng tối đa jquery là lưu trữ mảng kết quả được trả về trong biến thay vì duyệt lại DOM mọi lúc bạn cần để có được thứ gì đó.

Ví dụ về những gì không nên làm:

$('.myLinks').each(function(){ 
    // your code here 
}); 
$('.myLinks').each(function(){ 
    // some more code here 
}); 

Better thực hành:

var myLinks = $('.myLinks'); 
myLinks.each(function(){ 
    // your code here 
}); 
myLinks.each(function(){ 
    // some more code here 
}); 
+17

Thực hành tốt hơn: làm mọi thứ trong một vòng lặp. – ChaosPandion

+0

Chắc chắn cả hai ví dụ đều giống nhau nếu chạy một lần? Trước khi jQuery lặp lại thông qua đối tượng, nó thiết lập một biến, giống như bạn làm trong ví dụ thứ hai của bạn. Nếu bạn phải chạy qua câu lệnh '.each' nhiều lần, thì có thể bộ nhớ đệm biến sẽ giúp ích. –

5

Phương pháp này sẽ cho bạn một sự cải thiện đáng kể tốc độ.

var elements = $('.myLinks').get(), element = null; 
for (var i = 0, length = elements.length; i < length; i++) { 
    element = elements[i]; 
    element.title = "My New Title!"; 
    element.style.color = "red"; 
} 

Caching cũng sẽ cải thiện hiệu suất.

function MyLinkCache() { 
    var internalCache = $('.myLinks').get(); 

    this.getCache = function() { 
     return internalCache; 
    } 

    this.rebuild = function() { 
     internalCache = $('.myLinks').get(); 
    } 
} 

Trong sử dụng:

var myLinks = new MyLinkCache(); 

function addMyLink() { 
    // Add a new link. 
    myLinks.rebuild(); 
} 

function processMyLinks() { 
    var elements = myLinks.getCache(), element = null; 
    for (var i = 0, length = elements.length; i < length; i++) { 
     element = elements[i]; 
     element.title = "My New Title!"; 
     element.style.color = "red"; 
    } 
} 
26

This article (# 3) chạy một số xét nghiệm hiệu suất và phát hiện ra rằng jQuery .each chức năng là khoảng 10x chậm như javascript bản địa cho vòng lặp.

Từ 10 Ways to Instantly Increase Your jQuery Performance - 3. Use For Instead of Each
Sử dụng Firebug, nó có thể đo thời gian mỗi hai chức năng cần thiết để chạy.

var array = new Array(); 
for (var i=0; i<10000; i++) { 
    array[i] = 0; 
} 

console.time('native'); 
var l = array.length; 
for (var i=0;i<l; i++) { 
    array[i] = i; 
} 
console.timeEnd('native'); 

console.time('jquery'); 
$.each (array, function (i) { 
    array[i] = i; 
}); 
console.timeEnd('jquery'); 

Kết quả trên là 2ms cho mã nguồn gốc, và 26ms cho "mỗi" phương pháp của jQuery. Với điều kiện tôi đã thử nghiệm nó trên máy tính cục bộ của mình và chúng không thực sự làm bất cứ điều gì (chỉ là một hoạt động điền mảng đơn giản), mỗi hàm của jQuery mất hơn 10 lần miễn là JS "for" loop. Điều này chắc chắn sẽ tăng khi xử lý các công cụ phức tạp hơn, như thiết lập thuộc tính CSS hoặc các thao tác thao tác DOM khác.

+2

Cảm ơn, đó là một bài viết hay. – pr1001

+0

điều này sẽ là câu trả lời. các trang động của tôi chỉ bị thay đổi bởi vì 'mỗi '. Ngoài ra, liên kết cung cấp lời khuyên tuyệt vời. Chỉ cần chú ý tôi chỉ làm khoảng 40% –

+1

Trong khi câu trả lời này đã hơn một tuổi và liên kết sẽ hữu ích hơn nếu bạn đăng các phần thiết yếu của câu trả lời ở đây, trên trang web này hoặc rủi ro đăng của bạn bị xóa [ Xem Câu hỏi thường gặp trong đó đề cập đến câu trả lời là 'hầu như không phải là liên kết'.] (Http://stackoverflow.com/faq#deletion) Bạn vẫn có thể bao gồm liên kết nếu muốn, nhưng chỉ là 'tham chiếu'. Câu trả lời nên tự đứng lên mà không cần liên kết. – Taryn

6

Sử dụng chức năng gốc thường sẽ là nhanh hơn hơn là trừu tượng, chẳng hạn như phương thức JQuery.each(). Tuy nhiên, phương thức JQuery.each() là dễ dàng hơn để sử dụng và yêu cầu ít mã hóa hơn về phía bạn.

Thật ra, không phải ai là lựa chọn đúng hay sai mà không có bất kỳ ngữ cảnh nào. Tôi là người phản đối rằng chúng ta nên viết mã dễ dàng hơn trước, giả sử nó tốt/legilble/clean code. Nếu bạn đi vào một tình huống, chẳng hạn như một trong những bạn đang mô tả, nơi có một sự chậm trễ đáng chú ý, hơn là thời gian để tìm ra nơi nút cổ chai của bạn và viết mã nhanh hơn.

Thay thế phương thức JQuery.each() trong các trường hợp này có thể trợ giúp, tuy nhiên, không thấy mã của bạn, có thể bạn không bị tắc nghẽn với phương pháp JQuery.

Các vấn đề liên quan