浏览器刷新出现“白屏”,本质原因通常是:HTML 已加载,但 JS/CSS 或接口数据未就绪,页面没有可渲染内容。要做到“刷新不白屏”,核心思路是:
👉 让用户在任何阶段都能看到可用内容(骨架/占位/缓存/服务端渲染)
✅ 一、最简单:HTML 中放一个「Loading 骨架屏」
在 index.html 中的 #app 里直接写静态骨架内容,而不是空 div。
<div id="app">
<div class="skeleton">
页面加载中...
</div>
</div>
等 Vue/React 挂载后会自动替换。
优点:
- 几乎零成本
- 解决“纯白屏”的观感问题
- 非常常用
可以配合 CSS 动画骨架屏:
.skeleton {
height: 100vh;
background: linear-gradient(90deg,#eee,#f5f5f5,#eee);
animation: loading 1.5s infinite;
}
✅ 二、开启资源预加载 / 减少首屏 JS 体积
白屏的另一个原因是:JS 包太大,下载慢。
1. 代码分包(webpack / vite)
const Home = () => import('./Home.vue')
2. gzip / brotli 压缩
服务器开启:
- gzip
- brotli
3. CDN 加速静态资源
✅ 三、使用缓存:Service Worker / PWA(进阶)
思路:
刷新时,先从缓存渲染旧页面,再后台更新新资源
即 stale-while-revalidate 策略。
适合:
- 管理系统
- 内部系统
- 对实时性要求不极端的页面
✅ 四、关键方案:SSR / 预渲染(根治白屏)
如果你是 SPA(Vue / React):
刷新时流程是:
下载 index.html(空)
下载 js
执行 js
渲染页面
SSR 后变成:
index.html 直接就是完整页面
常见方案:
- Vue: Nuxt
- React: Next.js
- 预渲染:prerender-spa-plugin
优点:
- 刷新几乎无白屏
- SEO 友好
- 首屏速度极快
✅ 五、常见“隐藏白屏”技巧
1. 保留上一次页面快照(骨架替换)
if (document.getElementById('app').innerHTML === '') {
showSkeleton()
}
2. 接口 loading 占位
<div v-if="loading">加载中...</div>
<div v-else>真实内容</div>
❌ 常见导致白屏的坑
-
JS 报错(直接渲染失败)
- 打开控制台看 error
-
路由懒加载失败
-
接口未返回就 render 空结构
-
静态资源 404
-
chunk hash 变化,旧页面引用新 js 失败
👉 生产环境建议加:
window.onerror = function(e) {
// 上报错误
}
最低成本方案:
骨架屏 + loading + gzip + 分包
较优方案:
骨架屏 + 预渲染 + CDN
最佳体验:
SSR(Nuxt / Next)+ Skeleton