Every `Tip` carried its own `TooltipProvider`, and there are ~107 call
sites. Each is a subtree that re-renders when anything above it does, so
they dominated unrelated interactions: 52,784 TooltipProvider renders and
18.3s of component time in a single sash drag.
Radix's provider holds only refs and stable callbacks (no reactive state)
— hoisting one to the app root is what it is designed for. `Tooltip`
still reads delayDuration/disableHoverableContent from context, and the
per-Tip overrides are preserved.
`Tip` keeps a local provider as a FALLBACK, chosen by context: a
component rendered in isolation has no root provider and Radix throws
"`Tooltip` must be used within `TooltipProvider`". Without this, 20 unit
tests that render a single control fail. Inside the app the flag is
always true, so the common path is a bare Tooltip.
This is the shape the earlier lazy-mount attempt should have taken. That
one deferred the Radix subtree until hover, which moved
data-slot="tooltip-trigger" off the mounted DOM and broke 18 tests
encoding that contract. Hoisting keeps the contract intact — every one of
those tests passes unchanged.
Measured on the same drag:
TooltipProvider 52,784 renders / 18.3s -> gone from the table
Primitive.div 40.5s -> 13.4s
Popper 10.5s -> 2.7s
Tooltip 15.7s -> 4.4s