:scope was added to qS/qSA in http://trac.webkit.org/changeset/145691. Running a few tests, I'm seeing using :scope takes ~2x longer. For example: var scope = document.querySelector('#scope'); scope.querySelectorAll('span'); always beats: scope.querySelectorAll(':scope span'); My test is here: http://jsbin.com/icahoc/1/ I would expect the latter to be as fast (if not faster) since there's a context element to restrict the search. Any insight?
Mar 26 2013,
I looked at http://jsbin.com/icahoc/1/ and investigated this issue. So, var nodes = scope.querySelectorAll('span'); var nodes = scope.querySelectorAll(':scope span'); I think, querySelectorAll's cost depends on how many elements are checked to match a given selector. The first querySelectorAll has only one selector but the second one has two selectors. Since the first and second use the same "scope" element, both querySelectoAll check the same elements. For each element, (a) the first querySelectorAll: checks whether a given element is span or not. (b) the second querySelectorAll: does above. Next walks up toward document root with checking whether a scoping node is in a chain from the element to root. (b) needs to see at least one more element comparing with (a). This causes "~2x longer". Roughly speaking, querySelector(All) needs "number of a given element's children" x "number of elements to walk up" (in this case, almost the same as number of selectors).
Apr 5 2013, Project Member
Apr 6 2013, Project Member
Apr 18 2013,
May 22 2013,
The expression could be broken in half. First evaluate the :scope portion of the expression and then evaluate the selector portion just as before as if the scope portion doesn't exist (with the caveat that you don't let parent checks pass :scope). It should give you the desired performance gain... but since this is my first time looking at this codebase I don't think I'll be doing it, there is just too much for me to take in.
Jun 9 2013,
Perhaps .find won't have this issue.
Jun 10 2014,
I'll take over the ownership of this bug, but looks like it is 1 year old and needs validation (thus 'untriaged').
Jun 10 2014,
I think, it would be better to make this issue "WontFix", because: - currently we have some fast path for querySelector with simple id selector or simple tag selector, and - the length of ":scope span" is 2 and the length of "span" is 1. So we need to spend 2x longer time for SelectorChecker::match.
Aug 6 2015,
Aug 28 2015,
Aug 31 2015,
.find(), defined in http://www.w3.org/TR/selectors-api2/ could solve the performance issue?
Dec 27 2015,
any news or updates about :scope in querySelector() ?
Jan 31 2016,
Do you have example pages where this slowdown is a problem? Having a trace from about:tracing, or a profile from the inspector where querySelector is causing you issues would be really great.
Feb 1 2016,
I personally don't have a page, but I have avoided using this feature in my apps due to it being slower than normal qS. We don't have chromestatus.com metrics on this feature, but I doubt it sees very much usage. It's hard to find a real page to trace.
Jul 11 2017,
Selector API might be in Blink > CSS.
Jul 12 2017,
Jul 12 2017,
Oct 17 2017,
bulk edit to remove owner=me where I'm not actively looking at.
Oct 17 2017,
mark it available.
Nov 27 2017,
Nov 30 2017,
This can be fixed by doing what I've outlined here: https://bugs.chromium.org/p/chromium/issues/detail?id=492482#c13
Dec 6 2017,
Dec 7, Project Member
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue. Sorry for the inconvenience if the bug really should have been left as Available. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
Sign in to add a comment