Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   QSA CSS Selector Engine v1.0 - Выкладываю CSS-селектор по просьбе трудящихся (https://javascript.ru/forum/project/24330-qsa-css-selector-engine-v1-0-vykladyvayu-css-selektor-po-prosbe-trudyashhikhsya.html)

devote 26.12.2011 13:39

QSA CSS Selector Engine v1.0.1 - Выкладываю CSS-селектор по просьбе трудящихся
 
Основные отличия от Sizzle - в два раза меньше размер обфусцированного файла, исходный так же присутствует. Все по максимуму прокомментировано на русском языке. Скорость работы внутреннего поиска не используя встроенный селектор в браузер, в среднем в полтора раза выше чем Sizzle. Почему сравниваю только Sizzle, потому что единственный селектор который сортирует элементы на выходе.

другие селекторы, такие как:
Mootools, Prototype, Dojo, DOMAssistant, jQuery( не Sizzle ), YASS и д.р. Не правильно сортируют элементы. Можете сами проверить.

тесты:
http://spb-piksel.ru/tests/speed/
http://spb-piksel.ru/tests/speed2/

Использование:

qsa.querySelectorAll( string selector [, node/nodeList context(s), nodeList extra(s) ] );

qsa.querySelectorAll( "div + p > a" );
qsa.querySelectorAll( "div + p > a", document.getElemetById("myNode") );
qsa.querySelectorAll( "div + p > a", document.getElemetById("myNode"), [ elem1, elem2, elem3 ] );


Найдете ошибки, иль чего не то... сообщайте. СПС

1.2 - исправил ошибку при использовании объекта как наполняющего результат, происходило удаление совсем не того элемента. Так же добавил четвертый параметр noSort отключает сортировку результатов, увеличивается скорость поиска элементов, но при этом элементы не сортируются.

1.2.1 - Убрал зависания при неправильных селекторах.

1.2.2 - Не искал элементы с селектором: style[type="text\\/css"] Исправлено.

1.2.3 - В Safari при сортировке элементов происходил сбой Исправлено.

1.3 - Добавлен метод matchesSelector.

GitHub: https://github.com/devote/QSA
ссылка для скачивания: http://code.spb-piksel.ru/?qsa.latest.zip

TAGS: CSS3 Selector, селектор, qsa, поиск элементов, движок селекторов

devote 27.12.2011 05:57

Была исправлена серьезная ошибка

float 27.12.2011 07:35

line: 134 - 2-ка не лишняя?

devote 27.12.2011 07:36

Цитата:

Сообщение от float
line: 134 - 2-ка не лишняя?

нет не лишняя, это для ИЕ который отдает ссылку в полном формате в зависимости от текущего домена, а не ту что указана в href, поэтому ему явно нужно указывать что нужна та что есть в теге

float 27.12.2011 07:52

нда... надо бы мне почаще на msdn заглядывать...:)

devote 27.12.2011 07:54

Цитата:

Сообщение от float (Сообщение 146366)
нда... надо бы мне почаще на msdn заглядывать...:)

Ну мы туда смотрим как правило по необходимости, а сидеть изучать его нет времени и надобности

devote 27.12.2011 13:50

Добавил дополнительную реализацию

devote 27.12.2011 15:26

Никак не могу оставить ее в покое =)) На сегодня точно все, больше ничего исправлять не буду.

FINoM 27.12.2011 20:10

Круто. Только мало что понял :D

trikadin 27.12.2011 20:15

Цитата:

Сообщение от FINoM
Круто. Только мало что понял

Вот-вот...

FINoM 27.12.2011 20:18

Цитата:

Сообщение от trikadin
Вот-вот...

Я просто никогда не писал серьезных парсеров на регулярках.

devote 27.12.2011 20:19

Цитата:

Сообщение от FINoM (Сообщение 146538)
Круто. Только мало что понял :D

А что не понятно? Вы спрашивайте, я расскажу что да как

devote 27.12.2011 20:20

Цитата:

Сообщение от FINoM
Я просто никогда не писал серьезных парсеров на регулярках.

Да там всего одна регулярка... в отличии от Sizzle в которой их десяток

FINoM 27.12.2011 20:26

Цитата:

Сообщение от devote
А что не понятно? Вы спрашивайте, я расскажу что да как

Та ничего, всё равно не пойму :D
Если у тебя есть лишнее время, то хотелось бы увидеть сравнение производительности твоей либы, сиззла и нативного querySelectorAll при разных селекторах.

devote 27.12.2011 20:41

Цитата:

Сообщение от FINoM
Если у тебя есть лишнее время, то хотелось бы увидеть сравнение производительности твоей либы, сиззла и нативного querySelectorAll при разных селекторах.

http://spb-piksel.ru/tests/speed/

стандартный метод querySelectorAll отключен в обеих библиотеках

trikadin 27.12.2011 20:49

Цитата:

Сообщение от devote

Ничё такой перевес...

devote 27.12.2011 20:53

Цитата:

Сообщение от FINoM
и нативного querySelectorAll при разных селекторах.

C нативным вообще сравнивать нет смысла, там почти всегда все в ноль мс.

devote 28.12.2011 00:06

добавил ссылки на тесты в первый пост, так что смотрите сами и делайте выводы

FINoM 28.12.2011 00:25

Добавь плиз querySelectorAll

trikadin 28.12.2011 00:26

Цитата:

Сообщение от FINoM
Добавь плиз querySelectorAll

Там добавлено поле, в котором прописано количество элементов, которые нужно найти. А нативную ф-цию подключать смысла нет, имхо.

FINoM 28.12.2011 00:27

Это какой-то фреймворк для замеров скорости?

trikadin 28.12.2011 00:28

Цитата:

Сообщение от FINoM
Это какой-то фреймворк для замеров скорости?

Да.

Там подписано внизу.

devote 28.12.2011 00:29

Цитата:

Сообщение от FINoM
Добавь плиз querySelectorAll

ну добавил

devote 28.12.2011 00:29

Цитата:

Сообщение от FINoM
Это какой-то фреймворк для замеров скорости?

для замеров скорости селекторов

FINoM 28.12.2011 00:30

Цитата:

Сообщение от trikadin
А нативную ф-цию подключать смысла нет, имхо.

Мне кажется есть.
Цитата:

Сообщение от devote
для замеров скорости селекторов

Оно один раз селектит или много?

FINoM 28.12.2011 00:33

Цитата:

Сообщение от devote
для замеров скорости селекторов

Не подскажешь фреймворк для замера скорости не только селекторов?

devote 28.12.2011 02:07

Цитата:

Сообщение от FINoM
Оно один раз селектит или много?

много, если точно 25раз, в моей версии, вычисляет среднее время со всех запусков, я его доработал ибо их версия всем довала одинаковые значения, и там небыло значения с плавующей точкой. тоесть микросекунд
Цитата:

Сообщение от FINoM
Не подскажешь фреймворк для замера скорости не только селекторов?

неа

float 29.12.2011 12:22

Потестил в опере 8,5 :D
до селектора div, p, a расклад примено 500/8000 в пользу сизла.
qsa проседает на селекторах:
p + p + .example > p
body div
div p
на 1-м меньше всего кстати. что странно...
оба сильно проседают на селекторе div, p, a
сизл на минуту зависает, qsa на пол.

ещё неплохо бы эксепшены добавить. чтобы запросы типо qsa.querySelectorAll('>') не вешали намертво браузер.

имхо с реди и расширением прототипа эт залишнее.

devote 29.12.2011 14:36

float,
нашел на чем тестить, речь идет о сегдняшних браузерах. ие7, ие8, вот эти два важных браузера в которых нужно тестить, а опера 8 это прошлый век. и я не совсем понял все же по твоим тестам кто лидер. выше ты написал одно, ниже другое.

и всмысле виснет?

devote 29.12.2011 15:07

ок, зависание убрал... удалил пару ненужных функций, вместо них написал новую. Вывожу эскепшн.. проседания у меня таковы:
если смотреть в ИЕ8 то разница между сизл и qsa таковы:
p + p + .example > p
сизл - 20.19 ms | 40 found
qsa - 27.31 ms | 40 found

div p
сизл - 20.88 ms | 140 found
qsa - 55.88 ms | 140 found

Это все в чем проигрывает qsa сизлу, во всех остальных селекторах сизл либо проигрывает либо на ровне, в большинстве случаях сизл проигрывает. Особенно на сложных селекторах.

Цитата:

Сообщение от float
на 1-м меньше всего кстати. что странно...

Немного теории, как они работают. сизл работает в обратную сторону, тоесть он сначала ищет то что указано в конце селектора, а потом ищет родителей совпавших с селектором ранее. Тоесть такой селектор:
p + p + .example > p
он перебирает таким образом: находит все теги P который указан в конце селектора. Потом ищет родителей с классом .example ну а потом смотрит что бы у родственника был брательник с тегом P и у того тоже брательник с тегом P. У меня же селектор идет от начала селектора, ищет все P, находит у них братьев и так далее. Вот именно из-за этого и есть разница, выигрывает тот кто быстрее наткнется на неудачу... поэту это сложный селектор и он всегда у всех может быть иной результат, все зависит от количества элементов в документе, и количества совпадений.. потому что прокручивать приходиться каждого рекурсивно в поисках дополнительных правил.

Цитата:

Сообщение от float
имхо с реди и расширением прототипа эт залишнее.

Это лишь дополнительная библиотека, реди нужен для того что бы дождаться загрузки DOM и всем существующим элементом назначить прототипы.

Никто не заставляет пользоваться версией с прототипами. Именно поэтому и сделаны две ветки.

Nekromancer 29.12.2011 15:38

devote,
кстати сизл так работает потому, что так так работает реальны css селектор :)

devote 29.12.2011 16:09

Цитата:

Сообщение от Nekromancer (Сообщение 147076)
devote,
кстати сизл так работает потому, что так так работает реальны css селектор :)

возможно, но тесты дают не лучший результат при обратном поиске. у меня частично так реализовано, для некоторых правил, но не для всех.

float 30.12.2011 01:40

Оперу я так, интереса ради. На старух браузерах qsa всегда лидирует в общем зачёте. Но для оперы 8,5, например, это только за счёт разницы в полминуту, так бы проиграл.
А вообще я прицепился потому, что в принципе во всех браузерах qsa не всегда, но часто проигрывает на старте, а там как бы самые употребительные селекторы...
А вообще этот тест немного странный. На одних и тех же ячейках иногда очень разный результат... Мб из-за работы сборщика или ещё чего...

devote 30.12.2011 01:49

Цитата:

Сообщение от float
Мб из-за работы сборщика или ещё чего...

И это тоже... сложно выяснить средний результат от одного запуска, тут надо сидеть с десяток раз запускать и смотреть средний результат.

devote 31.01.2012 04:49

Обновил версию

poorking 31.01.2012 22:19

devote,
Так что нового?, это ж самое интересное :)

Посмею пролить немного занудной слизи по поводу этих движков селекторов. Когда cмотришь регулярные выражения подобных творений, складывается впечатления что авторы не потрудились посмотреть грамматику селекторов в спецификации, где, чуть ли не готовые регулярные выражения написаны. Конечно адекватный пользователь интерфейса (который заведомо кривые селекторы вводить не будет), не натолкнется на косяки, но раз уж авторы утверждают, что движок dom выборок по CSS селекторам, то я думаю, что нужно соответствовать спецификации, раз уж мы имеем право гневно обсуждать, например, разработчиков браузеров, которые им не следуют. Например, приведу, некоторые из частей регулярного выражения QSA. В спецификации есть понятие IDENT, в QSA это выглядит вот так
[\w\-]+

Хотя по спецификации IDENT выглядит, если не ошибаюсь, вот так
-?(?:\\[\s\S]|[_a-zA-Z\u0080-\uFFFF])(?:\\[\s\S]|[\w\-\u0080-\uFFFF])*


Это конечно наглеж, но я хотя бы вот так написал
-?[_a-zA-Z][\-\w]*
чтобы цифру первой не вводили


И так далее. Такие допущения позволяют пользователю вводить невалидные данные и получать в лучшем случае никакой результат, в худшем - повисший браузер. Но это еще ладно.

У меня есть элемент
<a href = "javascript: void 0">


Я накосячил, написал
qsa.querySelectorAll("a[href*='jav\"]")


И получил [], и не понимаю почему? ведь если бы я неправильно ввел что-то, то получил бы SyntaxError, верно? А элемент искомый в моем документе 100% есть. Потом я ввел "a[href*='jav\"] +" и браузер вообще ушел куда то в бесконечность, дальше исследовать не стал.

Нет стал, еще интересный момент. В последовательности простых селекторов NS|TYPE#ID.CLASS[NS|ATTR]:PSEUDOFN(ARG) селектор типа может быть ТОЛЬКО первым номером. Но рядовой регексп с радостью обнаружит селектор типа например в таком случае [ATTR]TYPE или в таком :not(ololo)div, я в своем парсере ( однажды заморочился и написал парсер такой, который не позволял вводить невалидные данные, но выборки сделать сравнительно быстрые не получилось, особенно на том моменте где идет удаление дубликатов и сортировка (дубликаты ок, но наф вообще сортировка?) ) это все контролировал и кидал SyntaxError. Но к сожалению если все это учесть, то регулярка получается толстенная, которая ловит еще и ошибки, в ней около 15-20 карманов и возможно (я тогда не сравнивал) было не шибко производительно

А если без занудства, то движок реально крут, что так быстр.
IMHO qsa настолько быстр потому что не валидирует входные данные, а парсер очень мягок

devote 31.01.2012 22:29

poorking,
полностью соглашусь с тобой по поводу придерживания стандартов. Я не старался искать ошибки и их обрабатывать. НО! Скорость важнее, это же все же не нативный метод. Хотя если сравнивать с многими другими селекторами, то там обзор характеристик куда хуже. Не то что бы ошибки ловили, а порой и на валидных селекторах падают.

Да я читал спецификацию, и видел готовые реги для тех или иных случаев, но меня в первую очередь интересовала скорость работы с валидными селекторами. То что виснет, конечно не есть гуд. Обязалово посмотрю. Но проверять каждую мелочь, хм... а стоит ли? Нужно ли пожертвовать скоростью и компактностью ради проверок?

poorking 31.01.2012 22:43

devote,
Если вы хотите чтобы ваш движок был попопулярен, то надо найти компромисс, то есть контролировать реально наглые опечатки типа TYPE + (и после комбинатора нет селектора), и обеспечить неконкурентную производительность.

Про селектор типа не обязательно на первом месте можно вообще сказать что это фича, а кавычки написать так, чтобы левая была двойная, а правая одинарная, или наоборот, только безумцу может прийти в голову, в Sizzle вообще без облома написано ['"][^'"]['"] (давно смотрел сейчас не знаю) хотя это не верно, потому что вот так например "'" не написать, хотя валидно. Думаю это можно упустить. Так что если для масс - то главное хотя бы чтобы не висло ничего, и бегало быстро :) А специально чепуху аргументами вводить никто не будет, потому что это никому не надо, главное контролировать всякие левые типы кроме строк :)

devote 31.01.2012 23:14

Цитата:

Сообщение от poorking
Если вы хотите чтобы ваш движок был попопулярен, то надо найти компромисс, то есть контролировать реально наглые опечатки типа TYPE + (и после комбинатора нет селектора), и обеспечить неконкурентную производительность.

Да согласен, постараюсь это все организовать.

Цитата:

Сообщение от poorking
потому что вот так например "'" не написать, хотя валидно.

Ну у меня селектор нормально находит такие селекторы.

float 01.02.2012 00:20

Цитата:

Если вы хотите чтобы ваш движок был попопулярен, то надо найти компромисс, то есть контролировать реально наглые опечатки типа TYPE + (и после комбинатора нет селектора), и обеспечить неконкурентную производительность.
Вообще-то любые проверки сильно ударяют по скорости(хотя в регэкспах может и не особо. смотря где.)...
Помойму главное гарантировать то что не произойдёт зависания/зацикливания функции. А там: может имя класса с цифры начинаться или не может - дело десятое.
Хотя с другой стороны... Расхождение в поведении с встроенной функцией(в плане выброса исключений) тож не хорошо.


Часовой пояс GMT +3, время: 07:48.