Динамически изменяющиеся DOM-элементы по мере их прокрутки (производительность) - PullRequest
0 голосов
/ 26 января 2010

Я пытаюсь найти эффективный алгоритм для динамической загрузки фоновых изображений для группы <li>, и у меня есть некоторые проблемы с эффективностью. Мой текущий код выглядит так:

function elementInView($elem, vps, vpe) {
    var elempos = $elem.position(); 
    var pagestart = elempos.top + vps;
    var pageend = elempos.top + vps + $elem.height();
    var offset = 78 - Math.max(0,vps-pagestart) - Math.max(0,pageend-vpe);    
    // I want to update all items that are within 200 pixels of 
    // the current viewport
    return (vpe > 0 && offset > -200); 
}

$('#container').bind('scroll', function() {
    var $container = $(this);
    var vps = $container.scrollTop();
    var vpe = vps + $container.height();

    $('li:not(.bgset)', '#container').each(function() {
        var $this = $(this);
        if (elementInView($this,vps,vpe)) {
            $this.addClass('.bgset');
            // Set the background-image (doesn't affect performance noticably.)
        }
    });
});

Это занимает от 200 до 600 мс для списка из ~ 250 элементов и ~ 1500 мс для списка из ~ 1500 элементов, что делает его практически непригодным для использования.

Может кто-нибудь увидеть какие-либо проблемы с этим, или это в основном лучший способ сделать это? Я пытался получить ВСЕ <li> вместо $('li:not(.bgset)', но это не оказало никакого влияния вообще.

(Список содержит динамически сгенерированные фоновые изображения (которые не кэшируются и не меняются довольно сильно), а загрузка около 1500 из них действительно замедлила все, поэтому я попробовал этот подход)

РЕДАКТИРОВАТЬ: Забыл упомянуть, я думал о написании пользовательского селектора jQuery, который соответствует элементам, которые возвращают true для elementInView, это будет лучший подход?

Ответы [ 3 ]

1 голос
/ 26 января 2010

DOM работает медленно. Чтобы получить скорость, вам нужно использовать innerHTML.
Чтобы избежать манипуляций со строками, вы можете рассмотреть шаблонизатор JS, их много.
Мы создали шаблонизатор PURE , поскольку он крошечный и быстрый, он очень хорошо создавать страницы для мобильных телефонов.

Другим вариантом может быть рассмотрение проблемы в восходящем направлении. Вы уверены, что хотите предоставить своему пользователю список из сотен / тысяч товаров?

1 голос
/ 26 января 2010

Прежде всего, я рекомендую использовать профилировщик, чтобы получить реальные знания о том, что замедляет ваш код. В Firefox (Firebug), Chrome и Explorer есть профилировщики. Но я могу вспомнить некоторые проблемы прямо сейчас.

Я полагаю, что все LI являются дочерними элементами одного и того же UL, поэтому вы можете получить к ним доступ напрямую (firstChild / nextSibling) без вызова $(). Даже если имеется более одного UL, прямой доступ все же быстрее, чем $().

Другая возможная причина - сложный CSS. Я видел случай, когда из-за слишком большого числа операций с плавающей точкой и позиционирования single доступ к элементу offsetTop занял полсекунды. Это может повлиять на скорость .height() и .position().

Но сначала профиль!

1 голос
/ 26 января 2010

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

Задумывались ли вы, возможно, о спрайте на ходу с одновременным созданием соответствующего CSS. Таким образом, вы можете сократить HTTP-запросы и уменьшить количество перерисовок / перекомпоновок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...