为Shiny应用程序进行代码分析?

30
在一个 R Shiny 的 Web 应用中,有哪些好的方法可以运行代码分析并显示在处理时间方面消耗最多的 Shiny 代码部分?
我有一个庞大、复杂的 Shiny 应用程序,我想找出我在这个代码迷宫中最拖慢 Shiny 应用程序的地方。我尝试了 Rprof 和 profr,但没有得到太多的见解。

23
在同一个句子中说出“又大又胖又闪亮”,而不冒犯任何人,这个表现值得点赞。 - Brandon Bertelsen
3个回答

16

我认为这个问题需要一些更新,因此我会添加另一个答案...

您可以使用profvis软件包来对shiny应用程序进行性能分析。它将为您的R代码直接提供火焰图。也就是说,不需要使用Chrome的火焰图并猜测瓶颈在哪里。您将确切地知道需要在哪里更改代码。

以下是具体操作:

  1. 通过Profvis运行shiny应用程序
  2. 与shiny应用程序进行交互
  3. 关闭浏览器
  4. 通过Stop按钮停止Console
  5. 加载概要文件
  6. 如果步骤5失败,请尝试转换为html(内存问题)

某些步骤的详细信息如下:

步骤1:运行profvis

library(profvis)
profvis({ runApp('directory_of_shiny_app') }  
    , prof_output = '/directory_to_save_profile')

步骤 5:加载您的个人资料

profvis(prof_input = '/path_to_save_output/random_name.Rprof') 

注意:Profvis会给您的文件随机命名。因此,您需要相应地更改输入路径。

第6步:转换为html格式

如果您有一个非常大的应用程序并且火焰图稍微长一点,可能需要执行此步骤。否则,您可能会收到错误消息:“Pandoc:...内存不足”。

p <- profvis(prof_input = '/path_to_save_output/file108f93bff877b.Rprof')
htmlwidgets::saveWidget(p, "/path_to_save_output/profile.html")

然后在浏览器中打开HTML文件。


10
一些(粗略的)想法:
  1. 在浏览器中对应用程序进行分析可能会有帮助。我有一个使用navbarPage的较大的应用程序,页面构建速度变慢了。在Chrome中使用分析工具(开发人员工具)可以确定“罪魁祸首”。修复/改进正在进行中。https://github.com/rstudio/shiny/issues/381#issuecomment-33750794
  2. 从应用程序的代码窗口运行分析器。使用shinyAce包 (https://github.com/trestletech/shinyAce),我可以编辑(和运行)代码,包括来自应用程序内部的分析器(即调用反应等)。请参阅下面的链接(R > Code)。请注意,服务器上的代码评估已停用,但如果您想尝试此功能,则应用程序的源代码位于github上(请参见About页面)。
  3. 将代码编写为常规的R函数,并由反应函数调用。我正在重写我的应用程序,以便它可以使用knitr进行“可再生研究”(R > Report)。这种重组使得更容易在R(studio)上使用分析库,而不需要启动应用程序。
  4. Rselenium是Selenium的R接口,用于Web应用程序的测试工具 (https://github.com/johndharrison/RSelenium)。我刚开始使用这个工具,但您可以使用它和像system.time这样的工具来比较不同组件的速度。

http://vnijs.rady.ucsd.edu:3838/marketing/


您可以使用RSelenium和browsermob代理创建HAR文件来记录您的Selenium会话。我在https://github.com/johndharrison/RBMproxy中提供了一个简短的示例,其中包含一些beta版的browsermob代理绑定。 - jdharrison
感谢@jdharrison。我不熟悉browsermobHAR文件。这是为了更容易地构建测试还是评估测试结果?看起来是后者。如果是这样,您会推荐使用它,而不是使用testthat,或者也许两者一起使用? - Vincent
HAR代表HTTP存档。它对于分析Web应用程序的各个组件的加载时间非常有用。它将与testthat一起使用。例如,当您切换到navbarPage时,它将突出显示加载缓慢的元素。 - jdharrison
听起来很不错John。你可以举个例子说明一下怎么做吗?也许可以用Shiny的其中一个展示应用? - Vincent

2

从我的经验来看:

  1. 在函数中使用插件print() 你可以找出哪个函数花费了大部分时间。 例如:

mydebug <- function(msg="[DEBUG]") { DEBUG <- FALSE if (DEBUG) { print(sprintf("%s - %s - %s", msg1, as.character(Sys.time()), as.character(deparse(sys.calls()[[sys.nframe()-1]])))) } } f <- function() { mydebug() ## 这里是原始函数定义 ..... mydebug() return(...) ## 返回值需要放在mydebug()之后 }

  1. 使用Chrome火焰图进行性能分析

您可以获得一个火焰图来发现时间花在哪里(例如哪个JS函数?是否由于布局而导致?)。

enter image description here

详细信息请参见:https://developers.google.com/web/tools/chrome-devtools/profile/rendering-tools/analyze-runtime?hl=en


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接