Slow Callsback on Multipage App/Refreshing with every change

I recently decided to turn my app into a multi page app which consists currently of only two pages.

I have the site hosted on pythonanywhere and it has the following folder structure:

- app.py 
-navbar.py
- pages    
       |-- page1.py
       |-- page2.py
- assets
       |-- style.css

The app is a dataframe viewer which usually consists of ~85000 rows
Using callbacks i added dropdown and rangeslider components to filter the dataframe.

When i was using a flat project structure before with only page being app.py the app was very responsive and fast. Now when i load the site it almost flickers and almost fully reloads on every callback firing. I’m using the “use_pages” function.

ezgif.com-video-to-gif-converted

Is there any way to prevent this or speed it up. The callback is mainly the culprit here.
Or should i switch to something like AG Grid and use it’s native filtering options

Well, that’s annoying!

Can you show how your callbacks are working? It appears the entire page is refreshing, rather than just the components on the page that need to be updated.

1 Like

It appears the entire page is refreshing

Unfortunately yes.

The Callback is simple and a bit messy.

@callback(
    Output(my_table, 'data'),
    Output(my_table, 'page_size'),
    Input(drop1, 'value'),
    Input(drop2, 'value'),
    Input(drop3, 'value'),
    Input(slider1, 'value'),
    Input(slider2, 'value'),
    Input(slider3, 'value'),
    Input(slider4, 'value'),
    Input(slider5, 'value'),
    Input(slider6, 'value'),
    Input(slider7, 'value'),
    Input(slider8, 'value'),
    Input(slider9, 'value'),
    Input(drop4, 'value'),
    Input(drop5, 'value'),
    Input(row_drop, 'value'),

)

def update_dropdown_options(scr1, scr2,scr3,scr4, scr5, scr6,scr7,
                            scr8,scr9,dta1,dta2,dta3,dta4, row_v):
    dff = df.copy()


    if cont_v:
        dff = dff[dff.symbol.isin(scr1)]
    if country_v:
        dff = dff[dff.expiration.isin(scr2)]
    if type_v:
        dff = dff[dff.optionType==scr3]

    dff = dff[(dff['DTE'] >= scr4[0]) & (dff['DTE'] < scr4[1])]
    dff = dff[(dff['Last Price'] >= scr5[0]) & (dff['Last Price'] < scr5[1])]
    dff = dff[(dff['% Day Change'] >= scr6[0]) & (dff['% Day Change'] < scr6[1])]
    dff = dff[(dff['Bid'] >= scr7[0]) & (dff['Bid'] < scr7[1])]
    dff = dff[(dff['Ask'] >= scr8[0]) & (dff['Ask'] < scr8[1])]
    dff = dff[(dff['Mark'] >= scr9[0]) & (dff['Mark'] < scr9[1])]
    dff = dff[(dff['BE'] >= dta1[0]) & (dff['BE'] < dta1[1])]
    dff = dff[(dff['Ptnl Rtn'] >= dta2[0]) & (dff['Ptnl Rtn'] < dta2[1])]


    if dta8:
        dff = dff[dff.Sector.isin(dta3)]
    if dta9:
        dff = dff[dff['Contract Time']==dta4]

    return dff.to_dict('records'), row_v

Hi @mvnchi

I don’t think that callback is making the whole page refresh. There must be something else that’s triggering the refresh.

1 Like

Hello @mvnchi,

Could this possibly be from dcc.Loading? That looks like something it would do.

If so, check out my topic about having the spinner show only when loading the page initially.

2 Likes

Yes @jinnyzor has a great suggestion! Another option is to put the dcc.Loading on the table only.

However, I think the best solution would be to us Dash AG Grid :tada:

2 Likes

Thank you both for looking into it and your suggestions!

dcc.Loading() really was the cause. I have removed it for now but will look into your topic.

1 Like