Селекторы Jquery по классу CSS в IE действительно медленные - обходные пути? - PullRequest
3 голосов
/ 17 июня 2010

У меня есть веб-приложение, в котором у меня есть несколько элементов с class="classA". Я хочу выбрать и применить функцию ко всем из них. Я делаю очевидную вещь, которая $(".classA").each(function () { ... }). Это прекрасно работает в Chrome / Safari / Firefox, но очень медленно в IE. Оказывается, у IE серьезные проблемы с производительностью при выборе вещей по классу CSS в jQuery.

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

- РЕДАКТИРОВАТЬ -

Ниже приведен код моего теста.

  • test1 использует document.getElementById("id") и работает очень быстро.

  • test2 использует $("#id") и работает довольно медленно.

  • test3 использует $(".class") и еще медленнее.

Насколько я могу судить, в IE8 нет встроенной реализации document.getElementsByClassName - я получаю сообщение об ошибке при попытке его использовать.

<html>

    <head>
        <script type="text/javascript" src="jquery-1.4.2.js"></script>


        <script type="text/javascript">


            function test1 ()
            {
                var start = (new Date).getTime();
                for (var i = 0; i < 10000; i++)
                {
                    document.getElementById("test1");
                }
                var elapsed = (new Date).getTime() - start;
                alert("test1 elapsed: " + elapsed);
            }

            function test2 ()
            {
                var start = (new Date).getTime();
                for (var i = 0; i < 10000; i++)
                {
                    var x = $("#test2");
                }
                var elapsed = (new Date).getTime() - start;
                alert("test2 elapsed: " + elapsed);
            }

            function test3 ()
            {
                var start = (new Date).getTime();
                for (var i = 0; i < 10000; i++)
                {
                    $(".test3");
                }
                var elapsed = (new Date).getTime() - start;
                alert("test3 elapsed: " + elapsed);
            }

        </script>

    </head>

    <body>

        <div id="test1">test1</div>

        <div id="test2">test2</div>

        <div id="test3" class="test3">test3 1</div>
        <div id="test3" class="test3">test3 2</div>
        <div id="test3" class="test3">test3 3</div>
        <div id="test3" class="test3">test3 4</div>

        <input type="button" onclick="test1();" value="test1" />
        <input type="button" onclick="test2();" value="test2" />
        <input type="button" onclick="test3();" value="test3" />

    </body>

</html>

Ответы [ 3 ]

18 голосов
/ 17 июня 2010

Взгляните на jQuery: анализ производительности селекторов :

Тест 2 - Поиск элемента по классу

Хотя классы CSS предназначены дляповторно использованный среди элементов, вы можете создать некоторые элементы с уникальным именем класса просто для идентификации и извлечения их через javascript.Это именно то, что мы тестируем во втором тесте, отсекая элемент, класс которого "p-4781".У нас есть четыре варианта:

A - Использование селектора класса

$('.p-4781').html()

B - Использование селектора класса + тег

$('p.p-4781').html()

C - Использование поиска атрибутов + тега

$('p[class="p-4781"]').html()

D - Использование поиска по тегам + фильтр

$('p').filter('.p-4781').html()

После первого запуска этого теста в разных браузерах я получил:

   Firefox Opera    IE6     IE7    Safari
A     2891   641   1718     631      329
B      453    78    313     180       78
C      422   109    578     201      187
D      203   266    375     210       94

Таблица выше показывает случай B как самый быстрый селектор для большинства браузеров (кроме Firefox).Легко понять, почему случай A неэффективен, поскольку код должен перебирать все элементы дерева DOM.Случаи C и D не так уж и плохи, но я бы сказал, что для этой цели предпочтительным должен быть случай B.

Так что используйте имя тега плюс имя класса.Это намного быстрее в старых браузерах.

3 голосов
/ 17 июня 2010

Вы можете попробовать разные вещи, но IE оптимизирован для выборки элементов по идентификатору, ничего больше (он помещает идентификаторы элементов в хеш-таблицу под крышками).

Если вы генерируете свою страницу с помощью какой-либо серверной технологии, вы можете определить список элементов, а затем вывести массив JavaScript идентификаторов этих элементов, а затем, когда страница загрузится, вы можете просмотреть этот массив и собрать ваши элементы по ID.

Это подход, который мы с успехом использовали для приложений ASP.NET, хотя, возможно, вы занимаетесь чем-то другим. Я бы, по крайней мере, исследовал варианты, описанные jmbledsoe, они могут немного помочь, но я сомневаюсь, что вы получите производительность, на которую надеетесь.

1 голос
/ 17 июня 2010

Я не знаю, поможет ли это, но если все ваши элементы имеют одинаковый тег (например, DIV), вы можете использовать селектор типа «DIV.classA». JQuery может быть в состоянии оптимизировать это с помощью вызова getElementsByTagName.

Если вы можете указать родительский элемент, например, $ ('DIV.classA', someParent), который ограничивает область поиска, что может повысить производительность.

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