Vite 白屏刷新问题分析
问题现象
在 Vite 开发模式下,修改代码后保存,浏览器页面会出现短暂的白屏闪烁,然后重新渲染内容。
原因分析
Vite 使用 HMR(Hot Module Replacement) 来实现热更新,但在以下情况会退化为全量刷新(Full Reload):
| 场景 | 行为 | 说明 |
|---|---|---|
| 修改组件模板 | HMR | 局部热替换,无白屏 |
| 修改组件脚本 | HMR | 局部热替换,组件状态可能丢失 |
| 修改 CSS | HMR | 样式热替换,无白屏 |
| 修改环境变量 | Full Reload | 需要重启 Vite Dev Server |
| 修改入口文件 | Full Reload | main.ts/index.html 变更 |
| 修改配置文件 | Full Reload | vite.config.ts 变更 |
| HMR 边界失效 | Full Reload | 无法找到合适的 HMR 边界 |
白屏的具体原因
- 全局状态丢失:Pinia/Vuex 中的状态在 Full Reload 时会被重置
- 路由重置:Vue Router 重新初始化,回到初始路由
- 组件树重建:所有组件重新挂载,之前的 DOM 被清除
优化方案
方案一:配置 HMR 保留状态
// vite.config.ts
export default defineConfig({
server: {
hmr: {
overlay: false // 禁用错误覆盖层闪烁
}
},
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag.includes('-')
}
}
})
]
})
typescript
方案二:Pinia 持久化
// 使用 pinia-plugin-persistedstate
const useUserStore = defineStore('user', {
state: () => ({
token: '',
userInfo: null
}),
persist: {
key: 'user-store',
storage: localStorage,
paths: ['token', 'userInfo']
}
})
typescript
方案三:减少 Full Reload 触发
- 将配置集中管理,避免频繁修改
vite.config.ts - 环境变量使用
.env文件,通过import.meta.env访问 - 避免在入口文件中直接引入频繁变更的模块
生产环境的白屏问题
生产环境部署后的白屏通常是以下原因:
- JS 文件加载慢:使用代码分割和懒加载
- 没有 Loading 状态:在
index.html中添加静态 Loading 动画 - CDN 资源加载失败:配置资源 fallback
↑