
Apesar de suas vantagens, os Dynamic Shiny Modules podem desestabilizar o ambiente Shiny e fazer com que seu gráfico reativo seja renderizado várias vezes. Neste post do blog, apresento como remover as sobras do módulo excluído e certifique-se de que seus observadores gráficos brilhantes sejam renderizados apenas uma vez.
Ao trabalhar com aplicativos Shiny avançados, você provavelmente encontrou a necessidade de usar Módulos brilhantes. Os Módulos brilhantes permitem modularizar o código, reutilizá-lo para criar vários componentes usando funções únicas e impedir a duplicação do código.
Talvez o melhor recurso do Shiny Modules seja a capacidade de criar elementos dinâmicos de aplicativos. Uma ótima implementação disso pode ser encontrada aqui. Este exemplo específico fornece lógica conveniente para adicionar e remover variáveis e seus valores de maneira reativa.
A implementação de módulos brilhantes vem com alguns desafios que podem afetar a estabilidade do seu ambiente brilhante. Neste artigo, mostrarei como superá-los.
Contents
Removendo os restos de um módulo obsoleto
A remoção de um módulo pode ter um impacto desestabilizador no ambiente do aplicativo Shiny. Para ilustrar esse problema, vamos considerar simples inscrição:
O aplicativo permite ao usuário criar (e remover) um novo módulo que conta o número de cliques do botão colocado dentro do módulo. O número de cliques também é exibido fora do módulo para ver o valor do módulo interno após a remoção do módulo.
A expectativa é que a remoção do módulo remova seus objetos internos, incluindo valores de entrada. Infelizmente, esse não é o caso:
De fato, a remoção do módulo afeta apenas a parte da interface do usuário enquanto os valores reativos do módulo ainda estão no ambiente da sessão Shiny e são reescritos logo após a chamada de um novo módulo. Isso se torna particularmente problemático quando o módulo armazena grandes entradas. A adição de um novo módulo agrega a memória usada pelo aplicativo e pode esgotar rapidamente toda a RAM disponível no servidor que hospeda o aplicativo. Esse problema pode ser resolvido com a introdução do remove_shiny_inputs função, conforme explicado aqui. A função permite remover valores de entrada de um módulo Shiny não utilizado.
Em nossa implementação, o uso da função requer uma modificação simples do evento remove_module:
|
Removendo observadores internos que se registraram várias vezes
A segunda questão provavelmente contribuiu para que o cabelo fosse arrancado da cabeça de muitos programadores brilhantes.
Os eventos de observação, assim como os valores reativos no exemplo acima, não são removidos quando um módulo é excluído. Nesse caso, o problema é ainda mais sério – o observador obsoleto é replicado em vez de substituído. Como resultado, o observador é acionado tantas vezes quanto o novo módulo (com o mesmo ID) foi criado.
Em nosso exemplo, adicionar uma função de impressão simples dentro de um observeEvent mostra a essência desse problema:
|
Esse comportamento pode fazer com que seu aplicativo desacelere significativamente em apenas alguns minutos de uso.
A solução mais rápida para esse problema é uma solução alternativa que requer que o desenvolvedor crie novos módulos com identificadores exclusivos. Dessa forma, cada novo módulo cria um observador único e os observadores anteriores não são mais acionados.
A solução adequada, não tão conhecida, é oferecida diretamente pelo pacote Shiny e não requer nenhuma solução alternativa hacky. Começamos atribuindo o observador à variável selecionada:
O objeto my_observer agora nos permite usar vários métodos úteis relacionados ao observador criado. Um deles, destruir(), fornece a remoção correta de um observador brilhante de seu ambiente, com:
Temos duas opções para aplicar esta solução ao nosso exemplo.
A primeira abordagem exige a atribuição do observador do módulo a uma variável acessível diretamente no servidor Shiny. Por exemplo, podemos usar reactiveVal que é passado para o módulo e projetado para armazenar observadores.
A segunda abordagem utiliza o objeto $ userData da sessão (veja a postagem no blog de Marcin)
Decidimos usar a segunda abordagem, portanto atribuímos um observador à variável `session $ userData $ my_observer`:
|
Em seguida, modificamos o evento remove_module adicionando uma ação de destruição à variável que acabamos de criar:
|
O resultado atendeu às nossas expectativas:
O código final do aplicativo está disponível aqui.
Conclusão
O Shiny oferece excelentes funcionalidades para a criação de aplicativos interativos avançados.
Embora esse pacote poderoso seja fácil de usar, ainda precisamos gerenciar adequadamente os objetos de baixo nível do aplicativo para garantir o desempenho ideal. Se você tiver algum exemplo de como lutou para resolver outros desafios Shiny menos comuns, compartilhe na seção de comentários abaixo!
Siga-nos para mais
Artigo Como remover com segurança um módulo dinâmico brilhante vem do Appsilon Data Science | Soluções completas de ciência de dados.
Relacionado
Se você chegou até aqui, por que não inscreva-se para atualizações do site? Escolha o seu sabor: e-mail, twitter, RSS ou facebook …
*As fotos exibidas neste post pertencem ao post www.r-bloggers.com