Black Lives Matter. Please consider donating to Black Girls Code today.

Page is slow with multiples callbacks

is there a way to preload all callbacks in a page? I have two pages in my dash app, one of them have many callbacks and is slow when i want load it. Every time i load that page all callbacks is called and this produce slow load.

Is it possible to avoid callbacks fire when I load a page?

No, this has been a long requested feature but as far as I’m aware still not possible. There is however a mitigation strategy:

  1. Load your layout via a layout function, e.g. app.layout = get_layout where get_layout is a function that gets your layout with all the details pre-loaded

  2. Set your callbacks to return dash.no_update or raise dash.exceptions.PreventUpdate on page load (usually when all your inputs are None)

  3. Leverage multi-output callbacks where ever possible. You can usually significantly reduce the number of callbacks you have by creating callbacks that have multiple outputs. In some cases this logically makes sense and makes your application code simpler, in some cases it leads to “monolithic callbacks” that stuff lots of unrelated logic together just for the sake of performance, so try to find all use cases of the former before resorting to the latter.

I have many callbacks, so, return PreventUpdate in all of them take the same time that return other value and i dont want to join all callblacks in one.

it would be -> raise PreventUpdate (if you have 3 outputs, it would still be only a single raise PreventUpdate) that prevents update for All outputs,
but if you want to say return an output for 2 of them, then it would be of this sort -> [return no_update, no_update, …]

if the callbacks do share the same outputs then i believe it is necessary to bundle all into a single callback, and use the callback triggered context to identify the component that triggered it, and then multiple if statements for each button type with no_update for the not relevant outputs is the way to go i believe

My application has more than 100 filter data range sliders and each of the callbacks has as input the value of the slider and as output the children of a label to see the range and be able to update it. So I don’t want to join all callbacks in one with all the inputs and all the outputs. Separating on different callbacks is faster but slower every time I load the page. When I change the page and return to the same page, all callbacks are reloaded.

So, I would like to load all callbacks only once, and not reload them all when you select another page and return.

for something similar for me what i did is

  • basically have a hidden dummy button on page layout (at the start)
  • a dcc.Store defined at the initial index page layout with session or local storage type
  • the button nclicks callback is triggered first when the page loads
  • store some dummy value in the store in some initial callback on the page
  • now you can use a combination of the dummy button being triggered and if the store is None or not to basically differentiate between landing on the page for the first time versus returning to it from another page
  • so for the case when returning to the page you can just raise a PreventUpdate on all (assuming you can set the components with persistence True and type being local perhaps)
    • of course again this is easier if you have a single callback with all the filters. since you have 100 i would recommend naming them with a convention like prop-i (for i from 1 to 100)
    • and for the callback you can refer to them like this
@app.callback([Output(f"prop-{i}", "value") for i in range(100)],
              [Input('dummy-btn', 'n_clicks'), Input('dummy-store', 'data')])
def return_prop_values(n, store):
    ... (conditions)
    raise PreventUpdate

I have an app with over 1’000 callbacks, returning a value can create a visual disturbance / interfere with the user, where as PreventUpdate means there is no interference with whatever the user is doing, so the UI experience is dramatically different.

As far as I’m aware at the moment the only strategy to have less calls at page layout time is to have less server callbacks overall. And the only ways I know how to have less server callbacks overall with Dash are: 1) Merge server side callbacks, 2) Client side callbacks, 3) Use a client initiated event system

I know Dash team are working on moving to an async framework that will maybe eventually allow something like Django’s message channel natively, but it’s a fairly large departure from the current model of UI updates so I wouldn’t wait on it for something you critically need.

Hi Damian,

I tried “dash.no_update” joining all callbacks and solve the problem!

thanks!