Improve profvis performance for profiling shiny app - r

I have a very large and complex R Shiny app and I am trying to find bottlenecks or parts of the code to improve via the profvis package.
The problem is that profvis itself is performing very slowly (because of the processes and functions in my shiny app) so that it's lagging and almost not possible to properly view & navigate through the profile or the flame graph.
Starting the profvis profile via R or via browser (firefox & chrome tested) doesn't really make a big difference here.
I am only testing one (the main) feature/calculation in my shiny app which is initiated by one action button, thus I can't really test less features or make the profile "shorter".
Any help or tips are appreciated. Especially ways to run profvis faster. Another option I tried was to only wrap parts of my code inside the shiny app with profvis, but I didn't find a way to get this work.
Thank you!

Related

Interactive Document (takes input gives output) in Rpubs

Is it possible to publish an RMarkdown file to Rpubs that takes input and gives out put from the Rpubs site? I want to create a simple calculator related to my job that takes a few inputs and gives an output and, if possible, publish to Rpubs for people to view and use.
SHINY: I know this is what shiny is for, creating interactive apps, but I dont know it very well or how to implement an app I create for multiple people to use, or how to imbed the link to the app, and so on. Just trying to see if this is possible in things I already know how to use
RPubs is for HTML documents that don't require R calculations on the backend. In some instances, there can be some degree of interactivity e.g., brushing and linking plots, filtering data and having the filter propagate to a plot. These happen through the crosstalk package. However, it sounds like you need a shiny app that can take inputs and have R do some calculation of those on the back end. You could host your app on shinyapps.io
It's also possible, depending on how complicated the calculations are, that the entire app could be written in native javascript, which wouldn't require a server-side computation, so could be hosted on any website.

Shiny app is stalled when executing a big calculation

I'm new to shiny , couldn't get my answer anywhere tho.
I have a heavy code aggregating tables in R. I wanted to move it to the Web app and I chose Shiny as my original code is written in R so I thought it saves me lots of time.
When I run the code by
ObserveEvent(actionbutton$do,{mybigcalculation(input_tables)})
my code is running but at the time of executing my code, it's not possible to do other stuff like exploring tables in the other tabs.The rendering part works but he web app functionalities is completely frozen at the time the process is running.
Any help would be highly appreciated ? if this doesn't work I have to move to typical web app development by having backend ( e.g plumber ) and frontend (e.g React) in separate servers.
Thank you
After a long investigation, I think I found the answer. I'm writing it down here as you might face this issue quite often developing your web app by Shiny. Always there are some big processes you wanna do and wanna make sure your async works great.
There are libraries (future & promises packages) that Cheng explains them here. it says, they can take the calculations in the background and make them come back with the result while the shiny app is doing its normal job. It didn't work for me and I still had my web app stalled. But what I saw, they did increase mybigcalculation speed dramatically. Also it took it to the background makes it invisible in the console.
I found my answer in a package called Shiny.worker library.
Now my app is working fine while my expensive code is running in the background. I made my ideal execution(fast and async) by wrapping future package inside of a shiny worker library.
So it looks something like this:
load.lib <- c("promises","future","shiny.worker")
install.lib <- load.lib[!load.lib %in% installed.packages()]
for(lib in install.lib) install.packages(lib,dependencies=TRUE)
sapply(load.lib,library,character=TRUE)
plan(multisession)
initiate the worker by:
worker <- shiny.worker::initialize_worker()
then:
wrapper <- function(args) {
future::future(my_heavy_calculations(args$r))
}
reactive_arguments <- reactive({
input$start
list(r = rnorm(1))
})
resultPromise <- worker$run_job("job1", wrapper, args_reactive = reactive_arguments)
resultPromise()$result # contains the result of the calculations
resultPromise()$resolved # contains flag that informs whether the job has finished or not
I'm looking forward for any idea and suggestions that can makes the answer better.

Speedup UI in loading shiny

In global.R file I am reading some 10-12 excel files, some user defined functions, modules and doing some data manipulation (not so heavy task) on top of that. I want to speed up loading shiny app. I was thinking if I save it in .RData and then do load("mydata.RData", envir = .GlobalEnv) instead of reading excel files and sourcing functions in global.R. Would it improve loading time of shiny app? I am fine even if UI appears but server still loads. I am more interested in showing UI to the user instantly and user can wait for some calculation. I am using docker for production, hence mainly interested in UI loading time as container takes some time to spin up which user has to wait and then loading the app also takes time.
That is a big topic and there are several points in which you can improve your Shiny-App, so that it runs faster.
The first idea would be, to put every tab into a module. Meaning that the code you normally run within your ui.R will get a lot shorter. Thus the app gets faster, since the plots, files, etc. what is needed within this module, just gets loaded once the user clicks on that tab.
Make your app more efficient by using data.table. This package is specifically designed for faster usage. You can even combine it with dplyr. In your case try loading your files with the data.table::fread() command.
When it comes to plotting you can even use JavaScript's D3. There is a package called r2d3, which enables you to use JS's D3 to plot within your Shiny-App.
Convert the excel-files into a more machine readable format, like .rds. This also increases the loading speed.
I would suggest, you once use the profvis package and run your Shiny-App with it. It will allow, after you've loaded your app and closed it again, to see what exactly took so much time. Maybe it was not the loading after all, but a different problem instead? Then you could go from there.

R/Shiny: View full stack/execution log

I'm debugging a Shiny web app, and would like to see the entire control flow/execution path over the course of rendering and updating the generated website.
Is there a way to capture/print/dump-to-file every line of code that is executed in the process of rendering/updating a Shiny app? It would also be good (maybe better?) to see every line of R code parsed by the running R interpreter instance; I'm not concerned about length of this output, and would prefer to get things as verbosely as possible.
I have looked into the stack tracing Shiny functions but these seem to be intended for error catching/handling/reporting. The app is not generating errors/warnings, just setting some variables to NULL at some point when they shouldn't be, so I'm not sure if this is the right approach. These stack tracing functions also seem to be more localized, designed to operate within a given reactive variable/function/render rather than following the control/execution flow across differing reactives/rendering functions in an app.
This app is a large, company-internal app so I cannot give a MRE/MWE.
I finally found the profvis package that does more-or-less exactly what I want by taking a snapshot of the execution stack at a fixed time interval (default 10ms). I'm still working on using this tool to debug, but I believe this will get me there and would also be useful to others debugging Shiny apps that need more than browser() and/or reactlog.
Specifically, I have been doing:
#install.packages("profvis")
library(profvis)
exec_log <- profvis(runApp("myShinyApp"))
...interact with the myShinyApp web page enough to trigger the bug, then interrupt execution...
print(exec_log)

Workflow for maintaining different versions of a Shiny app

Lately I have been making several very similar Shiny apps for different clients and hosting them on shinyapps.io.
Each app has a different title, different data, some differences in branding etc. but otherwise the code is very similar.
I'm having trouble maintaining these apps. When find and fix a bug I currently have to go through 5 different apps and make the change each time.
Does anyone have good suggestions on how to handle this? Git branches? I know the best solution would be to have one app and upload different data, but that's not possible unfortunately.
I'd like to keep using shinyapps.io, but I'm open to hosting the apps somewhere else if it makes my workflow better.
As I wrote in the comment shinyModules() will help you: https://shiny.rstudio.com/articles/modules.html
Shiny modules are to shiny functions, like ordinary functions are to repeating code.
Or to put it differently:
Repeating code --> function
repeating shiny function --> shiny module
As the documentation is a bit complicated here and there, i wrote a simplified example here:
Create a reactive function outside the shiny app.
You could store all the shiny modules in a file modules.R and add a global.R script to each of the apps that loads the modules (source("../modules.R"). Then you only have to update the functions within modules.R. That change of structure might take a while in the beginning. But, i think in the long run it pays off for more complex apps.
I ended up making a library that contained most of the code I needed for the apps, as suggested by Adam Spannbauer in the comments.
It's not perfect; I still have some duplication and I have to have the library on GitHub so that it will work with shinyapps.io. However, it's a big improvement on what I was doing previously.

Resources