Тестирование производительности селекторов jQuery
Всем известно что jQuery может все. Но далеко не всем известно что jQuery это может несколькими способами. Вот именно об этом я и хочу сегодня поговорить, а заодно проверить какой способ быстрее. Подвергну тестам вышедшую сегодня в свет jQuery 1.3.2, вставленную в страницу результатов Google, общий вес html файла чуть более чем 25кб, все возможные тэги в наличии. Еще хотелось бы акцентировать внимание на том что я не буду использовать псевдо-селектор :not() , так как смысловой нагрузки он не несет, хотя дает еще один способ выбрать элемент.
Первым я протестирую контекст, проверять буду вот таким скриптом
var start = new Date();
for(var i=0;i<1000;i++)
$....
var stop = new Date();
console.log(stop-start)
Я не будем добавлять ничего нового к коду Google, а только попробуем собрать коллекцию li.
| $("li", document) | 120 |
| $("li", "ol") | 220 |
Вывод из первого эксперимента - сам по себе контекст это еще один поиск по DOM дереву, поэтому задавать контекст стоит только если второй запрос ограничит первый на столько что сэкономленное время будет больше чем время второго запроса, такого эффекта можно добиться например указав id родителя (не обязательного прямого) в контексте.
Второй пример покажет как лучше всего получить всех прямых потомков.
| $("ol>*") | 1800+ |
| $("ol>li") | 215 |
| $("ol").children("li") | 330 |
Не используйте звездочку - это не оправдано в 99.9% случаев (а в этом примере * возвращает еще и затесавшийся случайно элемент link) и не стоит без особой надобности использовать метод children - он тормозит.
В третьем примере я протестирую получение первого прямого потомка.
| $("ol>li:first") | 375 |
| $("ol>li:eq(0)") | 380 |
| $("ol>li").eq(0) | 240 |
| $("ol:first-child") | 140 |
| $("ol:nth-child(1)") | 165 |
| $("ol").children("li") | 330 |
| $("ol").find(":first-child") | 1500+ |
| $("ol").find(":nth-child(1)") | 2600+ |
Не могу найти разумного объяснения почему так тормозит find, но наверное на это есть какие-то причины. А еще интересна разница в использовании eq(0) как селектора и как метода - дольше в полтора раза.
Думаю стоит отвлечся от потомков и протестировать атрибуты. Вытащим input у которых type=radio
| $(":radio") | 1500+ |
| $("[type=radio]") | 2400+ |
| $("input:radio") | 200 |
| $("input[type=radio]") | 240 |
| $("input").filter("[type=radio]") | 320 |
Похоже фильтром тоже не стоит злоупотреблять, а псевдо-селекторы придуманы не только для удобства в написании
Ну и конечно надо доколупаться до классов а то было бы не честно
| $("[class^=gac]") | 2700+ |
| $(".gac_a, .gac_c, .gac_d, .gac_e, .gac_m") | 1200+ |
| $(".gac_a").add(".gac_c").add(".gac_d").add(".gac_e").add(".gac_m") | 1100+ |
Магия...
Свежие комментарии