Эффективность привязки jQuery

У меня проблема с загрузкой с использованием нескольких привязок jQuery на пару тысяч элементов и входов, есть ли более эффективный способ сделать это?

У сайта есть возможность переключаться между списками продуктов с помощью ajax-вызовов, страница не может обновиться. В некоторых списках есть 10 предметов, около 100, некоторые из них за 2000 год. Вопрос о скорости возникает, когда я начинаю перелистывать списки; каждый раз, когда загружается список 2000+, система перетаскивается в течение примерно 10 секунд.

Прежде чем перестроить список, я устанавливаю целевой элемент html в '' и откручиваю два привязки ниже. Я уверен, что это имеет какое-то отношение ко всем родительским, следующим и дочерним вызовам, которые я выполняю в обратных вызовах. Любая помощь очень ценится.

цикл 2500 раз

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

конец цикла

$('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
    );
});

Ответ 1

Вы привязываете обработчик 2500 раз, вместо этого используйте свою функцию как в прямом эфире, так и в деле делегирования следующим образом:

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

.live() прослушивает щелчок на уровне DOM, а затем выполняет событие с контекстом источника щелчка. Это означает, что у вас есть один обработчик событий вместо 2500 из них, что означает намного быстрее и проще в браузере.

Если у вас есть контейнер, который обертывает заменяемый контент, который не заменен (остается во всех вызовах AJAX), вы можете сделать его более локальным следующим образом:

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

В результате этого события пузырьки событий меньше времени, прежде чем их поймать.

Еще одна болевая точка, вероятно, является созданием элементов, можете ли вы опубликовать этот код? Есть часто легкие оптимизации, которые приносят большой прирост производительности.

Обновление

Как и в jQuery 1.7, метод . live() устарел. Используйте . On() для присоединения обработчиков событий. Пользователи более старых версий jQuery должны использовать . Delegate() вместо .live() - JQuery Docs

Ответ 2

Привяжите событие click ко всему документу и внутри функции, посмотрите на event.target, чтобы увидеть, какой элемент продукта был нажат. Таким образом вам нужно выполнить только одно связывание.

Ответ 3

вы должны посмотреть jqrid или flexigrid somthing, что позволит вам делать подкачки, которые выделяют данные для вывода сразу, поэтому лучше всего ограничить, сколько вы выставляете сразу, даже если эти вещи подходят для вашего проекта, вы должны выяснить, как ограничить данные. нижняя строка

Ответ 4

Сначала используйте профилировщик, встроенный в Firebug, чтобы проверить, где находится большая часть задержки; просто нажмите "Профиль", запустите свое медленное действие, снова нажмите его и посмотрите, какие вызовы являются самыми дорогими.

Во-вторых, посмотрите на обработку "живого" события: http://api.jquery.com/live/

Как это работает, так это только один обработчик событий, просматривающий весь документ, делегирование живых обработчиков событий. Это работает намного быстрее, когда у вас есть множество элементов, потому что вам не нужно специально добавлять обработчик событий для каждого элемента.