dash icon indicating copy to clipboard operation
dash copied to clipboard

[BUG] Regressed rendering performance in MantineProvider after Dash 3.x / DMC 2.x upgrade

Open DavidKatz-il opened this issue 1 month ago • 6 comments

Describe the bug

After upgrading Dash 2.18.2 to 3.2.0 and Dash Mantine Components (DMC) 0.12.0 to 2.3.0, I noticed a significant slowdown when using MantineProvider.

In DMC 0.12.0, the app ran exceptionally fast without MantineProvider, with an INP of around 50–60 ms. However, when I added MantineProvider in the same version, performance plummeted sharply, reaching 600–700 ms. After upgrading to DMC 2.x, performance improved significantly, dropping to approximately 120 ms. However, it still lags behind the original setup without MantineProvider.

Unfortunately, MantineProvider is now mandatory in the latest versions.

As mentioned in the issue here, it appears to be an upstream issue, possibly related to the dash_renderer.

Could you please provide an update on whether there’s a plan to fix this issue? If not, could you suggest a workaround or offer some insights into the potential source of the problem?

Thanks

DavidKatz-il avatar Nov 12 '25 12:11 DavidKatz-il

@DavidKatz-il thanks for submitting this. We're always looking into opportunities to optimize the dash_renderer and would love contributions in that space! Unfortunately we aren't able to prioritize this in the immediate future; but would be happy to review any pull requests addressing the issue.

robertclaus avatar Nov 12 '25 17:11 robertclaus

@robertclaus

Thanks for the quick answer! Do you have any suggestions or guidance on where I should begin?

DavidKatz-il avatar Nov 12 '25 17:11 DavidKatz-il

Hello @DavidKatz-il,

I originally had the same issue with MantineProvider, thus I was stuck at 0.12 for a very long time until Dash 3 came out. I put a lot of effort into making it so that DMC would be usable on lower end computers. You can see my findings here in this chain:

https://discord.com/channels/932931236882677780/1129886616605949952

The "fix" was to making it so components only listen for updates to it explicitly, or in some cases listen to children updates (in the event that the parent needs to rerender, eg tabs, switches)

I ran your example with both 2.18.2 and 3.3.0 and the display time was similar. Again, this stems from an issue with MantineProvider.

To see the real difference between the two, check this example where you start trying to update version 2.18.2 vs 3.3.0, in 2.18.2 the entire dom tree rerenders with each key stroke.

import dash
from dash import html, _dash_renderer
import dash_mantine_components as dmc

_dash_renderer._set_react_version('18.2.0')

def create_deeply_nested_card(i):
    return dmc.Card(
        dmc.Stack([
            dmc.Group([
                dmc.Stack([
                    dmc.Paper(
                        dmc.Group([
                            dmc.Tooltip([
                                dmc.Paper(
                                    dmc.Group([
                                        dmc.Stack([
                                            dmc.Text(f"Card {i}", size="lg", fw=700),
                                        ]),
                                    ]),
                                ),
                            ], label=f"This is Card #{i}"),
                        ]),
                    ),
                ]),
            ]),
            dmc.Paper(
                dmc.Tooltip([
                    dmc.Stack([
                        dmc.Paper(
                            dmc.Group([
                                dmc.Stack([
                                    dmc.Paper(
                                        dmc.Chip(
                                            "Toggle Me",
                                            variant="filled",
                                            id={'type': 'switch', 'index': i},
                                            size="md",
                                        ),
                                    ),
                                ]),
                            ]),
                        ),
                    ]),
                ], label=f"This is Toggle #{i}"),
            ),
            dmc.Paper(
                dmc.Tooltip([
                    dmc.Stack([
                        dmc.Paper(
                            [
                                dmc.Badge(f"BADGE {i}", id={'type': 'badge', 'index': i}, color="red"),
                                dmc.TextInput()
                            ]
                        ),
                    ]),
                ], label=f"This is BADGE #{i}"),
            ),
        ]),
        shadow="sm",
        withBorder=True,
        style={'marginBottom': '5px'}
    )


app = dash.Dash(__name__)
app.layout = dmc.MantineProvider(
    dmc.AppShell([
        dmc.Container([
            html.Div([create_deeply_nested_card(i) for i in range(1000)]),
        ])
    ])
)

if __name__ == "__main__":
    app.run(debug=False)

BSd3v avatar Nov 13 '25 15:11 BSd3v

Also wanted to thank the Plotly team for the work that's already been done to address this issue. There was a huge performance boost in Dash 3. https://github.com/plotly/dash/issues/3057

AnnMarieW avatar Nov 13 '25 16:11 AnnMarieW

@BSd3v Thanks for the detailed explanation.

As I mentioned in the dash-mantine issue, I noticed that updating Dash indeed improves performance when using MantineProvider. However, in version 0.12, I didn’t need to use MantineProvider, and the app still runs faster than it does with Dash 3 and MantineProvider enabled.

To clarify, loading time isn’t the concern, it’s actually better now, even compared to 0.12 without MantineProvider. The issue lies with the INP when clicking on a chip (as shown in the example). That’s where the performance difference becomes noticeable.

Thanks again to you and the whole team for the great work on Dash and Dash Mantine.

DavidKatz-il avatar Nov 13 '25 16:11 DavidKatz-il

@DavidKatz-il,

I see the issue when I slow down the CPU, I also narrowed this down to the new Chip component having the ChipGroupContext.

^ nevermind, its not consistent...

Anyways, here is a base level comparison with react native https://codesandbox.io/p/sandbox/quizzical-carson-jxrc2f

With comparing, I got when toggling: Dash 72 - 120 ms React 16 - 64 ms

BSd3v avatar Nov 13 '25 17:11 BSd3v