Open popes01a opened 5 years ago
I'm having the same issue. Updating big html tables has got considerably slower since after 0.40. I had to roll back to 0.40 for now.
@popes01a thanks for the elaborated examples for performance issues. there is a major change around 0.40.0 in dash-renderer about the react component hierachy, extra props-check might adds few latency, we will investigate this furthermore.
Few suggestions you can do before that:
children += [html.Tr([html.Td('Label '), html.Td(html.A('?action=enable'))]) for _ in range(800)]
will save about 2 seconds from backend. Same issue when I upgraded. My render time went from 0.17 seconds to 3 .1 seconds. Simple tabular data page with 20+ callbacks. Rolled back to 0.40.0 and running fine but major functionality roll back also.
Belated thanks @popes01a for the very clear investigation and report. We will try to dig into this for the next release - which is also expected to reduce the need for these big explicit html.Table
components by allowing links and images in dash-table
but there will of course always be cases that warrant large explicit layouts of one form or another.
I have switched to using a Dropdown
and a Continue
button to trigger the action for now, but links inside a dash-table
component would be ideal. Looking forward to the release!
Testing out multiple versions of Dash with code modified from example 2 (multi-output was added in 0.39) and to avoid React warnings.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash()
options = list({'label': 'City %d' % i, 'value': 'city-%d' % i} for i in range(10))
children = []
for i in range(5):
children.extend([
html.Label('Multi-Select Dropdown'),
dcc.Dropdown(id='dropdown-%d' % i, options=options, value=['city-0', 'city-1'], multi=True),
])
rows = [html.Tr([
html.Td('Label'),
html.Td(html.A('?action=enable'))
])] * 800
children += [html.Table([html.Tbody(rows)])]
app.layout = html.Div(children)
for i in range(4):
@app.callback(
Output('dropdown-%d' % (i + 1), 'options'),
[Input('dropdown-%d' % i, 'value')])
def update_options(value):
return options
@app.callback(
Output('dropdown-%d' % (i + 1), 'value'),
[Input('dropdown-%d' % i, 'value')])
def update_options(value):
return value
if __name__ == '__main__':
app.run_server(debug=False)
I get the following times for debug=False and dropdown count=5, average of 3 runs.
Dash version | Network ready | CPU time |
---|---|---|
0.35 | 6.67s | 9.44s |
0.40 | 2.14s | 3.27s |
0.42 | 6.57s | 8.60s |
1.7.0 | 7.24s | 9.36s |
Looks like 0.35, 0.42, 1.7.0 all have similar performance and 0.40 stands on its own. Will look into running the perf test against more versions and looking more deeply into what's happening during render that would explain the performance differences.
I've played around with the latest version of dash, and I don't notice the performance issue I was experiencing with 0.41.0+ any more. Maybe this issue has been solved somehow?
dash==1.13.3
dash-html-components==1.0.3
@arthurandres great! We did improve performance a bunch in #1254 - @Marc-Andre-Rivet when you're back you can extend the table above, and perhaps close this issue?
We recently switched to a newer Dash version and noticed our application got considerably slower. While in Dash v0.40.0 it usually took ~20s for a page to load, in the newer versions this goes up to ~55s, or even 90s depending on the browser.
After some digging, it turns out that having a plain HTML table built using
dash-html-components
considerably slows the page down. We cannot use adash-table
in this case as we need links inside the table.There is a considerable difference between v0.40.0 and all versions released after, so I'm assuming that whatever is slowing this down was added in v0.40.0. Page load timings for different
dash
versions and the code examples can be found below.Any ideas why this became an issue and what can be done to fix this? Thanks!
Example 1:
Example 2: