perf(panel): an empty toast stack measures nothing on every draw

Merged
CH
9d ago
+5-0

This is a follow-up to #4296, found by the profile Charles asked for after it merged.

The problem: useStackGlide in toast.tsx runs a useLayoutEffect with no dependency list. After every draw of the toast stack it reads --duration-fast and --spring-fast through getComputedStyle, plus every toast's box. Each read forces a style or layout pass over the whole window, and it happens even though the stack is nearly always empty.

The evidence: a 15 s profile of the panel at rest on bae007ad2, which includes #4296, put 203 ms in getPropertyValue from toast.tsx:401. That is about a fifth of the main thread's busy time in that window, and the cost grows with the size of the DOM.

The fix: an empty stack now returns before reading anything. A stack with toasts in it glides as before.

The behavior doesn't change. The existing toast tests pass, and I added none, since all that changes is the work done.

I swept packages/panel and packages/ui for other useLayoutEffect calls with no dependency list that read layout. The rest already return early when they have nothing to do: plan comments with no threads, a reveal that isn't pending, a combobox with no active row.

Made with Luke


Devin Review