// Effect cost for #3890: the one added useLayoutEffect parks focus then sets // state, so it costs an extra commit per fully-hidden collapse. Counts, not ms. const {openStory, row} = require(process.env.HOME + '/astryx/probe-kit/lib.cjs'); async function cycle(story, label, focusInside) { const {browser, page} = await openStory('chromium', story, { port: 6157, viewport: {width: 1000, height: 500}, ready: () => document.querySelector('nav[role="navigation"]') != null, launch: {headless: false}, }); const cdp = await page.context().newCDPSession(page); await cdp.send('Performance.enable'); const read = async () => { const {metrics} = await cdp.send('Performance.getMetrics'); const m = Object.fromEntries(metrics.map(x => [x.name, x.value])); return {layout: m.LayoutCount, recalc: m.RecalcStyleCount, nodes: m.Nodes}; }; // Count React commits on the nav subtree as attribute/child mutations of the // nav element itself — inert lands in its own commit, which is the cost. await page.evaluate(() => { window.__commits = []; const nav = document.querySelector('nav[role="navigation"]'); new MutationObserver(ms => ms.forEach(m => window.__commits.push(`${m.type}:${m.attributeName ?? ''}`) )).observe(nav, {attributes: true}); }); const before = await read(); await page.evaluate(inside => { const nav = document.querySelector('nav[role="navigation"]'); if (inside) nav.querySelector('a[href]').focus(); else document.querySelector('button')?.focus(); [...document.querySelectorAll('button')] .find(b => !nav.contains(b) && /sidebar/i.test(b.getAttribute('aria-label') || '')) .click(); }, focusInside); await page.waitForTimeout(400); const after = await read(); const commits = await page.evaluate(() => window.__commits); row(label, { layout: after.layout - before.layout, recalc: after.recalc - before.recalc, navMutations: commits.length, detail: JSON.stringify(commits), }); await browser.close(); } (async () => { await cycle('core-sidenav--hidden-collapse', 'N=1 focus INSIDE ', true); await cycle('core-sidenav--hidden-collapse', 'N=1 focus OUTSIDE', false); await cycle('scratch-sidenav3890--two-navs-shared', 'N=2 focus OUTSIDE', false); })().catch(e => {console.error(e); process.exit(1);});