mui / mui/material-ui

[material-ui][Dialog][Tooltip] Improve performance with lots of elements

Open
#27,879 1 comment 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

performance scope: modal scope: tooltip
Dominant language
JavaScript
Stars
99.1k
Forks
32.5k
Avg merge
2d 17h
Merged PRs (30d)
106

Description

  • I have searched the issues of this repository and believe that this is not a duplicate.

Summary 💡

Adding / removing children to / from the HTML body causes the browser to recalculate the children of the body. With many elements this can have a noticeable performance impact.

Temporary elements should be created in a permanent child of body.

Examples 🌈

This is a contrived example where we're rendering 10000 button elements in the body.
You can clearly see the performance impact on opening the modal dialog.

Bad:
Just use the dialog normally, it will be rendered as direct child of the body.
Opening the modal dialog takes >600ms.
image

Good:
A custom div in the body that is used as container of the dialog.

Opening the modal dialog takes ~65ms.
image

This problem also affects other elements based on the Dialog component, e.g. the Drawer.

This problem could also affect the Tooltip component, though after a quick test I wasn't able to see any notable performance improvements (see this demo).

Note: it seems like chrome (firefox not so much) can handle this if the 10000 buttons are nested (see this demo where the buttons are wrapped in a div).

Motivation 🔦

I just read this blog post by @atfzl (thx btw!) about performance pitfalls for children of body. I was wondering if this could affect the material-ui components as well.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing how Dialog, Drawer, and Tooltip choose their container and where their temporary elements are attached relative to the HTML body. Reproduce the linked CodeSandbox examples with many buttons, then compare the default and custom-container cases. Done means opening the affected components no longer incurs the reported body-child performance cost while retaining their existing behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react
Domain
frontend, performance
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.