如何实现页面F5重载时的加载屏?路由事件不触发场景技术问询
页面重载场景下加载屏实现方案
首先明确核心问题:F5触发的页面全量重载会销毁原页面的所有JS上下文,前端路由实例还未完成初始化,因此routeChangeStart等路由事件不会被触发,需要绑定页面原生生命周期实现加载屏。
最优实现方案:静态内置加载屏
直接将加载屏的DOM和样式内置到入口HTML中,不需要等待JS加载执行即可优先渲染,是兼容性最好、感知最快的方案:
步骤1:在入口HTML插入静态加载屏
将加载屏代码放在index.html的<body>最开头,样式使用内联写法避免资源加载延迟:
<!DOCTYPE html> <html lang="zh-CN"> <head> <!-- 其他头部配置 --> <!-- 也可以把加载屏样式放在head的内联style里 --> <style> #initial-loading { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; background: #ffffff; z-index: 99999; transition: opacity 0.3s ease; } </style> </head> <body> <!-- 静态加载屏,页面解析时最先渲染 --> <div id="initial-loading"> <div class="loading-spinner">页面加载中...</div> </div> <!-- 应用挂载节点 --> <div id="app"></div> </body> </html>
步骤2:页面就绪后移除加载屏
根据项目类型选择对应的移除时机:
- 框架项目(Vue/React/Angular等):在根组件挂载完成后移除加载屏
// Vue 3 示例 import { onMounted } from 'vue' onMounted(() => { const loadingEl = document.getElementById('initial-loading') if (!loadingEl) return // 可选:加淡出过场效果 loadingEl.style.opacity = '0' setTimeout(() => loadingEl.remove(), 300) })// React 示例 import { useEffect } from 'react' useEffect(() => { const loadingEl = document.getElementById('initial-loading') if (!loadingEl) return loadingEl.style.opacity = '0' setTimeout(() => loadingEl.remove(), 300) }, []) - 原生JS项目:监听
window.load事件,所有资源加载完成后移除window.addEventListener('load', () => { const loadingEl = document.getElementById('initial-loading') loadingEl?.remove() })
与路由切换加载逻辑复用
该方案和原有路由切换加载逻辑完全不冲突:
- 页面首次加载/重载场景:由静态加载屏负责展示
- 单页应用内部路由切换场景:继续使用原有
routeChangeStart/routeChangeComplete事件控制加载屏展示
两种场景的加载UI可以统一设计样式,用户不会感知到差异。
注意事项
- 加载屏的样式必须是内联或者写在HTML头部的内联样式中,不能放在异步加载的CSS资源里,否则会出现白屏后才显示加载屏的问题
- 加载屏的
z-index需要设置为全局最高值,避免被其他提前渲染的DOM遮挡 - 如果页面有首屏接口请求依赖,可以把加载屏的移除时机延后到首屏接口返回后,避免出现加载屏消失后页面仍为空的情况
内容的提问来源于stack exchange,提问作者QUANG Tuấn Vũ
相关产品推荐
相关产品推荐

