UNPKG

@primer/react

Version:

An implementation of GitHub's Primer Design System using React

86 lines (83 loc) 2.31 kB
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 };