perf(Typography): skip Tooltip render when text is not overflowing - #3424
perf(Typography): skip Tooltip render when text is not overflowing#3424rivka-ungar wants to merge 1 commit into
Conversation
Avoid mounting Tooltip (and its 49+ hooks via Dialog) on every Text/Heading element by only rendering the wrapper when overflow is actually detected. Additionally skip the ResizeObserver entirely when withoutTooltip=true. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PR Summary by Qodoperf(typography): avoid Tooltip/ResizeObserver when ellipsis isn’t overflowing
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo
1. Stale overflow after re-enable
|
| ) { | ||
| const isOverflowing = useIsOverflowing({ | ||
| ref: ellipsis ? ref : null, | ||
| ref: ellipsis && !withoutTooltip ? ref : null, |
There was a problem hiding this comment.
1. Stale overflow after re-enable 🐞 Bug ≡ Correctness
useTooltipProps now passes null to useIsOverflowing when withoutTooltip=true, which stops the ResizeObserver and can leave isOverflowing at its previous value. If withoutTooltip later flips back to false after layout/content changes, Typography can briefly make the wrong tooltip decision until the first ResizeObserver callback runs.
Agent Prompt
### Issue description
`useTooltipProps` disables overflow observation by passing a `null` ref into `useIsOverflowing` when `withoutTooltip=true`. Because `useIsOverflowing` stores overflow in React state and only updates it via the ResizeObserver callback, disabling the observer can leave a stale `isOverflowing` value that is reused when tooltips are re-enabled.
### Issue Context
This is most visible when `withoutTooltip` is toggled at runtime (e.g., responsive UI, user preference toggles) and the element’s overflow state changes while observation is disabled. On re-enable, Typography may mount (or not mount) Tooltip for one render based on stale overflow state.
### Fix Focus Areas
- packages/components/typography/src/Typography/TypographyHooks.tsx[34-40]
- packages/hooks/src/useIsOverflowing/index.ts[36-53]
### Suggested fix approach
Update `useIsOverflowing` to explicitly handle a missing/disabled ref by resetting overflow to `false` when `ref` is falsy or when `ref.current` is not available, so re-enabling observation starts from a consistent state. This preserves the perf optimization while avoiding transient incorrect tooltip decisions.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
📦 Bundle Size Analysis ✅ No bundle size changes detected. Unchanged Components
📊 Summary:
|
Motivation
Every
TextandHeadingelement (which both go throughTypography) unconditionally rendered a<Tooltip>wrapper even when the text was not overflowing,withoutTooltip=true, orellipsis=false. BecauseTooltipmountsDialoginternally — which carries ~49 hooks — a page with 50–100 text elements paid that cost on every render even though no tooltip was ever needed.This is a follow-up to #3416 (Tooltip early-return optimisation) and applies the same principle at the Typography layer.
Changes
Typography.tsxbaseElement).overrideTooltipProps.contentis falsy (no overflow detected,withoutTooltip=true,ellipsis=false, etc.) return the element directly — no Tooltip mount.<Tooltip>.TypographyHooks.tsxuseTooltipProps, theuseIsOverflowingcall now passesref: ellipsis && !withoutTooltip ? ref : null. Previously aResizeObserverwas created wheneverellipsis=true, even whenwithoutTooltip=truemade the result irrelevant. This eliminates that unnecessary observer.Safety
overrideTooltipProps.content, which is only truthy whenuseTooltipPropsreturns{ ...tooltipProps, content: children }— i.e. when!withoutTooltip && ellipsis && isOverflowing.Test plan
yarn workspace @vibe/typography test— all 20 tests greenText/Heading, verify ellipsis tooltip still appears when text is long enough to overflow🤖 Generated with Claude Code