đź“Ł Dash Loading States

We need to provide a better loading experience for Dash Apps. Many apps use callbacks that take several seconds to load and up until now, the only loading state that was available was in the document.title (the tab of your browser).

I’d like to make “loading states” a first-class citizen in Dash: customizable on the component-level as a JS component author or as a Dash app developer and customizable on the app-level (e.g. full-screen overlays).

I have just added preliminary support for app-level loading screens in dash-renderer==0.9.0. dash-renderer will now inject a <div class="_dash-loading-callback"/> into the app whenever it is waiting for a callback to be executed. This element is unstyled and contains no content. You can bind your own loading screens to this component by using custom CSS. Here’s an example of a grey loading screen that fades in (over 0.5s).

Here’s the CSS for that example: https://codepen.io/chriddyp/pen/brPBPO

pip install dash-renderer==0.9.0
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html

import time

app = dash.Dash()

app.layout = html.Div([
    html.H3('Loading State Example'),
    dcc.Dropdown(
        id='dropdown',
        options=[{'label': i, 'value': i} for i in ['a', 'b', 'c']]
    ),
    html.Div(id='output')
])


@app.callback(Output('output', 'children'), [Input('dropdown', 'value')])
def update_value(value):
    time.sleep(2)
    return 'You have computed {}'.format(value)

# Dash CSS
app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"})

# Loading screen CSS
app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/brPBPO.css"})

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

This functionality is beta. It may change in the future.

If you create a nice loading screen experience using this functionality, please share! :beers:

20 Likes

Big feature. It means a lot. Thanks @chriddyp

Upgraded my dash environment and tested this feature in my app. The user experience is quite good. But I found one issue as below:
OS: win10
Browser: Chrome and Edge
Screen Resolution: 1920x1080
Set scale to 150% in the display setting (right click in the desktop)
The result is that the 20% bottom part is still solid while in the loading state (see following picture)

There’s a nice spinning wheel example here too for those looking for one (Progress indicator (spinning wheel gif) for long-running callbacks?):

https://www.w3schools.com/howto/howto_css_loader.asp

(just change the name of the class to _dash-loading-callback)

5 Likes

Is there (or will there be) any functionality to only show the callback div when the callback lasts more than a specified amount of time? Its great for long callbacks but flashes up annoyingly for short callbacks!

1 Like

@mikesmith1611 - That’s a great point. For now, the solution would be to add a delay to your CSS animation. Here’s an example with a 1 second delay and a 0.5s transition: https://codepen.io/chriddyp/pen/dZMMma?editors=1111.

Does something like that work?

1 Like

That solution didn’t work for the spinner example I showed above, but if you fade in the spinner with enough delay the flicker goes away:
(updated css to include a delay)

4 Likes

Amazing @mikesmith1611. This works really well for my use case.

1 Like

@chriddyp I’m not quite sure I understood the support for loading screens. Once I install dash-renderer==0.9.0, it will give me an unstyled and empty screen while my callbacks are executed? I don’t want to append no customization right now, but it would be great to show somehow that the app is loading. I have different loading periods depending on the callback and some of them take up to 20 seconds to update. The user will probably break the application before that. Thanks again!

Did you try the example that I posted here? 📣 Dash Loading States That example contains a custom CSS file that is used to display an overlay while callbacks are loading. You can customize this CSS file to display the loading indicator in a separate way if you’d like, as was done by

2 Likes

@chriddyp Basically, I have multiple dropdowns filtering two tables. Depending on the dropdown I select it is going to take longer to update the tables. I’m failing to see how I’d use different loading indicators in this case…

This isn’t yet customizable on the component level, it’s only global. All we’re doing is:

So, that element will appear on every callback, there is no way to differentiate it between different callbacks.

It still is not yet possible to customize the loading experience on the per component level (“different loading indicators”). I’d like to add this functionality but it will be quite a bit of work, will likely need a company or organization to help sponsor the development of it (Consulting, Training & Open-Source Development)

2 Likes

@chriddyp I understand now. It was kind of a CSS ignorance case here, but now I see the loading screen works exactly as I need. Thank you!

1 Like

Care to elaborate with a code example?

I observed the same on Chrome, with scaling at 100%.

All you need to do is adding app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/brPBPO.css"}). All the rest is already being managed for you. The screen will be shaded when the “Updating…” shows up in the document.title (the tab in the browser).

1 Like

Thanks for reporting! I just fixed this (the fix was to turn position: absolute into position: fixed)

The spinner solution works great for me, thanks! I was wondering if there is a way to somehow customize the contents of the _dash-loading-callback element and not only the css?

For example what I’m looking for is to have the spinner and a “Loading” text displayed when a callback is running

Another example would be to have the background greyed out (with a 100% div) and display the spinner at the same time

I developed a codepen showcasing a small addition using CSS pseudo elements that enables embedding text and animated gifs into the Dash loading callback div.

The core idea is moving all the CSS in ._dash-loading-callback into the pseudo-element ._dash-loading-callback::after. The original class can be barebones:

._dash-loading-callback {
  position: fixed;
  z-index: 100;
}

Then, within ._dash-loading-callback::after, you can add text using

content: 'your text here';

and embed animated gifs using

background-image: url(https://www.w3schools.com/html/programming.gif);
background-position: center center;
background-repeat: no-repeat;

Notably, this works with a background color

background-color: rgba(255, 255, 255, 0.5);

I’ve found Dash to be excellent so far, and chriddyp and the forums in general have been extremely helpful, so I hope this helps someone.

12 Likes

It really helps me a lot, thanks @chriddyp @mxwsn