Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tooltip] Performance issue when lots of tooltips are used in a table #27057

Closed
2 tasks done
cmacdonnacha opened this issue Jul 1, 2021 · 9 comments
Closed
2 tasks done
Labels
component: tooltip This is the name of the generic UI component, not the React module! performance status: expected behavior Does not imply the behavior is intended. Just that we know about it and can't work around it

Comments

@cmacdonnacha
Copy link

It seems like adding the <Tooltip> component in my table cells is causing some performance issues. I've used React Profiler to debug this and it's pointing to Popper as taking up the most rendering time which I believe is what MUI uses for tooltips. Also, when I used the Chrome performance debugging tool I can see the blocking time is 3 times bigger when using Tooltips.

  • The issue is present in the latest release.
  • I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 😯

Table becomes laggy when tooltips are used.

Expected Behavior 🤔

Table remains performant when tooltips are used.

Steps to Reproduce 🕹

This isn't an exact demo of my own use case, I just forked one of the demos, but it shows how the Tooltips slow things down when clicking on "Select all" checkbox. In my own use case the performance hit is a bit more severe as I'm filtering the table at the same time.

With tooltips: https://codesandbox.io/s/material-demo-forked-fs4zu?file=/demo.tsx:10280-10308
Without tooltips: https://codesandbox.io/s/material-demo-forked-wkdkk?file=/demo.tsx:11145-11234

Steps:

  1. Click the "select all" checkbox in left top

Context 🔦

I have a table with 50 rows and 9 columns, each cell has an icon and tooltip. When I filter the table it's very laggy but once I remove the tooltips it's perfectly fine.

Your Environment 🌎

  System:
    OS: macOS 11.4
  Binaries:
    Node: 14.15.5 - ~/.nvm/versions/node/v14.15.5/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.11 - ~/.nvm/versions/node/v14.15.5/bin/npm
  Browsers:
    Chrome: 91.0.4472.114
  npmPackages:
    @material-ui/core: ^4.11.3 => 4.11.3 
    @material-ui/icons: ^4.11.2 => 4.11.2 
    @material-ui/styles:  4.11.3 
    @material-ui/system:  4.11.3 
    @material-ui/types:  5.1.0 
    @material-ui/utils:  4.11.2 
    @types/react: ^17.0.3 => 17.0.3 
    react: ^17.0.1 => 17.0.1 
    react-dom: ^17.0.1 => 17.0.1 
    typescript: ^4.2.3 => 4.2.3 
@cmacdonnacha cmacdonnacha added the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Jul 1, 2021
@cmacdonnacha
Copy link
Author

cmacdonnacha commented Jul 1, 2021

I also noticed that the blocking time is reduced if I use a simple <span>

<Tooltip title="Person status">
   <span>{person?.status}</span>
</Tooltip>

instead of an Icon:

<Tooltip title="Person status">
   <CheckCircle />
</Tooltip>

I'm guessing a more complex child causes the rendering time to increase? The blocking time goes from 1577ms down to 457ms when I remove tooltips completely.

@michal-perlakowski
Copy link
Contributor

Performance is similar in V5: https://codesandbox.io/s/material-demo-forked-etgwf?file=/demo.tsx

@cmacdonnacha
Copy link
Author

Replacing md-tooltip with react-tooltip actually brought the blocking time from 1557ms down to 437ms so it must be something to do with Popper. I'd obviously rather not install another tooltip package though.

@mnajdova mnajdova added component: tooltip This is the name of the generic UI component, not the React module! performance and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Jul 8, 2021
@oliviertassinari
Copy link
Member

oliviertassinari commented Jul 14, 2021

@cmacdonnacha Do you benchmark in development or production? I would suspect the difference of performance between md-tooltip and react-tooltip to come from emotion. If this is confirmed, then it could be relevant for dev that extreme performance to use the unstyled version of the tooltip: mui/base-ui#10 + plain CSS.
Otherwise, you could virtualize the list. Maybe it could help.

@oliviertassinari oliviertassinari changed the title [md-tooltip] - Performance issue when lots of tooltips are used in a table. [Tooltip] Performance issue when lots of tooltips are used in a table. Jul 14, 2021
@oliviertassinari oliviertassinari changed the title [Tooltip] Performance issue when lots of tooltips are used in a table. [Tooltip] Performance issue when lots of tooltips are used in a table Jul 14, 2021
@cmacdonnacha
Copy link
Author

Hey @oliviertassinari I benchmark in dev while debugging but also tried production. In dev the blocking time was 1557ms and in production it was 472ms which is much better but there's still a noticeable lag to the human eye when filtering a table with 50 rows and 9 columns (450 tooltips). The unstyled version sounds good, is this something that I can try out or is it in progress?

@oliviertassinari
Copy link
Member

oliviertassinari commented Jul 14, 2021

For unstyled, @michaldudak is leading the effort in mui/base-ui#10, we accept contributions from the community.

Now, the demo renders 1,600 tooltips. We have never designed the component for this amount of instances, and I don't think that we should start either now. 500 is about the limit we consider valid. You can check our data grid component that implements virtualization and memorization to make this use case fast. I'm actually surprised that you didn't face an issue with the table component too.

I have also opened #27290 as from what I can benchmark, we also spend time on the <Table*> components.

@oliviertassinari oliviertassinari added status: expected behavior Does not imply the behavior is intended. Just that we know about it and can't work around it out of scope The problem looks valid but we won't fix it (maybe we will revisit it in the future) and removed out of scope The problem looks valid but we won't fix it (maybe we will revisit it in the future) labels Jul 14, 2021
@cmacdonnacha
Copy link
Author

No problem thanks, switching to react-tooltip did the trick to be honest to we're happy enough. Popper must be a lot heavier. We have pagination where the user can choose between 15, 30 and 50 rows and it now performs well even at 50. Thanks for taking the time 👍

@enoh-barbu
Copy link

enoh-barbu commented Dec 2, 2021

The problem is that tooltip should be rendered only on mouse over/enter

I wrote for myself a wrapper component

import { useState } from 'react';
import Tooltip, { TooltipProps } from '@mui/material/Tooltip';

export default function CustomTooltip({ children, ...rest }: TooltipProps) {
    const [renderTooltip, setRenderTooltip] = useState(false);

    return (
        <div
            onMouseEnter={() => !renderTooltip && setRenderTooltip(true)}
            className="display-contents"
        >
            {!renderTooltip && children}
            {
                renderTooltip && (
                    <Tooltip {...rest}>
                        {children}
                    </Tooltip>
                )
            }
        </div>
    );
}

@s-mahdi
Copy link

s-mahdi commented Dec 14, 2021

I used controlled tooltip to solve this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: tooltip This is the name of the generic UI component, not the React module! performance status: expected behavior Does not imply the behavior is intended. Just that we know about it and can't work around it
Projects
None yet
Development

No branches or pull requests

6 participants