2010-03-19 32 views
16

Tôi đang gặp sự cố với tốc độ tải bằng cách sử dụng nhiều liên kết jQuery trên vài nghìn yếu tố và đầu vào, có cách nào hiệu quả hơn để thực hiện việc này không?Hiệu suất liên kết jQuery

Trang web có khả năng chuyển đổi giữa các danh sách sản phẩm thông qua cuộc gọi ajax, trang không thể làm mới. Một số danh sách có 10 mục, một số 100, một số hơn 2000. Vấn đề tốc độ phát sinh khi tôi bắt đầu lật giữa các danh sách; mỗi lần danh sách mục 2000+ được tải hệ thống kéo trong khoảng 10 giây.

Trước khi tôi xây dựng lại danh sách, tôi sẽ đặt html của thành phần đích thành '' và hủy liên kết hai liên kết bên dưới. Tôi chắc chắn rằng nó có một cái gì đó để làm với tất cả các phụ huynh, tiếp theo, và các cuộc gọi con tôi đang làm trong callbacks. Bất kỳ sự giúp đỡ nào cũng được đánh giá cao.

vòng lặp 2500 lần

<ul> 
    <li><input type="text" class="product-code" /></li> 
    <li>PROD-CODE</li> 
    ... 
    <li>PRICE</li> 
</ul> 

cuối vòng lặp

$('li.product-code').bind('click', function(event){ 

    selector = '#p-'+ $(this).prev('li').children('input').attr('lm'); 

     $(selector).val(

      ($(selector).val() == '' ? 1 : (parseFloat($(selector).val()) + 1)) 

     ); 

    Remote.Cart.lastProduct = selector; 
    Remote.Cart.Products.Push( 

      Remote.Cart.customerKey, 
      { 
       code  : $(this).prev('li').children('input').attr('code'), 
       title  : $(this).next('li').html(), 
       quantity : $('#p-'+ $(this).prev('li').children('input').attr('lm')).val(), 
       price  : $(this).prev('li').children('input').attr('price'), 
       weight : $(this).prev('li').children('input').attr('weight'), 
       taxable : $(this).prev('li').children('input').attr('taxable'), 
       productId : $(this).prev('li').children('input').attr('productId'), 
       links  : $(this).prev('li').children('input').attr('productLinks') 
      }, 
      '#p-'+ $(this).prev('li').children('input').attr('lm'), 
      false, 
      (parseFloat($(selector).val()) - 1) 

    ); 

    return false; 

}); 

$('input.product-qty').bind('keyup', function(){ 

    Remote.Cart.lastProduct = '#p-'+ $(this).attr('lm'); 
    Remote.Cart.Products.Push( 

      Remote.Cart.customerKey, 
      { 
       code  : $(this).attr('code') , 
       title  : $(this).parent().next('li').next('li').html(), 
       quantity : $(this).val(), 
       price  : $(this).attr('price'), 
       weight : $(this).attr('weight'), 
       taxable : $(this).attr('taxable'), 
       productId : $(this).attr('productId'), 
       links  : $(this).attr('productLinks') 
      }, 
      '#p-'+ $(this).attr('lm'), 
      false, 
      previousValue 
    ); 
}); 

Trả lời

28

Bạn đang ràng buộc một handler 2500 lần, thay vì sử dụng chức năng của bạn, hoặc trực tiếp hoặc ủy thác như thế này:

$('li.product-code').live('click', function(event){ 
$('input.product-qty').live('keyup', function(){ 

.live() lắng nghe cho các nhấp chuột để bong bóng lên ở cấp DOM sau đó thực hiện sự kiện này với bối cảnh của nguồn nhấp chuột. Điều này có nghĩa là bạn có một trình xử lý sự kiện thay vì 2500 trong số đó, nghĩa là số nhiều hơn nhanh hơn và dễ dàng hơn trên trình duyệt.

Nếu bạn có một container rằng kết thúc tốt đẹp các nội dung thay thế mà không được thay thế (vẫn còn trên tất cả các cuộc gọi AJAX), bạn có thể làm cho nó địa phương nhiều như thế này:

$('#container').delegate('li.product-code', 'click', function(event){ 
$('#container').delegate('input.product-qty', 'keyup', function(){ 

Kết quả của việc này là sự kiện bong bóng ít lần hơn trước khi bị bắt.

Điểm đau khác có lẽ là tạo ra các phần tử, bạn có thể đăng mã đó không? Thường có các tối ưu hóa dễ dàng mang lại hiệu suất lớn ở đó.

Cập nhật

Tính đến jQuery 1.7, phương pháp .live() bị phản đối. Sử dụng .on() để đính kèm trình xử lý sự kiện. Người dùng các phiên bản cũ hơn của jQuery nên sử dụng .delegate() tùy chọn .live() - JQuery Docs

+0

Live là người chiến thắng! Giờ đây, tốc độ tạm dừng duy nhất của tôi là trình cắm không phải nhấp chuột mà tôi đã tải xuống. Nếu không có sự ràng buộc, việc tạo danh sách là ngay lập tức, bây giờ là khoảng một nửa giây. Với kịch bản không phải nhấp chuột nó treo, nhưng đó là do các ràng buộc tôi tưởng tượng. Cảm ơn rất nhiều! – clownshoes

+0

@chelfers - Bạn đang sử dụng plugin không nhấp chuột phải nào? Điều này cũng nên được khá dễ dàng để chuyển sang '.live()' và nhận được tất cả các mã của bạn ngay lập tức ... nếu bạn đã không làm điều này đã trả lời ở đây và tôi sẽ xem xét. –

+0

'delegate()' chắc chắn là con đường để đi. Nó tối ưu hơn nhiều so với các lựa chọn thay thế khi bạn có hàng nghìn yếu tố mà bạn muốn chụp. Chỉ báo trước là nó đòi hỏi jQuery 1.4. –

0

bạn nên nhìn vào jqrid hoặc flexigrid somthing mà sẽ cho phép bạn làm thats paging phân bổ cho các dữ liệu đến đầu ra cùng một lúc vì vậy tốt nhất để giới hạn số tiền bạn đưa ra ngay lập tức ngay cả khi những điều đó phù hợp với dự án của bạn, bạn phải tìm hiểu cách giới hạn dữ liệu là dòng dưới cùng

+0

Vấn đề là tôi cần tất cả dữ liệu trên một trang dựa trên yêu cầu của khách hàng. Tôi đã xây dựng một hệ thống phân trang, nhưng đã không sử dụng -_- – clownshoes

2

Liên kết sự kiện nhấp của bạn với toàn bộ tài liệu và trong hàm, hãy xem event.target để xem phần tử sản phẩm nào thực sự được nhấp vào. Bằng cách này, bạn chỉ cần thực hiện một liên kết đơn.

+0

Tốt hơn có thể không ràng buộc nó với toàn bộ tài liệu, nhưng với phần tử gốc ul hoặc ol. Tôi chắc chắn sẽ tránh để đi với sống, vì điều này có vấn đề hiệu suất là tốt, hoàn toàn có thể tránh được trong trường hợp này. – Jan

0

Trước tiên, hãy sử dụng trình tạo hồ sơ được xây dựng trong Firebug để kiểm tra phần lớn thời gian trì hoãn là; chỉ cần nhấn "hồ sơ", chạy hành động chậm của bạn, nhấn lại và xem cuộc gọi nào đắt nhất.

Thứ hai, nhìn vào xử lý sự kiện "sống": http://api.jquery.com/live/

Cách làm việc này là chỉ có một xử lý sự kiện, nhìn vào toàn bộ tài liệu, ủy thác cho sống xử lý sự kiện. Điều này hoạt động nhanh hơn nhiều khi bạn có vô số các phần tử, vì bạn không cần phải thêm một trình xử lý sự kiện cho từng phần tử cụ thể.

+0

Tôi đã xử lý trực tiếp. Profiler đã không giúp quá nhiều vì nó đã cho tôi một cảm giác chung về những gì tôi đã biết là bogging kịch bản xuống. – clownshoes

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