浏览器刷新后页面白屏

85 阅读2分钟

浏览器刷新出现“白屏”,本质原因通常是: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>

❌ 常见导致白屏的坑

  1. JS 报错(直接渲染失败)

    • 打开控制台看 error
  2. 路由懒加载失败

  3. 接口未返回就 render 空结构

  4. 静态资源 404

  5. chunk hash 变化,旧页面引用新 js 失败

👉 生产环境建议加:

window.onerror = function(e) {
  // 上报错误
}

最低成本方案:

骨架屏 + loading + gzip + 分包

较优方案:

骨架屏 + 预渲染 + CDN

最佳体验:

SSR(Nuxt / Next)+ Skeleton