[BUG] Regressed rendering performance in MantineProvider after Dash 3.x / DMC 2.x upgrade
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 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
Thanks for the quick answer! Do you have any suggestions or guidance on where I should begin?
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)
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
@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,
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