Какой самый быстрый способ выбрать большое количество флажков и де / выбрать их? - PullRequest
5 голосов
/ 14 апреля 2009

Поскольку я использую jQuery 1.3+, все, кроме одного теста по времени, используют это. Другой - простой javascript, который я нашел еще в 2000 году. Я перестал идти по этому пути, так как для запуска теста требовалось около 150 секунд. Я прочитал довольно много веб-страниц по оптимизации jQuery, которые касаются выбора одного элемента. '#Id' - лучший вариант для использования этого, но теперь у меня есть проблема проверки всех флажков в одном столбце в довольно большой таблице, которая имеет несколько столбцов флажков .

Что я сделал, так это установил страницу, которая создает 20000 строк таблицы с двумя столбцами флажков. Цель состоит в том, чтобы проверить во втором столбце, сколько времени это заняло, а затем снять их и посмотреть, сколько времени это заняло. Очевидно, мы хотим самое низкое время. Я использую только IE6 и 7, и в моем случае все мои пользователи будут делать то же самое.

20000 строк вы говорите? Я тоже так сказал, но это будет производство (из моих рук), и уже слишком поздно что-либо менять. Я просто пытаюсь бросить град Мэри с 1 секундой, оставшейся на часах. Кроме того, я узнал, что input.chkbox не самый быстрый селектор (для IE7)! :)

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

Так что вам не нужно перепечатывать все дерьмо, которое я уже сделал, вот тестовые материалы, которые я придумал:

Обновлено утро 4/14, чтобы включать в себя дальнейшие испытания времени:

<form id="form1" runat="server">
<div>           
        <a href="#" id="one">input[id^='chkbox'][type='checkbox']</a><br />
        <a href="#" id="two">#myTable tr[id^='row'] input[id^='chkbox'][type='checkbox']</a><br />
        <a href="#" id="three">#myTable tr.myRow input[id^='chkbox'][type='checkbox']</a><br />
        <a href="#" id="four">tr.myRow input[id^='chkbox'][type='checkbox']</a><br />
        <a href="#" id="five">input[id^='chkbox']</a><br />
        <a href="#" id="six">.chkbox</a><br />
        <a href="#" id="seven">input.chkbox</a><br />
        <a href="#" id="eight">#myTable input.chkbox</a><br />

        <a href="#" id="nine">"input.chkbox", "tr"</a><br />
        <a href="#" id="nine1">"input.chkbox", "tr.myRow"</a><br />
        <a href="#" id="nine2">"input.chkbox", "#form1"</a><br />
        <a href="#" id="nine3">"input.chkbox", "#myTable"</a><br />

        <a href="#" id="ten">input[name=chkbox]</a><br />
        <a href="#" id="ten1">"input[name=chkbox]", "tr.myRow"</a><br />
        <a href="#" id="ten2">"input[name=chkbox]", "#form1"</a><br />
        <a href="#" id="ten3">"input[name=chkbox]", "#myTable"</a><br />

        <a href="#" id="ten4">"input[name=chkbox]", $("#form1")</a><br />
        <a href="#" id="ten5">"input[name=chkbox]", $("#myTable")</a><br />

        <a href="#" id="eleven">input[name='chkbox']:checkbox</a><br />
        <a href="#" id="twelve">:checkbox</a><br />
        <a href="#" id="twelve1">input:checkbox</a><br />
        <a href="#" id="thirteen">input[type=checkbox]</a><br />

        <div>
            <input type="text" id="goBox" /> <button id="go">Go!</button>
            <div id="goBoxTook"></div>
        </div>

        <table id="myTable">
            <tr id="headerRow"><th>Row #</th><th>Checkboxes o' fun!</th><th>Don't check these!</th></tr>
            <% for(int i = 0; i < 20000;i++) { %>
            <tr id="row<%= i %>" class="myRow">
                <td><%= i %> Row</td>
                <td>
                    <input type="checkbox" id="chkbox<%= i %>" name="chkbox" class="chkbox" />
                </td>
                <td>
                    <input type="checkbox" id="otherBox<%= i %>" name="otherBox" class="otherBox" />
                </td>
            </tr>
            <% } %>
        </table>
</div>
        <script type="text/javascript" src="<%= ResolveUrl("~/") %>Javascript/jquery.1.3.1.min.js"></script>
        <script type="text/javascript">

            $(function() {                  
                function run(selectorText, el) {                    
                    var start = new Date();                     
                    $(selectorText).attr("checked", true);                              
                    var end = new Date();
                    var timeElapsed = end-start;
                    $(el).after("<br />Checking Took " + timeElapsed + "ms");

                    start = new Date();                     
                    $(selectorText).attr("checked", false);                             
                    end = new Date();
                    timeElapsed = end-start;
                    $(el).after("<br />Unchecking Took " + timeElapsed + "ms");
                }       

                function runWithContext(selectorText, context, el) {                    
                    var start = new Date();                     
                    $(selectorText, context).attr("checked", true);                             
                    var end = new Date();
                    var timeElapsed = end-start;
                    $(el).after("<br />Checking Took " + timeElapsed + "ms");

                    start = new Date();                     
                    $(selectorText, context).attr("checked", false);                                
                    end = new Date();
                    timeElapsed = end-start;
                    $(el).after("<br />Unchecking Took " + timeElapsed + "ms");
                }

                $("#one").click(function() {                        
                    run("input[id^='chkbox'][type='checkbox']", this);
                });

                $("#two").click(function() {
                    run("#myTable tr[id^='row'] input[id^='chkbox'][type='checkbox']", this);
                });

                $("#three").click(function() {
                    run("#myTable tr.myRow input[id^='chkbox'][type='checkbox']", this);
                });

                $("#four").click(function() {
                    run("tr.myRow input[id^='chkbox'][type='checkbox']", this);
                });

                $("#five").click(function() {
                    run("input[id^='chkbox']", this);
                });

                $("#six").click(function() {
                    run(".chkbox", this);
                });

                $("#seven").click(function() {
                    run("input.chkbox", this);
                });

                $("#eight").click(function() {
                    run("#myTable input.chkbox", this);
                });

                $("#nine").click(function() {
                    runWithContext("input.chkbox", "tr", this);
                });


                $("#nine1").click(function() {
                    runWithContext("input.chkbox", "tr.myRow", this);
                });
                $("#nine2").click(function() {
                    runWithContext("input.chkbox", "#form1", this);
                });
                $("#nine3").click(function() {
                    runWithContext("input.chkbox", "#myTable", this);
                });

                $("#ten").click(function() {
                    run("input[name=chkbox]", this);
                });                 

                $("#ten1").click(function() {
                    runWithContext("input[name=chkbox]", "tr.myRow", this);
                });

                $("#ten2").click(function() {
                    runWithContext("input[name=chkbox]", "#form1", this);
                });

                $("#ten3").click(function() {
                    runWithContext("input[name=chkbox]", "#myTable", this);
                });

                $("#ten4").click(function() {
                    runWithContext("input[name=chkbox]", $("#form1"), this);
                });

                $("#ten5").click(function() {
                    runWithContext("input[name=chkbox]", $("#myTable"), this);
                });

                $("#eleven").click(function() {
                    run("input[name='chkbox']:checkbox", this);
                });

                $("#twelve").click(function() {
                    run(":checkbox", this);
                });

                $("#twelve1").click(function() {
                    run("input:checkbox", this);
                });

                $("#thirteen").click(function() {
                    run("input[type=checkbox]", this);
                });

                $('#go').click(function() {
                    run($('#goBox').val(), this);
                });
            });
        </script>
</form>

Ответы [ 4 ]

8 голосов
/ 14 апреля 2009

input [name = chkbox] становится самым быстрым селектором jQuery на моей машине под IE7.

Unchecking Took 2453ms
Checking Took 2438ms
Unchecking Took 2438ms
Checking Took 2437ms
Unchecking Took 2453ms
Checking Took 2438ms

input.chkbox и ...

Unchecking Took 2813ms
Checking Took 2797ms
Unchecking Took 2797ms
Checking Took 2797ms
Unchecking Took 2813ms
Checking Took 2797ms

вход: checkbox.chkbox кажется связанным

Unchecking Took 2797ms
Checking Took 2797ms
Unchecking Took 2813ms
Checking Took 2781ms

.chkbox почти вдвое дольше, чем input.chkbox

Unchecking Took 4031ms
Checking Took 4062ms
Unchecking Took 4031ms
Checking Took 4062ms

Javascript для цикла, безусловно, является худшим в:

Checking Took 149797ms

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

Мне это тоже было довольно интересно:

вход [ID = 'chkbox']

Unchecking Took 3031ms
Checking Took 3016ms

заняло меньше времени, чем:

вход [ID = 'chkbox'] [тип = 'Флажок']

Unchecking Took 3375ms
Checking Took 3344ms

Я думал, так как я разместил больше фильтров, это будет быстрее. Неа!

Задание еще большего числа путей к флажку делает его медленнее:

# myTable tr [id ^ = 'row'] input [id ^ = 'chkbox'] [type = 'checkbox']

Checking Took 10422ms

Он даже не запускал вторую проверку, поскольку спросил, хочу ли я продолжать запускать сценарии на моем компьютере. Псих! : P

Обновление Утро 4/14:

Кто-то поднял настройку контекста: на самом деле я сделал несколько из них и многое к своему удивлению, и вопреки тому, что многие люди говорили в Интернете в IE7, они были медленнее ! Вот моменты, когда я получал несколько разных контекстов, указанных в сочетании с более быстрым селектором выше:

"input.chkbox", "tr"

Checking Took 8546ms

"input.chkbox", "tr.myRow"

Checking Took 8875ms

"input.chkbox", "# form1"

Unchecking Took 3032ms
Checking Took 3000ms

"input.chkbox", "#myTable"

Unchecking Took 2906ms
Checking Took 2875ms

Текущий победитель (все еще): input [name = chkbox]

Unchecking Took 2469ms
Checking Took 2453ms

"input [name = chkbox]", "tr.myRow"

Checking Took 9547ms

"input [name = chkbox]", "# form1"

Unchecking Took 3140ms
Checking Took 3141ms

"input [name = chkbox]", "#myTable"

Unchecking Took 2985ms
Checking Took 2969ms

Обновление 2 Утро 4/14

Думал, что мог бы быть лучше после того, как заметил синтаксическое отличие от http://beardscratchers.com/journal/jquery-its-all-about-context. Кажется, что они НЕ совпадают с , они дают немного лучшие времена, но все же не бьют неконтекстный селектор - штопать.

"input [name = chkbox]", $ ("# form1")

Unchecking Took 3078ms
Checking Took 3000ms
Unchecking Took 3078ms
Checking Took 3016ms

"input [name = chkbox]", $ ("# myTable")

Unchecking Took 2938ms
Checking Took 2906ms
Unchecking Took 2938ms
Checking Took 2921ms

Обновление 3 Утро 4/14

Расс хотел, чтобы я попробовал это, они де / выбрали ВСЕ коробки, но опять же было интересно:

: Флажок

Unchecking Took 8328ms
Checking Took 6250ms

вход: Флажок

Unchecking Took 5016ms
Checking Took 5000ms

-> Самый быстрый?!?! * * +1137 ввод [тип = флажок] * * тысячи сто тридцать девять

Unchecking Took 4969ms
Checking Took 4938ms

Тот факт, что третье место является самым быстрым, довольно интересен, поскольку это противоречит тому, что я мог бы подумать. Почему бы (по крайней мере, для IE7) флажок: просто использовать флажок type =, чтобы добиться более быстрого времени? Это очень близкие результаты, но проверка заняла на 62 мс меньше времени. Кроме того, почему первые два отличаются вообще? Есть ли другой элемент помимо входного, который может иметь флажок?

5 голосов
/ 14 апреля 2009

Я не проверял это, но вы могли бы попробовать создать массив [] ссылок на флажки при загрузке страницы, а затем просто повторять это каждый раз, когда вы хотите внести изменение?

Вы бы заплатили за производительность при загрузке страницы, но может быть быстрее, чем обходить DOM каждый раз. Эй, по крайней мере, вы будете выполнять тяжелую работу во время простоя пользователя (сколько времени потребуется людям, чтобы найти и щелкнуть опции отмены выбора / выбора).

2 голосов
/ 14 апреля 2009

Мое единственное предложение, вероятно, тоже не сработает. Переключите браузеры. Но у меня была только одна компания, которая фактически согласилась с этим. Мы заставили компанию перейти на FireFox, а конкретные пользователи перешли на Google Chrome. IE слишком медленно работает с JavaScript.

Также вы можете попробовать предварительно кэшировать список запросов jquery.

Если ничего не помогает, решите это с помощью психологии. Это означает, что пользователь должен знать, что что-то займет много времени. Установите функцию «Пожалуйста, подождите», пока функция выполняется. Таким образом, пользователь знает, что браузер не просто заблокирован, и он знает, когда он сможет вернуться к работе. У меня было много медленных страниц, "решенных", делая только это.

1 голос
/ 14 апреля 2009

Пробовали ли вы селекторы jQuery с context, чтобы увидеть, улучшает ли это производительность? Предположительно элементы управления будут внутри формы ASP.NET и, возможно, другого уникально идентифицируемого элемента?

Например, где у вас есть

$("input[id^='chkbox']")

Попробуйте с

$("input[id^='chkbox']", "#myFormID")

Вот статья BeardScratchers в контексте

EDIT:

После ваших обновлений кажется, что 2,45-6 секунд могут быть самыми быстрыми, которых вы можете достичь, учитывая ваши обстоятельства.

Просто для полноты, вы пробовали следующие селекторы?

$(':checkbox')
$('input[type=checkbox]')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...