I have a moderatly large data.frame (5000 - 10000) in my Shiny app that should be rendered dynamically as a datatable
, together with dynamically created action buttons.
I used the pattern from this stackoverflow post to create the buttons: R Shiny: Handle Action Buttons in Data Table
This works perfectly, however, with larger data.frames i ran into performance issues. Converting the shiny.tags
to character (either with as.character()
or with htmltools::renderTags()
) makes things very slow. I ran a small microbenchmark on this:
- creation of the tag tree takes roughly 1 sec
- adding the conversion to HTML makes this time go up to ~ 15 - 20 sec
library(microbenchmark)
library(shiny)
library(ggplot2)
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
create_info_btns_mapChr <- function(FUN, len, id, ...) {
args <- rlang::list2(...)
list <-
seq_len(len) %>% purrr::map(.f = FUN, inputId = paste0(id), ...)
chr <- list %>% purrr::map( ~ as.character(.x))
}
create_info_btns_map <- function(FUN, len, id, ...) {
args <- rlang::list2(...)
list <-
seq_len(len) %>% purrr::map(.f = FUN, inputId = paste0(id), ...)
}
df <- diamonds[1:10000, ]
mbm <- microbenchmark::microbenchmark(tags = {
create_info_btns_map(
actionButton,
nrow(df),
id = "test_",
label = icon("info-circle"),
icon = NULL)
},
html = {
out <- create_info_btns_mapChr(
actionButton,
nrow(df),
id = "test_",
label = icon("info-circle"),
icon = NULL)
},
times = 2)
mbm
#> Unit: seconds
#> expr min lq mean median uq max neval cld
#> tags 1.411491 1.411491 1.424619 1.424619 1.437746 1.437746 2 a
#> html 15.852125 15.852125 15.951569 15.951569 16.051013 16.051013 2 b
autoplot(mbm)
#> Coordinate system already present. Adding new coordinate system, which will replace the existing one.
Created on 2022-10-07 by the reprex package (v2.0.1)
Output image can be found here (cant include it directly yet) "https://i.imgur.com/eHhwbEo.png"
I have not found good entry points for optimization here. Maybe not adding all the buttons at once, but only for the visible records - but I would not know how to tackle that.. Any suggestions?
Best