Skip to content

Commit 7a912d4

Browse files
it turns out that Element.contains is really slow, so big perf win by precomputing the active element parent path and doing an array inclusion check instead.
1 parent c89b5bb commit 7a912d4

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

src/idiomorph.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ var Idiomorph = (function () {
112112
* @property {ConfigInternal['callbacks']} callbacks
113113
* @property {ConfigInternal['head']} head
114114
* @property {HTMLDivElement} pantry
115+
* @property {Element[]} activeElementAndParents
115116
*/
116117

117118
//=============================================================================
@@ -424,7 +425,8 @@ var Idiomorph = (function () {
424425

425426
// if the current node contains active element, stop looking for better future matches,
426427
// because if one is found, this node will be moved to the pantry, reparenting it and thus losing focus
427-
if (cursor.contains(document.activeElement)) break;
428+
// @ts-ignore pretend cursor is Element rather than Node, we're just testing for array inclusion
429+
if (ctx.activeElementAndParents.includes(cursor)) break;
428430

429431
cursor = cursor.nextSibling;
430432
}
@@ -996,6 +998,7 @@ var Idiomorph = (function () {
996998
idMap: idMap,
997999
persistentIds: persistentIds,
9981000
pantry: createPantry(),
1001+
activeElementAndParents: createActiveElementAndParents(oldNode),
9991002
callbacks: mergedConfig.callbacks,
10001003
head: mergedConfig.head,
10011004
};
@@ -1036,6 +1039,21 @@ var Idiomorph = (function () {
10361039
return pantry;
10371040
}
10381041

1042+
/**
1043+
* @param {Element} oldNode
1044+
* @returns {Element[]}
1045+
*/
1046+
function createActiveElementAndParents(oldNode) {
1047+
/** @type {Element[]} */
1048+
let activeElementAndParents = [];
1049+
let elt = document.activeElement;
1050+
while (elt && elt !== oldNode) {
1051+
activeElementAndParents.push(elt);
1052+
elt = elt.parentElement;
1053+
}
1054+
return activeElementAndParents;
1055+
}
1056+
10391057
/**
10401058
* Returns all elements with an ID contained within the root element and its descendants
10411059
*

0 commit comments

Comments
 (0)