shinyproxy
shinyproxy copied to clipboard
Show progress bar on app launch
Hey there! I would like to ask for support to show a progress bar instead of the loading GIF to better convey the time needed to load an app.
I implemented such a solution in my app server with ShinyProxy installed to show a progress bar that fills in 20 seconds (approximate time taken to load app): https://compbio.imm.medicina.ulisboa.pt/psichomics
My implementation is pretty simple. I put a progress bar in a custom app.html with classes .progress-bar and .progress-[appID]:
<div class="progress">
<div class="progress-bar" role="progressbar" th:classappend="${'progress-' + appTitle}"></div>
</div>
In the script part of app.html (inside the $(window).on('load', function() {}), I set the width to go to 100% after 1 millisecond:
setTimeout(function() { $('.progress-bar').css('width', '100%'); }, 1);
And then in a custom CSS file, I add the following rules (if no custom .progress-[appID] is present, the progress bar will resort to fill in 5 seconds):
.progress {
width: 350px;
margin: auto;
}
.progress-bar { transition: width 5s ease-in-out; }
.progress-psichomics { transition: width 20s ease-in-out; }
I think it would be great to have such a feature in ShinyProxy and this could be implemented in two ways.
- Manually: each app in
application.ymlwould have an optional parameter to state the time taken to load and there would be a global parameter for the default time. - Automatically: as ShinyProxy can estimate loading times for apps, use the median value as the loading time for the next time an app is loading.
Tell me what do you think.
Thanks for the amazing program that is ShinyProxy! :)
Best, Nuno
Hi
Thanks for your suggestion! This is something we also have thought about, but don't have any concrete plans for yet.
With ShinyProxy 2.6.0, it is possible to implement the Manual method, just using the templates feature. You can specify the startup-time in a template-property for each app. See https://shinyproxy.io/documentation/configuration/#template-properties and https://github.com/openanalytics/shinyproxy-config-examples/tree/master/04-custom-html-template#template-properties-for-an-app .
For example:
- id: 06_tabsets
container-cmd: ["R", "-e", "shinyproxy::run_06_tabsets()"]
container-image: openanalytics/shinyproxy-demo
access-groups: scientists
template-properties:
startup-time: 20
You can then add a progress bar to the loading screen (using the app.html template):
<div id="loading" class="loading loading-img"><div class="loading-txt">Launching <span th:text="${appTitle}"></span>...<br>
<progress id="progress" value="0" th:max="${@thymeleaf.getTemplateProperty(appName, 'wait-time', 30)}"></progress>
</div></div>
and then add this piece of javascript:
<script type="text/javascript" th:inline="javascript">
$(window).on('load', function() {
var lastValue = 0;
var interval = setInterval(function () {
if (!$("#progress").is(":visible")) {
clearInterval(interval);
return;
}
lastValue++;
$('#progress').val(lastValue);
}, 1000)
});
</script>
Of course you can fine-tine this with some animations etc.
Regarding the automatic way: this would be a very cool feature, however, this would require ShinyProxy to store these loading-times somewhere. There are all kind of options here (file on disk, redis, database, re-use the usage-statitistics feature), but we don't want to force users into adding complexity when hosting ShinyProxy. Currently it does not require a database or persistent storage. Of course, this could be implemented as an optional feature, but even then we have to think about the best method to store these values.
Hey @LEDfan, thank you for suggestion! I missed that we can now add our own template properties, that is certainly useful. Thanks for your time!