I am building an App that at some point renders 7-16 Highcharts in a grid-layout. The rendering of these Highcharts is quite slow and I am trying to make it faster.
Right now I am using renderUI(), htmlOutput() and highcharter::hw_grid() to render the graphs. ( See Code chunk 1) I have come upon this Post where they tried to improve the performance by first using highcharter::renderHighchart() to render the Graphs and then using highcharter::higchartOutput() in renderUI() function. I have changed the code a bit so that it's output is the same as in my first Version, but the Idea should have stayed the same.(see Code chunk 2)
I have now Implemented both versions in two shiny-Apps and tried to evaluate them with profvis. I am very new to profvis and i am not sure where to look exactly to compare these two options. So I have just looked at the total time RunApp() takes. My first Version using renderUI() and htmlOutput() seemst to be faster than version two. This contradicts the results of the beforementioned Post.
Now I am wondering which options is faster and why. Should I change my code from Version 1 to version 2 to improve performance?
samp <- sample(5000, 100, replace = TRUE)
library("highcharter")
library(shiny)
ui <- shinyUI(fluidPage(
htmlOutput('plots')
))
server <- shinyServer(function(input, output) {
output$plots <- renderUI({
output=list()
for (i in 1:50) {
n <- i # Make local variable
plotname <- paste("plot", n , sep="")
output[[plotname]] <-
highchart() %>%
hc_chart(type = "column") %>%
hc_title(text = "renderHighchart()") %>%
hc_xAxis(categories = seq_along(samp)) %>%
hc_add_series(
data = samp,
name = "Downloads"
)
}
hw_grid(output,ncol=3)
})
})
app=shinyApp(ui=ui,server=server)
profvis::profvis(runApp(app))
samp <- sample(5000, 100, replace = TRUE)
library("highcharter")
library(shiny)
ui <- shinyUI(fluidPage(
uiOutput('plots')
))
server <- shinyServer(function(input, output) {
n.col <- 3
output$plots <- renderUI({
col.width <- round(12/n.col) # Calculate bootstrap column width
n.row <- ceiling(50/n.col) # calculate number of rows
cnter <<- 0 # Counter variable
# Create row with columns
rows <- lapply(1:n.row,function(row.num){
cols <- lapply(1:n.col, function(i) {
cnter <<- cnter + 1
plotname <- paste("plot", cnter, sep="")
column(col.width, highchartOutput(plotname))
})
fluidRow( do.call(tagList, cols) )
})
do.call(tagList, rows)
})
for (i in 1:50) {
local({
n <- i # Make local variable
plotname <- paste("plot", n , sep="")
output[[plotname]] <- renderHighchart({
highchart() %>%
hc_chart(type = "column") %>%
hc_title(text = "renderHighchart()") %>%
hc_xAxis(categories = seq_along(samp)) %>%
hc_add_series(
data = samp,
name = "Downloads"
)
})
})
}
})
app=shinyApp(ui=ui,server=server)
profvis::profvis(runApp(app))
I have now put the two options in one app
samp <- sample(5000, 100, replace = TRUE)
library("highcharter")
library(shiny)
ui <- shinyUI(
fluidPage(
fluidRow(uiOutput('plots')),
fluidRow(htmlOutput('rUI')))
)
server <- shinyServer(function(input, output) {
n.col <- 3
output$plots <- renderUI({
col.width <- round(12/n.col) # Calculate bootstrap column width
n.row <- ceiling(50/n.col) # calculate number of rows
cnter <<- 0 # Counter variable
# Create row with columns
rows <- lapply(1:n.row,function(row.num){
cols <- lapply(1:n.col, function(i) {
cnter <<- cnter + 1
plotname <- paste("plot", cnter, sep="")
column(col.width, highchartOutput(plotname))
})
fluidRow( do.call(tagList, cols) )
})
do.call(tagList, rows)
})
for (i in 1:50) {
local({
n <- i # Make local variable
plotname <- paste("plot", n , sep="")
output[[plotname]] <- renderHighchart({
highchart() %>%
hc_chart(type = "column") %>%
hc_title(text = "renderHighchart()") %>%
hc_xAxis(categories = seq_along(samp)) %>%
hc_add_series(
data = samp,
name = "Downloads"
)
})
})
}
output$rUI <- renderUI({
output=list()
for (i in 1:50) {
n <- i # Make local variable
plotname <- paste("plot", n , sep="")
output[[plotname]] <-
highchart() %>%
hc_chart(type = "column") %>%
hc_title(text = "renderUI") %>%
hc_xAxis(categories = seq_along(samp)) %>%
hc_add_series(
data = samp,
name = "Downloads"
)
}
hw_grid(output,ncol=3)
})
})
app=shinyApp(ui=ui,server=server)
profvis::profvis(runApp(app))
If I now look at the aggregated time of output$plots
and output$rUi
in profvis, I can see that the aggregated time for output$plots
is indeed faster