Skip to content

Serious performance issues related to React context #3057

Closed
@CNFeffery

Description

@CNFeffery

When using components associated with the XxxProvider, severe performance issues can arise when there is a large amount of page content. Here are some examples related to well-known component libraries in the Dash ecosystem:

  • with dmc

In dmc, it is required that the application be wrapped inside the MantineProvider. With the React Developer Tools, you can see that any interaction with an internal component will trigger a re-render of all components on the current page.
Image

import dash_mantine_components as dmc
from dash import Dash, _dash_renderer

_dash_renderer._set_react_version("18.2.0")

app = Dash(external_stylesheets=dmc.styles.ALL)

app.layout = dmc.MantineProvider([dmc.Button("test", style={"margin": 5})] * 200)

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

Even placing components from dcc under the MantineProvider will cause the same issue:
Image

import dash_mantine_components as dmc
from dash import Dash, _dash_renderer, dcc

_dash_renderer._set_react_version("18.2.0")

app = Dash(external_stylesheets=dmc.styles.ALL)

app.layout = dmc.MantineProvider([dcc.Input(style={"margin": 5})] * 200)

if __name__ == "__main__":
    app.run(debug=True)
  • with fac

In fac, the similar component AntdConfigProvider is not a must-use, but the same issue will also occur:
Image

import dash
from dash import html
import feffery_antd_components as fac

app = dash.Dash(__name__)

app.layout = html.Div(
    fac.AntdConfigProvider(
        [fac.AntdButton("test", type="primary", style={"margin": 5})] * 100
    )
)

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

However, the issue of global re-rendering does not occur with components within html, such as for html.Div (which has the functionality to update the click event to the component's n_clicks property):

  • with dmc
import dash_mantine_components as dmc
from dash import Dash, _dash_renderer, html

_dash_renderer._set_react_version("18.2.0")

app = Dash(external_stylesheets=dmc.styles.ALL)

app.layout = dmc.MantineProvider(
    [html.Div(style={"height": 25, "border": "1px solid black", "marginBottom": 5})]
    * 100
)

if __name__ == "__main__":
    app.run(debug=True)
  • with fac
import dash
from dash import html
import feffery_antd_components as fac

app = dash.Dash(__name__)

app.layout = html.Div(
    fac.AntdConfigProvider(
        [html.Div(style={"height": 25, "border": "1px solid black", "marginBottom": 5})]
        * 100
    )
)

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

I hope to receive more help on this issue, to explore the deeper reasons and possible solutions.

Metadata

Metadata

Assignees

Labels

P1needed for current cycleperformancesomething is slow

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions