DOM манипулирование использует собственные функции для выполнения простых операций. Поставщики браузеров оптимизируют их. Вы строите строку из HTML. Внутренне jQuery использует .innerHTML
для создания коллекции, которая затем исправляет мега-быстрый синтаксический анализатор браузера.
Выбор медленный по сравнению, потому что JS-коду необходимо многократно проходить через DOM. Более новые браузеры имеют встроенную обработку выбора, которая обеспечивает резкое ускорение JS на основе селектора. Со временем это станет меньшей проблемой.
Вот как разбивается запрос $(".checkbox input", row)
:
row.getElementsByTagName('*');
- for проходит через каждый возвращенный элемент (все элементы в строке) и тестирует
elements[i].className
с /(\s|^)checkbox(\s|$)/
.
- цикл для каждого оставшегося элемента и сбор
matched[i].getElementsByTagName('input');
- уникальная финальная коллекция.
Это отличается для jQuery 1.3, поскольку его движок движется по селектору наоборот, начиная с получения всех входных элементов и затем проверяя родительские элементы.
Помните, что движки селектора JS реализуют гораздо больше спецификации селектора CSS, чем на самом деле можно использовать с CSS (или реализовано в современных браузерах). Используя это, и знание движков, мы можем оптимизировать селектор, можно оптимизировать несколькими различными способами:
Если вы знаете, к какому типу элемента относится .checkbox
:
$("td.checkbox input", row);
Это быстрее для фильтра сначала для типа, а затем для класса только для тех совпадений. Это не относится к очень небольшому подмножеству элементов, но в практике это почти никогда не происходит.
Тест одного класса является самым медленным из распространенных селекторов, которые люди фактически используют .
Упрощенный выбор:
$("input[type=checkbox]", row);
Один цикл быстрее, чем два цикла. Это только находит входные элементы и затем непосредственно фильтрует их по атрибуту типа. Поскольку sub / child-elements никогда не используются, unique также может быть пропущен (и умные движки попытаются сделать это, так как unique медленный).
Более прямой селектор:
$("td:first.checkbox input", row);
Более сложный селектор на самом деле может быть быстрее, если он более прямой (YMMV).
Если возможно, переместите контекст поиска на уровень таблицы:
Под этим я подразумеваю, что вместо циклического обхода строк и поиска флажка в каждом из них оставьте их в покое до окончания цикла, а затем выберите их все одновременно:
$("tr td:first.checkbox input", table);
Смысл этого состоит в том, чтобы устранить накладные расходы при повторном запуске двигателя селектора, но вместо этого делать все за один раз. Это представлено здесь для полноты, а не для того, что, я думаю, могло бы привести к огромным ускорениям.
Не выбирайте:
Создайте ряд из битов, назначая события по мере продвижения.
var row = $( '<tr></tr>' );
var cell = $( '<td class="checkbox"></td>' ).appendTo( row );
$( '<input type="checkbox" name="..."/>' ).appendTo( cell ).click(/* ... */);
Это может быть невозможно по причинам, не зависящим от Ajax или других шаблонов. Кроме того, скорость может не стоить превращать ваш код в такого рода беспорядок, но иногда это может иметь смысл.
Или, если ни один из них не работает для вас, либо вы получаете слишком большой прирост производительности, возможно, пришло время полностью переосмыслить метод. Вы можете назначить прослушиватель событий выше по дереву и захватывать там события вместо экземпляра для каждого элемента:
$('table').change(function(e){
// you may want a faster check...
if ( $(e.target).is('input[type=checkbox]') ) {
// do some stuff ...
}
});
Таким образом, вы ничего не делаете, пока пользователь не запросит это. Самый быстрый. : -)