[tooltip] Preventing from unnecessarily rerendering the children component
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 99.1k
- Forks
- 32.5k
- Avg merge
- 2d 17h
- Merged PRs (30d)
- 106
Description
Summary
This RFC concerns the React Tooltip component and potential performance issues.
Problem
The React Tooltip component unnecessarily rerenders the provided children component ~2-3 times on initial Tooltip render and every time the tooltip's visibility state toggles.
Cause
There are a considerable number of code paths leading up to the final cloneElement call here that create a large number of new references. This leads to the observed unnecessary rerendering behavior.
Experimentation
I have tested this and confirmed that Tooltip indeed causes the children component to unnecessarily render at least 2-3 additional times.
As a PoC, I have also tested with a reduced-complexity (but-otherwise like-for-like) Tooltip component that proves that leveraging React memoization utils eliminates the problem. For example, the ultimate cloneElement call ends up looking something like this:
I do not however possess the resources to delve any deeper into this (e.g. in-depth perf benchmarks). Apologies.
Open Questions
- Would the (likely significant) refactors be worth-it?
- Would the performance gain of less
childrenrenders outweigh the performance loss of memoization?
What are the requirements?
Zero unnecessary rerenders of the provided children component.
What are our options?
With my current understanding, there is only one accepted way to achieve this - refactor Tooltip to use React memoization utils to prevent childrenProps from being a new reference or containing new references.
Proposed solution
The crux of the solution is to extract out the cloneElement call and place it inside a useMemo call with the properties of childrenProps as the memoization dependencies.
This may require some additional uses of useCallback in order to ensure the event handler functions such as handleEnter and onMouseEnter are not new references.
Resources and benchmarks
N/A
Search keywords: tooltip, react, performance, memoization
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/mui-material/src/Tooltip/Tooltip.js around the final cloneElement call at line 668. Profile the Tooltip's initial render and visibility toggles, then evaluate whether memoization changes prevent unnecessary children renders without creating a larger performance cost; done means meeting the stated zero-unnecessary-rerenders requirement with supporting benchmarks.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react
- Domain
- frontend, performance
- Issue type
- Refactor
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100