./ Практика / YASS vs. All
Чуть больше года назад на Хабрахабре проскакивала статья про новый движок CSS-селекторов, который позиционировался как самый быстрый на планете.
YASS – Yet Another cSS selector (yass.webo.in)
Я следил за его развитием очень внимательно, чисто из практических соображений. Да, такие вещи, как кэширование селекторов и более быстрые внутренние циклы я позаимствовал именно оттуда. Проект достаточно быстро развивался, про него было написано несколько статей. Разработка движка велась буквально в комментариях к этим статьям на Хабре.
Спустя какое-то время мой интерес к нему угас. Разработка вроде заморозилась, а я был занят развитием собственного движка селекторов.
И вот, я решил заглянуть на страницу разработчика чтобы посмотреть, какие новые успехи у YASS. И если честно, я был разочарован.
Начнём по порядку. Первое, что бросилось в глаза, это скудность типов поддерживаемых селекторов. С сайта разработчика:
Поддерживаемые селекторы:
для выбора класса (например, .example),
для выбора узлов по имени тега: span или div,
наследование (например, div p a),
выбор дочерних элементов через >,
выбор дочерних узлов первого уровня через ~,
выбор первого дочернего узла с помощью +,
выбор элементов по идентификатору #id,
универсальный селектор — *,
запросы к атрибутам:
[type=checkbox] атрибуты с точным значением (class отработает по совпадению подстроки),
[title] — существование атрибута у элемента,
[rel~=nofollow] — наличие в атрибуте заданной строке в качестве значения, разделенного пробелами,
[class^=block] — значение атрибута, начинающееся с заданного значения,
[class$=hidden] — или заканчивающегося ею,
[alt*=image] — соответствие подстроки значения атрибута заданной,
[alt!=image] — отсутствие в атрибуте заданной строке в качестве значения, разделенного пробелами,
позиции элементов относительно родителей: :first-child, :last-child,
пустые элементы через селектор :empty,
корневой элемент (HTML) через :root,
выбранные элменты формы через псевдо-селектор :checked,
позиция элемента в родительском элементе — :nth-child(3),
выбор элементов по заданной позиции через :nth-child(even), :nth-child(odd), :nth-child(2n+1),
псевдо-селетор языка :lang.Неподдерживаемые селекторы:
Некоторые селекторы пока еще не поддерживаются. Вполне возможно, что ситуация изменится с выходом новых версий YASS.
отрицательный селектор :not(…),
множественные селекторы [class=class1][class=class2].
На первый взгляд всё нормально, хотя и видно, что не поддерживается :not(). Печально. Я скачал последнюю на данный момент версию библиотеки (версия 0.3.9 r179 от Nov 08, 2009) и запустил на локальном тесте SlickSpeed.
Первые впечатления: да, неплохо. Большая часть селекторов обрабатывается за 0.003 мс. Но чего стоит такая большая скорость работы? Кэширование? Быстрые циклы?
Нет. Это стоит того, что библиотека подгонялась под синтетические тесты. Стоит немного изменить селекторы, и всё, недобор элементов. YASS поддерживает очень ограниченные условия для :nth-child() – только число, “2n+1″, “2n”, “even” и “odd”. Позвольте, а где же, например “4n+2″, “-2n+1″ и т.п.? Нету, и видимо не планируется.
Даю навскидку 7 селекторов, некорректно работающих в YASS и корректно работающих в других библиотеках, в том числе и в Carbon.JS (замечу, что по заявлениям разработчика все они должны обрабатываться корректно):
- * > :nth-child(2n+1)
- * > * + * ~ *
- p:nth-child(even) > a[href^=http]
- html > body
- ul > li *
- p:nth-child(1)
- div div
Вывод только один: скорость – не главное. Не стоит доверять одним только тестам, всегда нужно всё проверять на практике самому.
