Какой селектор более эффективен - PullRequest
0 голосов
/ 18 января 2019

Я использую jQuery и хочу знать, какой селектор быстрее, но я не знаю, с чего начать его тестирование. Я понимаю, что самый эффективный селектор (самый быстрый) использует идентификатор типа $("#xxx").

А как же $("img[data-src]") или $("[data-src]")? Что является наиболее эффективным? Я знаю, что селекторы читаются справа налево, поэтому я должен предположить, что удаление «img» из селектора делает это быстрее? Если да, знаете ли вы, какой код я могу запустить на своей странице, чтобы 1000 раз проверить, какой селектор самый быстрый?

Ответы [ 2 ]

0 голосов
/ 18 января 2019

В общем, селекторы идут в следующем порядке эффективности (от самого низкого до самого эффективного):

  • ID
  • Класс
  • Имя тега
  • Детские отношения (foo > bar)
  • Отношения потомков (foo bar)
  • Атрибут (foo[bar="baz"])
  • Псевдоклассы (foo:hover, foo:nth-child())

Другое соображение заключается в том, что CSS-селекторы - это в основном поиск по дереву, поэтому чем больше вы можете вырезать из дерева, тем лучше. #foo .bar - это отношение потомков, но если включение #foo исключит большую часть вашего HTML из поиска, это сделает этот селектор более эффективным. Точно так же теоретически img[data-src] будет быстрее, чем [data-src], поскольку существует более ограниченный набор элементов, атрибут которых необходимо проверить.

(я не знаю этого наверняка, но ожидал бы, что правила CSS не всегда интерпретируются в строгом порядке справа налево. #foo .bar например, будет более эффективным, если интерпретируется слева направо: сначала ищите элемент ID, затем вам нужно только проверить его дочерние элементы на .bar вместо поиска по всему документу. Я бы предположил, что очевидные оптимизации производительности, подобные этой, уже встроены в большинство или во все движки браузера.)

Есть также некоторые случаи, когда вы можете заменить javascript-методы для правил css, такие как $('foo:nth-child(1)') против $('foo').first() - в этом конкретном случае jQuery быстрее , хотя это не обобщается для всех конечно, селекторы (так как для них нет соответствующих методов).

Если вы сомневаетесь, вы можете сравнить такие вещи, просто повторно выполнив выделение (в соответствии с вашим настоящим HTML) в цикле:

benchmark = function(selector) {
  var t1 = new Date();
  for (var i=0; i<100000; i++) {
      var x = $(selector);
  }
  var t2 = new Date();

  console.log(selector, t2-t1, "ms")
}

benchmark('[data-src="bar"]')
benchmark('img[data-src="bar"]')
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <div data-src="bar"></div>
  <img data-src="bar">
</div>

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

В большинстве случаев, с большинством веб-страниц, это мало что меняет в реальном мире. С очень простым HTML выше, селектор почти не имеет значения даже при 100 000 итерациях. На 10 000 итераций я даже не получаю последовательных результатов, из которых быстрее.

Если вы работаете с относительно большими деревьями HTML и сложными селекторами и начинаете видеть реальные проблемы с производительностью, которые, как вы подозреваете, связаны с этими поисками DOM, , тогда хорошая идея - начать тестирование такого рода. вещи. (Хотя даже в этом случае большую часть времени вы увидите больше улучшений от кэширования и повторного использования предыдущих вариантов, чем от точной настройки самих вариантов.)

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

0 голосов
/ 18 января 2019

$("img[data-src]") - более быстрый селектор, поскольку ему нужно будет только посмотреть на теги img, где $("[data-src]") будет смотреть на каждый элемент в DOM с этим атрибутом.

...