Improving shiny app loading speed

Hi,

I am working a quite large shiny application. In its current states, it takes quite a while (>10s) to be displayed when accessed remotely (open shiny server) or locally through Rstudio (the app seems actually slower when it is ran locally).

Are they strategies to apply to decrease load time? Are there ways to tell shiny not to load some component or not read a module until it is actually needed?

Thanks in advance

What exactly does your app do on start up? Do you have complex calculations/large amounts of data that are being processed when you load the app?

Shiny is quite sensible in that it won't calculate/draw anything it doesn't need to on start up (i.e. it will only calculate for something that is visible on screen).

There is no calculation, data read, or data simulation step at start up.
Only UI elements and supporting server side functions are being loaded. The UI is based upon shinydashboard and the app calls 12 different modules (including a few with sub-modules). Each module is more or less associated with a menu from the side bar. The app opens up to a "data loading and post-processing" module.

I recommend analyzing what R is doing when your app starts by using profvis. This is a good introduction: https://www.rstudio.com/resources/webinars/profvis-profiling-tools-for-faster-r-code/

For a Shiny app, you can profile your app's startup like this:

library(profvis)
profvis(runApp())

After you're looking at a profile you can see where the time is going, and focus on making the slowest part faster.

No luck with profvis: surrounding my runApp call in profvis seems to slow down all processes so much that my app is not even displayed on screen after 10 min of run (I tried at least 3 times, with fresh restart of R and/or Rstudio).

When I try to interrupt either the profiling, I get the following error message: Unable to establish connection with R session.

Looking at my Windows task manager: CPU is running super low, and I see no increase in memory use for Rstudio... so it's looking like the code is stuck somewhere.

profivs calls work on smaller apps (which are also not based upon shinydashboard, but I have to check this further).

Hmm, that's odd then. If there is no processing and just UI drawing then in theory loading should be relatively fast. What do the modules/sub-modules do?

@pomchip, Have you worked with the Utliization Scheduler? This is something that will affect load time and such. I spent a lot of time iterating on various settings for my app to get it to be optimal for my users.

This happens with me too i think it's server side issues or the CRAN mirror you choose

Have you worked with the Utliization Scheduler?

No, I haven't. I do not have access to Shiny Server Pro

@jim89

Hmm, that’s odd then. If there is no processing and just UI drawing then in theory loading should be relatively fast. What do the modules/sub-modules do?

Most of the UI of the modules are defined server-side by a bunch of reactive expression based upon the default value of high level data-related reactive. Essentially, I have a data module (the app opens in this module) in which the users can upload one or more datasets. This is attached to a few data reactive objects which are used in the other modules. Upon initialization of the app, the data objects are set to default (NA) values. The other modules reacts accordingly. Thinking about it, they should actually not react because I did not use outputOptions(..., uspendWhenHidden = FALSE).

I may need to gut my app to just the data module, and compare loading time.

@karimelghazouly

Load time is slow also when the app is run locally. I don't think this a server problem.

Bit of a shot in the dark here, but is there a chance that there's some circular dependency going on between the modules, meaning that the different UI elements are "looking" for each other as they render?

Some days later...
I think you should have a look at shiny package 'req' function.
Putting that right at the beginning of a reactive will allow you to evaluate its whole content until a condition is satisfied.
That should really reduce the loading time.

1 Like