Skip to content
This repository has been archived by the owner on May 30, 2023. It is now read-only.

Speed up the shiny app #34

Open
shyan0903 opened this issue Jun 10, 2022 · 5 comments
Open

Speed up the shiny app #34

shyan0903 opened this issue Jun 10, 2022 · 5 comments

Comments

@shyan0903
Copy link
Collaborator

shyan0903 commented Jun 10, 2022

Now that most of the functionalities have been implemented for the final data product: the BC Chronic Disease Dashboard hosted on Shiny, we have noticed unreasonably slow performance issue. Specifically, when one or multiple filters change, the charts can take a long time to be drawn and sometimes even lead the app to freeze. This issue documents the methods Jessie and I have tried to speed up the app.

@shyan0903
Copy link
Collaborator Author

Based on the benchmark tests documented here, I replaced all %>% with |>. The loading is visually faster.

@jessie14
Copy link
Collaborator

Attempted methods to speed up dashboard and their outcomes:

  • Subset data using dplyr instead of base R ( slight improvement)
  • Adding bindCache() and bindEvent() (no difference)
  • Using memoise on helper functions ( slows down app even more..??)
  • Profiling the app using profvis ( difficult to translate into useful fixes)
  • Eliminating renderUI elements ( moderate improvement)
  • Only read in required data (slight improvement on startup)
  • Close all other programs on computer and run only RStudio / Shiny App (biggest improvement)

@shyan0903
Copy link
Collaborator Author

shyan0903 commented Jun 14, 2022

More on using caching in Shiny to maximize performance:

According to the article, caching, where the application does the computation with a given set of inputs once and uses the saved results later, is most effective when the same computation or plotting is done multiple times. However, we do not expect a user to repeat creating the same plot. Moreover, given that we have many possible combinations for the six filters (such as 6 choices for rate types, 25 diseases, 5 HAs, and 195 CHSAs), it will be memory-consuming if we cache every set of inputs the user plays with.

As a result, the tradeoff between time saved by caching outputs to rare sets of inputs and memory occupied by many set of inputs is not worthy for our app.

@shyan0903
Copy link
Collaborator Author

shyan0903 commented Jun 14, 2022

We also tried using isolate() to remove the dependency of graph outputs on reactive objects based on this article.

Right now, our app is implemented in such a reactive way that the plots will be rerendered every time a filter value has changed. And since plotting does take a longer time, frequent changes to filter values will lead to slow performance and even cause the app to freeze.

Using isolate() can allow the user to finish all filter selections before clicking a button or other trigger to execute the computation and plotting all at once. However, this design is fundamentally different from what we tried to build and also requires significant changes to the existing code as the logic of reactive components changes. We decide to keep the responsiveness and let the users to leave buffer time between selections.

@shyan0903
Copy link
Collaborator Author

Another suggested method is using promises with Shiny. This method is essentially applying asynchronous programming to Shiny apps to increase scalability when multiple users are active at the same time. Upon second thought, our goal is to increase performance for a single user. We do not anticipate many users to explore chronic diseases in BC simultaneously. So we did not research further. One can learn more here if scalability is the focus.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants