使闪亮应用程序运行得更快的最佳实践是什么?

时间:2016-06-29 06:56:11

标签: r shiny

数据:

我有一个闪亮的仪表板应用程序,我的数据集大小约为600 MB。它每月膨胀100 MB。我的数据驻留在MySQL本地。

的MenuItems:

我的仪表板上有6到7个侧边栏menuItem,每个都有10-12个不同的输出 - 图表和表格。这些选项卡中的每一个都有3到6个输入,例如selectizeInput,滑块,日期范围等,以过滤数据。

数据子集:

由于我无法将所有数据加载到内存中,因此对于每个菜单项,我都会根据日期范围创建一个数据子集,方法是将日期范围保持为系统日期后的2-3天。

例如:

df1 <- reactive({df[df$date >- dateinput[1] & df$date <- dateinput[2], ]})

以上获取我的第一个菜单项的数据,并根据selectInput或其他输入,我进一步过滤数据。例如,如果我有Gender (male and female)的selectInput,那么我将df1进一步子集化为:

df2 <- reactive({
       if(is.null(input$Gender)){ 
          df1 
       } else if(input$Gender == "Male") 
          {df1[df1$Gender == "Male",]} 
       )}

如果我有超过1个输入,我进一步将这个df1子集化并将值传递给df2。 df2成为该MenuItem中所有图表和表的反应数据集。

menuItem的数量越多,我就会创建更多的子集以适应过滤器和分析。

我面临两个问题:

  1. 在较旧的计算机上,该应用未加载。和
  2. 在较新的机器上,应用程序加载速度非常慢,有时为5 - 6分钟
  3. 在第一组数据加载后,图表和表格在反应性更改时呈现得更快。

    为了解决这个问题,我尝试将所有常见和重复的参数和库移动到global.R。

    我有两个问题:

    1.在R中挖掘数据时需要记住任何基本的卫生因素,特别是通过闪亮(R中挖掘速度非常快)。

    2.我已阅读有关并行处理的内容,但几乎所有示例都谈到分发单个较重的计算。我们可以通过并行处理,分组数据或分发图表/表格准备进行分发。

    请注意,我是研究员而不是程序员,但他们已经学会在云上或最近在本地使用闪亮和主机应用程序。

    这对我的许多新手用户非常有帮助。

1 个答案:

答案 0 :(得分:12)

这是一个非常有趣的问题,值得更多正确的响应而不是评论。 我想谈谈我的经历和想法。我使用Shiny Server Pro构建了一个商业R+shiny应用程序,使用了数据库和其他技巧。

延迟的用户界面加载时间
我的应用程序需要超过30秒才能加载,即将控制权交还给用户。

问题

Shiny是一个单页面应用程序。因此,一个复杂的应用程序,加载了标签,加载数据以填充一些菜单和选择器等受到影响,这从初始加载时间开始。

UI可能的缓解措施

  • 使用动态UI组件(明智地)在启动后添加复杂性。例如,特定菜单可以非常简单地以少量元素开始,然后在稍后阶段添加更多元素。
  • 当我的应用差不多时,Joe Cheng提出了insertUIremoveUI 完了,所以我没有到处使用它们,但它们也可以 有助于创建一个更简单的页面。

使用数据库

我的应用使用了MonetDB以及之后的PostgreSQLMonetDB的表现很好,但是我遇到了多个用户冲突(复杂的问题,我在这里不详述),这迫使我转移到PostgreSQL作为替代。 PostgreSQL很好,但由于缓存预热问题,需要花费大量时间才能启动。在启动数据加载到DB时需要进行设计:糟糕的设计。

RDBMS延迟了可能的缓解措施

我认为我尝试了大多数技巧并取得了不同的成功。

  • 限制RDBMS使用。我从一开始就决定使用data.table 通过复制加速数据操作而不受限制,I 也使用fread进行任何类型的csv阅读。当时 fwrite(仍来自data.table)甚至不在地平线上, 否则值得认真考虑。
  • 应用程序重新设计。应用程序架构与学位有很大关系 使用RDBMS的强度。我确信时间可以 通过可以考虑R+shiny(主要是R)的设计保存 限制。
  • 现在MonetDB已将R个函数嵌入到代码中,因此它应该是 甚至比以前更快。它当然值得一看。在另一 应该彻底测试多用户功能:大多数R 数据库代码不考虑在多用户中使用 shiny提供的环境。也许RStudio应该这样做 更多关于这个的事情。老实说他们已经开始了 connection pools的实验性介绍,这很棒。

过度使用反应性

我认为使用像shiny这样的高级框架非常棒,而且反应性很有趣。另一方面,在广泛而复杂的应用程序中,事情很容易失控。

过度反应可能的缓解

  • 调试每个函数可以准确地了解多少时间a 调用特定的shiny函数,任何反应函数都是 通常不止一次打电话。当然这一切都会烧掉cpu时间,而且 至少需要保持控制。
  • observeEvent这样的构造现在有ignoreInit之类的参数: 明智地使用这些参数可以至少节省空隙周期 初始化时间。

根据我的经验,我们只涉及shiny可能做的事情。另一方面,由于R的单一过程性质,存在限制。使用Shiny Server Pro,可以设想使用负载平衡器并在不同服务器之间分布多个用户。另一方面,为了进入这些领域,我们需要在各种实例中使用某种消息传递系统。我已经知道在复杂的Shiny Server Pro应用程序中需要这样做(例如,当需要管理不同类别的用户,但同时在它们之间进行通信时)。但这超出了这个SO问题的范围。