You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny原油统计应用代码优化与加载提速技术求助

问题1:代码冗余优化

UI端标签页结构优化

如果当前UI是手动重复编写tabPanel创建图表标签页,可先定义图表配置列表,再通过循环批量生成标签页,避免重复代码:

# 定义所有图表的ID与标题
chart_config <- list(
  list(id = "prod_trend", title = "原油产量趋势"),
  list(id = "import_data", title = "原油进口数据"),
  list(id = "stock_change", title = "库存变化分析")
)

# 在UI中批量生成标签页
ui <- navbarPage(
  "EIA石油数据统计",
  lapply(chart_config, function(item) {
    tabPanel(
      item$title,
      plotlyOutput(item$id)
    )
  })
)

Server端renderPlotly循环优化

对应UI的图表ID,在Server端通过循环批量生成renderPlotly输出,无需重复编写每个绘图逻辑:

server <- function(input, output, session) {
  # 拉取并统一处理数据(假设最终整理为df)
  df <- reactive({
    # 这里是Google Sheet数据拉取与清洗逻辑
  })
  
  # 循环生成各图表的渲染函数
  lapply(chart_config, function(item) {
    output[[item$id]] <- renderPlotly({
      # 根据图表ID匹配对应的绘图逻辑,可封装为单独函数
      plot_data <- df() %>% filter(category == item$id)
      plot_ly(plot_data, x = ~date, y = ~value, type = "scatter", mode = "lines")
    })
  })
}

如果不同图表的绘图逻辑差异大,可把绘图逻辑封装成独立函数(如plot_prod_trend(df)),在循环中根据ID调用对应函数,进一步简化代码。


问题2:加载耗时优化分析与方案

耗时原因分析

  1. Google Sheet拉取效率低:默认拉取方式会自动推断列类型、请求元数据,加上网络延迟,11k行数据会消耗较多时间;若没有缓存,每次启动/刷新都会重复请求。
  2. 数据处理冗余:若每个renderPlotly中重复执行过滤、转换等操作,会导致重复计算,增加加载时间。
  3. 初始化阻塞:若数据拉取/处理放在Server函数顶层(非reactive),会阻塞应用启动,直到数据处理完成。

具体优化方案

1. 缓存Google Sheet数据

用memoise缓存数据拉取结果,避免重复请求:

library(memoise)
library(googlesheets4)

# 缓存数据拉取函数,设置过期时间(示例:每1小时更新一次)
get_gs_data <- memoise(function() {
  # 指定col_types减少类型推断耗时,只拉取需要的列
  read_sheet(
    "你的Google Sheet链接",
    col_types = "Dcnn", # 日期、字符、数值、数值
    range = "A:D"
  )
}, timeout = 3600)

# 在reactive中统一处理数据
df <- reactive({
  get_gs_data() %>% 
    mutate(date = as.Date(date), value = as.numeric(value)) %>% 
    drop_na()
})

2. 提前统一处理数据

在df() reactive中一次性完成所有数据清洗、转换、计算(如滚动均值、分类汇总),绘图时直接取用处理好的数据,避免重复计算。

3. 异步加载数据

用Shiny异步功能让UI先加载,后台拉取数据,减少用户等待空白页面的时间:

library(shiny)
library(promises)
library(future)

plan(multisession) # 启用异步处理

server <- function(input, output, session) {
  # 异步拉取并处理数据
  df <- reactiveFuture({
    get_gs_data() %>% 
      mutate(date = as.Date(date), value = as.numeric(value)) %>% 
      drop_na()
  })
  
  # 绘图时先确保数据加载完成
  lapply(chart_config, function(item) {
    output[[item$id]] <- renderPlotly({
      req(df())
      plot_data <- df() %>% filter(category == item$id)
      plot_ly(plot_data, x = ~date, y = ~value, type = "scatter", mode = "lines")
    })
  })
}

4. 优化部署配置(针对shinyapps.io)

  • 升级实例大小,获得更多CPU/内存资源
  • 启用Persistent Storage,缓存数据避免实例重启后重复拉取

内容的提问来源于stack exchange,提问作者Romain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 14:25:53