3

I have a general question about shiny reactive functions with some pseudo code to demonstrate essentially what I am trying to do. I essentially am wondering why even though each of my reactive functions are very quick, but when I am running the shiny app, there seems to be a significant delay between each of the functions. Thus, what seems to be making the app slow is not my individual functions but rather whatever is happening in between my reactive functions. This is pseudo code for what I am trying to do with some comments. If you need a complete reproducible example, it may take me awhile to create one, but I will eventually finish it. As for now, I am trying to just explain my thought process and see if this is some higher-level conceptual thing about reactive functions that I should take a look at to solve my speed issue.

## Global variables: long_list, initial_df

shinyApp(ui = fluidPage(
              titlePanel("Example"),
              sideBarLayout(
                 sideBarPanel(

                    ## long_list is a variable that contains all of the possible choices. 
                    ## There are many choices.

                    selectInput("symbols",
                                "Possible Choices",
                                long_list)

                    ## Have a few conditional panels. These
                    ## contain date range sliders and tables. 

                    conditionalPanel(
                        tableOutput("table1")
                        tableOutput("table2")
                                .
                                .
                                .
                        tableOutput("table10")
                    ),
                    conditionalPanel(
                        tableOutput("table11")
                    )
                 ...),
                 mainPanel(

                    ## many plots being rendered

                    rCharts::showOutput("plot1", "nvd3"),
                    rCharts::showOutput("plot2", "nvd3"),
                            .
                            .
                            .
                    rCharts::showOutput("plot10", "nvd3"),
                    conditionalPanel(
                         ## some condition
                         rCharts::showOutput("plot11", "nvd3")
                    )
                ...)
              )
            ),
     server = function(input, output) {

              ## returns a data frame that reacts to a change in some input,
              ## such as a radio button or a slider, and then returns a 
              ## dataframe that my plotting functions will use. It filters
              ## a global data frame by a certain symbol in this pseudo example. 
              ## This makes the data frame of interest smaller and thus results 
              ## in different plots depending on which symbol the user chooses. 

              filtered_data_frame <- reactive({

                 ## df is a global variable that contains a pre-calculated data frame. 

                 if(!is.null(input$symbols)) {
                    return(dplyr::filter(df, symbol == input$symbols))
                 }

                 ## if the initial check does not pass (we have a null symbol)
                 ## then we return NULL. This is for validation in the 
                 ## plotting functions to do nothing if this function returns
                 ## NULL

                 return(NULL)
              })

              output$plot1 <- rCharts::renderChart2({

                  ## checks to make sure the function above returns a non-null 
                  ## result before proceeding. Otherwise does nothing (empty string "")

                  validate(
                      need(!is.null(filtered_data_frame()), "")
                  )

                  ## nvd3 plot using rCharts

                  g <- nPlot(...)
                  g
              })

              output$plot2 <- rCharts::renderChart2({
                  validate(
                      need(!is.null(filtered_data_frame()), "")
                  )
                  g <- nPlot(...)
                  g
              }) 

              ## This continues for say 11 plots, (i.e. output$plot3...output$plot11) 
              ## and similarly the for say 11 tables, (i.e output$table1...output$table11)
              ## The tables render data frames. 
    }
)

Now each of the reactive functions, (i.e. filtered_data_frame(), output$plot1, output$table1...output$plot11, output$table11) are all individually very quick. I put a print statement for the start of each function and the end of each of function and they almost pretty instantaneously one after the other. For example:

 output$plot1 <- rCharts::renderChart2({
     validate(...)

     print("start")
     ...
     g <- nPlot(...)
     ...
     print("end")

     ## g is the name of the plot I return

     g
})

I have these "start" and "end" print statements for each of my reactive functions, and each individual function runs very quickly, but there are pauses between one function's "end" and another function's "start" that I cannot explain. I am not too sure what is causing these long pauses. I spent a lot of time optimizing each of my functions only to find out that most of the time did not seem to be within the functions but perhaps something slow with the reactive nature of shiny. Is there a way to reduce the long pauses between reactive functions in shiny? If more information is needed, I can provide a full reproducible example, but again it would probably take awhile to make an application that has as long of pauses as mine does.

I did notice that when I used a larger dataset as input (a larger dataset for the initial_df global variable), my app did run slower, but again not so much within each of the functions but rather long pauses between functions. Does anyone have any insight into this issue? Any help is greatly appreciated! Thank you!

johnny838
  • 922
  • 7
  • 15
  • 1
    I wouldn't expect that at all. Though there is work being done outside of your code (in this example, the renderChart2 function is taking your result and serializing it to JSON) I wouldn't expect this particular example to have a noticeable amount of lag. A fully reproducible example would be very helpful. – Joe Cheng Aug 07 '15 at 17:35
  • Thank you for taking a look! I will work on making a fully reproducible example. – johnny838 Aug 07 '15 at 17:38
  • Hi Joe, you are absolutely right in that the renderChart2 function is the cause of the lag. It seems that the paste calls in the renderChart2 source code are very slow, especially since our plots have very many data points. Other than trying to modify the source code, I am not too sure what else can be done, but it is luckily not a result of some background issue in shiny that we aren't aware of. I will take a look at trying to optimize unless you have any suggestions to improve renderChart2 or an alternative potentially? Thank you. – johnny838 Aug 10 '15 at 18:59

0 Answers0