Open jlstevens opened 4 years ago
Looks great, thanks! Apart from actually doing them, what's left is to figure out a priority order, which I'd say is a combination of how difficult they are and how many Panel users and use cases are likely to be affected. I.e. we should definitely do all the easy things; the more difficult or time consuming ones will need to be sorted into a priority order that depends on how much help they give. It's hard for me to judge the difficulty, but in terms of impact 1 and 4 offer a lot of bang for the buck, because they could benefit nearly all Panel apps without extra work. The rest are all useful but don't have quite as much reach because they require specific work by an app author each time, so I'd put those in a second tier of priority.
I strongly second that - sitting in front of a web page without any indication of whether or not it is still alive and kicking is sooo last millenium... Personally, I would prioritize item 3 or 4, since during the initial loading at least there is some feedback via the browser's loading indicator.
Great thoughts. Here is my feedback on the different items
For the app loading
indicator. Please let spinner
or similar be configurable. I would like to be able to specify for example the .gif spinner according to the branding i have to do either at awesome-panel.org or at work.
Making it easy in for example the upcoming MaterialTemplate to signal progress in a uniform way from anywhere in the application would be so nice. Please consider that sometimes you want to convey progress.value
, sometimes progress.active
, and sometimes even the not supported progress.message
or combinations of these.
At awesome-panel.org my custom MaterialTemplate signals progress using a .gif spinner in the upper right part of the page. It switches between a static image and a dynamic, breathing image.
Again it would be nice to be able to custom brand the progress showed if it is not neutral and awesome.
The other thing I have created is a ProgressService. Right now there is no easy way in Panel to signal progress. At awesome-panel.org I have a service for progress that different spinners or progressbars can watch
. See https://github.com/MarcSkovMadsen/awesome-panel/blob/master/package/awesome_panel/application/services/progress_service.py. This can be used in a variety of ways.
Similar to progress
, being able to report messages
including error messages would be so nice. I can see in the upcoming MaterialTemplate that @philippjfr have had some thoughts in that direction using a snackbar
.
An example of a user requesting a better experience when dynamic tabs are loading. https://discourse.holoviz.org/t/can-dynamic-tabs-trigger-progress-active-on-change-of-tab/859/3
FYI. @jlstevens
I have found what I believe is a very, very simple solution for this. It's based on CSS and css_classes
.
I believe we can easily add methods .start_loading
, stop_loading
, toggle_loading
to any pane, widget or layout in Panel.
Just use add, remove or toggle the css class pnx-loading
defined below.
.bk.pnx-loading:before {
position: absolute;
height: 100%;
width: 100%;
padding: 10%;
content: '';
z-index: 1000;
background-color: rgb(255,255,255,0.75); /partially transparent image/
border-color: lightgray;
background-image: url('https://raw.githubusercontent.com/MarcSkovMadsen/awesome-panel/master/assets/images/spinners/spinner_aqua.png');
background-repeat: no-repeat;
background-position: center; / Center the image /
background-size: 50% inherit;
border-width: 1px;
}```
and for DARK THEME additionally
```css
.bk.pnx-loading:before {
background-color: rgb(0,0,0,0.75); /partially transparent image/
border-color: lightgray;
}```
or if we don't want `gifs` then pure css loaders like https://projects.lukehaas.me/css-loaders/
FYI @jlstevens and other
I've just contributed this PR https://github.com/holoviz/panel/pull/1730
There is a high resolution video here https://discourse.holoviz.org/t/loading-spinner-for-layouts-panes-and-widgets-how-should-it-look-and-feel/1370
@MarcSkovMadsen I like this approach and I look forward to seeing that PR merged!
We've now made progress on pretty much all of these except for 1. and 4. Personally I see 4. as problematic because the frontend won't know when whatever computation that has been triggered completes and it is easy enough to set .loading=True
in Python. @jlstevens I'd appreciate it if you created a new issue for 1. as that is still important and then closed this issue.
This issue is writing up a discussion about how various types of load/processing times could be handled in panel to improve the user experience. It is common for a panel application to appear broken when in fact it is simply waiting for some processing to complete.
Here are seven orthogonal ways we can imagine improving the user experience in this regard, with checkboxes indicating whether that approach has been made to be well supported:
[ ] 1. When the bokeh server starts serving a panel app, you initially see a blank page. This initialization could benefit from a spinner or some other indication that the application is loading. This is the lowest level at which an improvement can be made and it would benefit all bokeh and panel users without requiring any effort from the app developer.
[x] 2. Once this initialization is complete, a signal or callback should be available to trigger further loading of components. The initial application may have a skeleton and the user may choose to use such a callback to defer slower loading components. This way, something appears on screen as fast as possible and slower components load later.
[x] 3. An optional global busy indicator would be a useful panel component even once a dashboard is fully loaded. While interacting with a dashboard there can be pauses that should be indicated to the user. This is similar in concept to the kernel busy indicator in Jupyter notebooks.
[ ] 4. Panel components could directly support feedback at the JavaScript level. For instance, buttons could immediately show a spinner while waiting for the execution of the attached callback. As buttons are often used to trigger tasks that take time, such an option could benefit many panel apps with minimal user effort.
[x] 5. In addition to the global busy indicator, panel should offer a collection of busy indicators (dots, traffic lights, spinners etc) as components that users can employ anywhere they wish.
[x] 6. Another way to make waiting less painful is to allow placeholder widgets to appear that get replaced with the populated widget once the callback is complete. For instance, dynamic layouts triggered by buttons could immediate insert a placeholder item to show where the data will be displayed once it arrives. This may simply be a recommendation in the docs for how to implement such behavior and not necessarily a new feature (e.g how to implement param methods/functions to do this).
[x] 7. Another pattern that might help would be to write code that returns the widgets immediately, just without the data that is being processed and not yet available. Once the (potentially slow) callback is complete, then the widgets would be populated with the corresponding data. This has the advantage of avoiding placeholder items by using the desired widgets that will be present once the callback is complete.
These approaches should be orthogonal to each other, some requiring more effort from the application developer than others. Taken together, I think these approaches will allow panel apps to feel more robust and responsive. Anything you would like to add @jbednar @philippjfr?