如何在Shiny应用加载大JavaScript文件前显示加载动画?
解决Shiny加载大型JS文件时启动动画延迟显示的问题
问题原因
浏览器会同步加载并执行<head>标签内的脚本,你的17MB大型JS文件会阻塞页面后续内容的解析与渲染——这就导致shinybusy的启动动画要等JS加载完成后,才能被浏览器渲染出来。
解决方案1:异步加载JS文件
给加载大型JS的<script>标签添加async或defer属性,让浏览器在加载JS的同时继续渲染页面,从而提前显示加载动画。
async:JS加载完成后立即执行(不保证顺序),适合无依赖的独立JS文件defer:JS加载完成后等待DOM解析完毕再执行,保证执行顺序,适合依赖DOM或其他脚本的文件
修改后的代码:
library(shiny) library(shinybusy) library(bslib) ui <- page_sidebar( tags$head( # 添加async属性实现异步加载 tags$script(src = "HUGE_JAVASCRIPT_FILE.js", async = TRUE) ), busy_start_up( loader = spin_epic("orbit", color = "#FFF"), text = "Loading...", timeout = 1500, color = "#FFF", background = "#112446" ), title = "Gröbner implicitization with GIAC", sidebar = sidebar( textInput( "equations", "Equations: ", value = "x = a*cost, y = b*sint" ), textInput( "relations", "Relations: ", value = "cost^2 + sint^2 = 1" ), textInput( "symbols", "Symbols: ", value = "cost, sint, a, b" ), actionButton("go", "Run", class = "btn-primary") ) ) server <- function(input, output, session) { } shinyApp(ui, server)
解决方案2:自定义加载动画(更可靠)
如果JS文件有依赖关系、异步加载会引发问题,可以直接在页面最顶部添加纯HTML/CSS实现的加载动画,通过JS监听文件加载完成事件来隐藏动画,完全规避Shiny组件的加载顺序限制。
修改后的代码:
library(shiny) library(bslib) ui <- tagList( # 自定义加载动画的样式 tags$style( " #loading-screen { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: #112446; display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 9999; /* 确保动画在最上层 */ } /* 仿shinybusy的orbit旋转动画 */ .orbit-loader { width: 60px; height: 60px; border: 3px solid rgba(255,255,255,0.3); border-top-color: #FFF; border-radius: 50%; animation: orbit 1s linear infinite; } @keyframes orbit { to { transform: rotate(360deg); } } .loading-text { color: #FFF; margin-top: 20px; font-size: 18px; } " ), # 加载动画DOM元素(放在页面最开头,优先渲染) tags$div( id = "loading-screen", tags$div(class = "orbit-loader"), tags$div(class = "loading-text", "Loading...") ), # 加载大型JS,监听加载完成事件隐藏动画 tags$head( tags$script( src = "HUGE_JAVASCRIPT_FILE.js", onload = "document.getElementById('loading-screen').style.display = 'none';" ) ), # 原页面内容 page_sidebar( title = "Gröbner implicitization with GIAC", sidebar = sidebar( textInput( "equations", "Equations: ", value = "x = a*cost, y = b*sint" ), textInput( "relations", "Relations: ", value = "cost^2 + sint^2 = 1" ), textInput( "symbols", "Symbols: ", value = "cost, sint, a, b" ), actionButton("go", "Run", class = "btn-primary") ) ) ) server <- function(input, output, session) { } shinyApp(ui, server)
内容的提问来源于stack exchange,提问作者Stéphane Laurent
相关产品推荐
相关产品推荐

