Q:

Render plotly plots asynchronously in shiny app

In shiny app I render couple plotly plots at once, but they render only after all of them are calculated. For example, if rendering 8 of 9 plots  takes 8 seconds and rendering 9th takes 15 seconds, the first 8 plots will appear only after 9th is rendered (after 15 seconds instead of 8). See example below.
box_plot1 appears only when box_plot2 is rendered. I played a bit with shiny promises, but didn't find solution so far.
MWE:
library(shinydashboard)
library(plotly)

header <- dashboardHeader(
  title = ""
)

body <- dashboardBody(
  fluidRow(
    column(width = 6,
           box(width = NULL, solidHeader = TRUE,
               plotly::plotlyOutput("box_plot1")
           )
    ),
    column(width = 6,
           box(width = NULL, solidHeader = TRUE,
               plotly::plotlyOutput("box_plot2")
           )
    )
  )
)

ui <- dashboardPage(
  header,
  dashboardSidebar(disable = TRUE),
  body
)

server <- function(input, output, session) {

  output$box_plot1 <- plotly::renderPlotly({
    p <- plot_ly(ggplot2::diamonds, x = ~cut, y = ~price, color = ~clarity, type = "box") %>%
      layout(boxmode = "group")

    p
  })

  output$box_plot2 <- plotly::renderPlotly({

    for (i in 1:3) {
      print(i)
      Sys.sleep(1)
    }

    plot_ly(ggplot2::diamonds, y = ~price, color = ~cut, type = "box")
  })
}

shinyApp(ui = ui, server = server)

A:

You can use renderUI in combination with reactiveValues which keep track of the order of the calculations.
library(shinydashboard)
library(plotly)

header <- dashboardHeader(
    title = ""
)

body <- dashboardBody(
    fluidRow(
        column(width = 6,
               uiOutput("plot1")
        ),
        column(width = 6,
               uiOutput("plot2")
        )
    )
)

ui <- dashboardPage(
    header,
    dashboardSidebar(disable = TRUE),
    body
)

server <- function(input, output, session) {

    rv <- reactiveValues(val = 0)

    output$plot1 <- renderUI({

        output$box_plot1 <- plotly::renderPlotly({

            for (i in 3:5) {
                print(i)
                Sys.sleep(1)
            }

            p <- plot_ly(ggplot2::diamonds, x = ~cut, y = ~price, color = ~clarity, type = "box") %>%
                layout(boxmode = "group")
            rv$val <- 1
            p
        })

        return(
            tagList(
                box(width = NULL, solidHeader = TRUE,
                    plotly::plotlyOutput("box_plot1")
                )
            )
        )

    })

    output$plot2 <- renderUI({

        if(rv$val == 0) {
            return(NULL)
        }

        output$box_plot2 <- plotly::renderPlotly({

            for (i in 1:3) {
                print(i)
                Sys.sleep(1)
            }

            plot_ly(ggplot2::diamonds, y = ~price, color = ~cut, type = "box")
        })

        return(
            tagList(
                box(width = NULL, solidHeader = TRUE,
                    plotly::plotlyOutput("box_plot2")
                )
            )
        )

    })

}

shinyApp(ui = ui, server = server)

