@primer/react
Version:
An implementation of GitHub's Primer Design System using React
86 lines (83 loc) • 2.31 kB
JavaScript
import { c } from 'react-compiler-runtime';
import React from 'react';
/**
* A hook that caches tree items to avoid expensive querySelectorAll calls on every keypress.
* The cache is invalidated when the tree structure changes (via MutationObserver).
*
* PERFORMANCE: This is critical for INP because querySelectorAll('[role="treeitem"]')
* on large trees can take 10-50ms, which directly blocks user input response.
*
* Note: useRovingTabIndex also uses querySelectorAll for Home/End/PageUp/PageDown navigation,
* but those are infrequent single keypresses. Typeahead fires on every character typed,
* making it the priority optimization target.
*/
function useTreeItemCache(containerRef) {
const $ = c(7);
const cacheRef = React.useRef(null);
let t0;
let t1;
if ($[0] !== containerRef) {
t0 = () => {
const container = containerRef.current;
if (!container) {
return;
}
const observer = new MutationObserver(mutations => {
const hasStructuralChange = mutations.some(_temp);
if (hasStructuralChange) {
cacheRef.current = null;
}
});
observer.observe(container, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ["role"]
});
cacheRef.current = null;
return () => observer.disconnect();
};
t1 = [containerRef];
$[0] = containerRef;
$[1] = t0;
$[2] = t1;
} else {
t0 = $[1];
t1 = $[2];
}
React.useEffect(t0, t1);
let t2;
if ($[3] !== containerRef) {
t2 = () => {
const container_0 = containerRef.current;
if (!container_0) {
return [];
}
if (cacheRef.current !== null) {
return cacheRef.current;
}
cacheRef.current = Array.from(container_0.querySelectorAll("[role=\"treeitem\"]"));
return cacheRef.current;
};
$[3] = containerRef;
$[4] = t2;
} else {
t2 = $[4];
}
const getTreeItems = t2;
let t3;
if ($[5] !== getTreeItems) {
t3 = {
getTreeItems
};
$[5] = getTreeItems;
$[6] = t3;
} else {
t3 = $[6];
}
return t3;
}
function _temp(mutation) {
return mutation.type === "childList" || mutation.type === "attributes" && mutation.attributeName === "role";
}
export { useTreeItemCache };