Блестящий - элементы не отображаются после завершения функции

Я динамически создаю элементы для вставки в fluidRow, проблема, с которой я сталкиваюсь, заключается в том, что все элементы визуализируются одновременно. Таким образом, вместо того, чтобы отображать каждый элемент, когда его renderUI функция заканчивается, все они продолжают ждать, пока не завершится последний renderUI. Таким образом, наличие большого количества элементов в my_dataset делает рендеринг очень медленным.

Я ожидал, что после отображения print(str_glue('End: {i}')) элемент будет отрисован. Однако это было не так, он ждал всех элементов (в том числе и тех, которые не были видны на экране).

Я пытался использовать outputOptions(..., suspendWhenHidden = TRUE), но это не имело значения (как и ожидалось, поскольку это значение по умолчанию).

MWE

library(shiny)
library(shinydashboard)
library(dplyr)
library(tidyr)
library(purrr)
library(stringr)
library(shinycssloaders)

qtd <- 500

my_dataset <- data.frame(
  stringsAsFactors = F,
  Name = rep('Sample', qtd),
  Value = runif (qtd)
)

ui <- function() {
  fluidPage(
    fluidRow(
      column(12, textInput(inputId = 'my_text_input', label = NULL, placeholder = 'Search', width = '100%')),
      uiOutput('custom_ui')
    )
  )
}

server <- function(input, output, session) {
  output[['custom_ui']] <- renderUI({
    filtered_dataset <- my_dataset %>%
      filter(grepl(input[['my_text_input']], Name, ignore.case = T)) %>%
      arrange(Name)
    
    map(1:nrow(filtered_dataset), function(i) {
      item <- filtered_dataset[i,]
      custom_id <- str_glue('custom_id_{i}')
      output[[custom_id]] <- renderUI({
        print(str_glue('Start: {i}'))
        print(item)
        result <- box(
          width = 3,
          title = item$Name,
          item$Value
        )
        print(str_glue('End: {i}'))
        result
      })
      
      column(width = 3, uiOutput(custom_id, style = 'height: 350px;') %>% withSpinner(type = 6))
    })
  })
}


runApp(shinyApp(ui = ui, server = server), launch.browser = T)

Вы не дали нам MWE, поэтому трудно быть уверенным, но... renderUI — это функция. Он вернется только после того, как весь содержащийся в нем код будет выполнен. Следовательно, вы ничего не видите, пока не увидите все. Варианты повышения скорости: (1) перенести построение набора данных за пределы renderUI. (Это хорошая практика, и я подозреваю, что вам все равно придется это делать.) 2 Поскольку вы фактически дублируете один и тот же интерфейс (с разными данными), определите модуль для представления интерфейса и создайте несколько экземпляров модуля для отображения. различные сокращения данных.

Limey 16.03.2022 18:23

@Limey Я добавил MWE

Daniel 16.03.2022 18:44
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
41
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

То, что вы описываете, является ожидаемым поведением. Сервер ничего не вернет пользовательскому интерфейсу, пока все вычисления не будут завершены.

Я вижу, вы очень полагаетесь на renderUI. Это делает приложение Shiny медленным. Когда приложение запускается, оно должно загрузиться, понять, что ему не хватает части пользовательского интерфейса, попросить сервер создать пользовательский интерфейс, после чего сервер создаст HTML-код для всех ваших полей и отправит их в пользовательский интерфейс до того, как что-либо будет показано. Вы должны попытаться сохранить как можно больше статичного пользовательского интерфейса.

В зависимости от того, чего вы хотите достичь, вероятно, есть много разных способов сделать это без renderUI.

Ниже приведен пример, в котором HTML-код для блоков создается вне renderUI. Это будет работать, если вам не нужны элементы управления вводом или выводами в полях, потому что тогда им нужен собственный идентификатор.


library(shiny)
library(shinydashboard)
library(dplyr)
library(purrr)

qtd <- 500

my_dataset <- data.frame(
  stringsAsFactors = FALSE,
  Name = rep('Sample', qtd),
  Value = runif (qtd)
) %>%
  mutate(
    x = map2(
      Name,
      Value,
      ~column(
        width = 3,
        box(
          width = 3,
          title = .x,
          .y
        )
      )
    )
  )


ui <- function() {
  fluidPage(
    fluidRow(
      column(
        12,
        textInput(
          inputId = 'my_text_input',
          label = NULL,
          placeholder = 'Search',
          width = '100%'
        )
      ),
      uiOutput('custom_ui')
    )
  )
}

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

  # Only the filtering of the data is done inside `renderUI`
  output[['custom_ui']] <- renderUI({

    filtered_dataset <-
      my_dataset %>%
      filter(grepl(input[['my_text_input']], Name, ignore.case = TRUE)) %>%
      arrange(Name) %>%
      pull(x)

  })

}


runApp(shinyApp(ui = ui, server = server), launch.browser = TRUE)


Last I just want to recommend this book by Hadley Wickham. I think reading this (or parts of this) book before working with Shiny will make everything easier for you.

Спасибо за ответ и за справочник, посмотрю! Ваше решение действительно работает как шарм для де MWE, который я выложил, но, к сожалению, для моей реальной проблемы это не так =/. Как вы прокомментировали, у меня есть некоторые выходы, которые мне нужно установить там динамически, но не волнуйтесь! Я уже нашел обходной путь для моей проблемы, который сработал для меня =). Еще раз, спасибо за ваше время!

Daniel 18.03.2022 18:54

Другие вопросы по теме