Skip to content

Commit c03ef18

Browse files
committed
Get selector optimisation
1 parent 5830a47 commit c03ef18

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

lib/core/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const definitions = [
2828
const constants = {
2929
helpUrlBase: 'https://dequeuniversity.com/rules/',
3030
gridSize: 200,
31+
selectorSimilarFilterLimit: 700,
3132
results: [],
3233
resultGroups: [],
3334
resultGroupMap: {},

lib/core/utils/get-selector.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import getNodeAttributes from './get-node-attributes';
44
import matchesSelector from './element-matches';
55
import isXHTML from './is-xhtml';
66
import getShadowSelector from './get-shadow-selector';
7+
import memoize from './memoize';
8+
import constants from '../../core/constants';
79

810
const ignoredAttributes = [
911
'class',
@@ -376,8 +378,8 @@ function generateSelector(elm, options, doc) {
376378
} else {
377379
selector = features;
378380
}
379-
if (!similar) {
380-
similar = Array.from(doc.querySelectorAll(selector));
381+
if (!similar || similar.length > constants.selectorSimilarFilterLimit) {
382+
similar = findSimilar(doc, selector);
381383
} else {
382384
similar = similar.filter(item => {
383385
return matchesSelector(item, selector);
@@ -401,6 +403,16 @@ function generateSelector(elm, options, doc) {
401403
* @param {Object} optional options
402404
* @returns {String|Array<String>} Unique CSS selector for the node
403405
*/
404-
export default function getSelector(elm, options) {
406+
function getSelector(elm, options) {
405407
return getShadowSelector(generateSelector, elm, options);
406408
}
409+
410+
// Axe can call getSelector more than once for the same element because
411+
// the same element can end up on multiple DqElements.
412+
export default memoize(getSelector);
413+
414+
// Similar elements create similar selectors. If there are lots of similar elements on the page,
415+
// axe ends up needing to run that same selector many times. We can memoize for a huge perf boost.
416+
const findSimilar = memoize((doc, selector) =>
417+
Array.from(doc.querySelectorAll(selector))
418+
);

0 commit comments

Comments
 (0)