plotly / plotly/dash

Switching back and forth between dcc.Tabs doesn't seem to release memory in the browser

Open
#2,882 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P3 sev-2
Dominant language
Python
Stars
24.4k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
13

Description

In a dash app with a 50 000 point scatter chart in tab 1 and another in tab 2, switching back and forth between those tabs increases the memory footprint that I see in the Chrome task manager by about 100 MB every time but it doesn't look like any gets released.

Screenshot from 2024-06-11 12-12-08

In the snapshot above, the memory footprint has climbed to 1.5 GB. Within a few minutes of not using the app it dropped, but only to 1 GB so it's still way higher than it was before I'd interacted with it.

Also, it looks like others in the community have seen something similar.

Describe your context
Please provide us your environment, so we can easily reproduce the issue.

  • replace the result of pip list | grep dash below
dash                            2.17.0
dash-ag-grid                    2.1.0
dash-bio                        1.0.2
dash-bootstrap-components       1.4.2
dash-bootstrap-templates        1.1.2
dash-chart-editor               0.0.1a4
dash-core-components            2.0.0
dash-cytoscape                  0.3.0
dash-dangerously-set-inner-html 0.0.2
dash-design-kit                 1.10.0
dash-embedded                   2.14.0
dash-enterprise                 1.0.0
dash-enterprise-auth            0.1.1
dash-enterprise-libraries       1.4.1
dash-extensions                 0.1.6
dash-facebook-login             0.0.2
dash-gif-component              1.1.0
dash-html-components            2.0.0
dash-iconify                    0.1.2
dash-mantine-components         0.12.1
dash-notes                      0.0.3
dash-renderer                   1.9.0
dash-snapshots                  2.2.7
dash-table                      5.0.0
dash-user-analytics             0.0.2
  • if frontend related, tell us your Browser, Version and OS

    • OS: Unbuntu 22.04
    • Browser Chrome
    • Version 122

Example app:

import dash
from dash import dash_table
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objs as go
import numpy as np
import pandas as pd

# Data generation for plots and table
np.random.seed(42)  # for reproducibility
x = np.linspace(0, 10, 50000)
y1 = np.random.randn(50000)
y2 = np.sin(x) + np.random.randn(50000) * 0.2

table_data = pd.DataFrame(np.random.randn(10, 4), columns=list("ABCD"))

# App initialization
app = dash.Dash(__name__)
server = app.server

# Layout
app.layout = html.Div([
    dcc.Tabs(id="tabs", value='tab-1', children=[
        dcc.Tab(label='Scatter Plot 1', value='tab-1'),
        dcc.Tab(label='Scatter Plot 2', value='tab-2'),
        dcc.Tab(label='Data Table', value='tab-3'),
    ]),
    html.Div(id='tabs-content')
])

# Callback to update tab content
@app.callback(Output('tabs-content', 'children'),
              Input('tabs', 'value'))
def render_content(tab):
    if tab == 'tab-1':
        return dcc.Graph(
            id='scatter-plot-1',
            figure={
                'data': [go.Scatter(x=x, y=y1, mode='markers')],
                'layout': go.Layout(title='Scatter Plot 1')
            }
        )
    elif tab == 'tab-2':
        return dcc.Graph(
            id='scatter-plot-2',
            figure={
                'data': [go.Scatter(x=x, y=y2, mode='markers')],
                'layout': go.Layout(title='Scatter Plot 2')
            }
        )
    elif tab == 'tab-3':
        return html.Div([
            html.H4('Data Table'),
            dash_table.DataTable(
                data=table_data.to_dict('records'),
                columns=[{'name': i, 'id': i} for i in table_data.columns]
            )
        ])

if __name__ == '__main__':
    app.run_server(debug=False)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Run the supplied Python example app and reproduce the memory increase by switching between dcc.Tabs values. Start at the tabs-content callback and its render_content entry point, then use Chrome task manager while switching tabs repeatedly. Done means repeated tab switching no longer leaves the browser memory footprint continually elevated.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, react
Domain
data-visualization, frontend, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.