白屏如何分析
面试回答总框架
线上页面白屏,我不会一上来就猜是 JS 报错,而是先把问题拆成三步:
- 定范围:全量还是部分用户;首屏白屏还是操作后白屏;单页面白屏还是全站白屏。
- 定阶段:页面从 URL 到可见内容,会经过 HTML、静态资源、JS 执行、框架挂载、接口请求、DOM/CSS 展示等阶段。白屏一定卡在某一层。
- 定证据:用监控、DevTools、错误日志、发布记录、灰度配置、用户环境互相印证,不只靠本地复现。
一句话回答:
我会按
HTML -> 静态资源 -> JS 执行 -> 框架挂载 -> 接口数据 -> DOM/CSS 展示 -> 灰度/缓存/兼容性这条链路逐层排查;线上先止血,再定位根因,最后从发布、代码兜底和监控告警上治理。
先判断白屏是哪一种
面试时可以先主动把白屏分类,这会显得思路很稳。
记忆口诀:
Case 1:HTML 文档没有正常返回
现象
- 页面完全空白。
- Network 里
document请求不是200。 - 返回的是错误页、登录页、网关页,而不是业务 HTML。
- 某些地区、运营商、CDN 节点访问异常。
怎么证明
打开 DevTools 的 Network,先看 document 类型请求:
- 状态码是否是
200,有没有404、500、502、504。 content-type是否是text/html。- Response 内容是不是正常 HTML。
- HTML 里引用的 JS/CSS 路径是否正确。
- 是否命中了旧 HTML、错误 HTML、灰度 HTML。
如果 HTML 都没有正常返回,就不是 React/Vue 组件本身的问题,要往 CDN、Nginx、网关、服务端、DNS、证书方向查。
怎么处理
- 查 CDN 边缘节点和回源状态。
- 查 Nginx/网关访问日志。
- 检查发布时是否改了
base、路由 fallback、静态目录。 - 如果是全量问题,优先回滚或切回上一版 HTML。
面试追问
追问:你本地打开正常,但用户说白屏,怎么办?
自己能打开只能说明不是全量故障,不能证明线上没问题。我会拿到用户的 URL、时间、账号、地区、浏览器、设备、版本、是否灰度、监控 eventId,再按地域、UA、CDN 节点、release、用户 ID 聚合,看是不是某一类用户集中异常。
追问:HTML 返回了 200 就一定正常吗?
不一定。200 只能说明请求成功,还要看返回内容是不是业务 HTML。有些场景会把登录页、错误页、网关兜底页、旧 HTML 以 200 返回,前端看起来仍然会白屏。
Case 2:JS/CSS 静态资源加载失败
现象
- HTML 正常返回,但入口 JS 没有执行。
- Network 里 JS/CSS 出现
404、5xx、MIME type 错误、CORS 错误、SRI 校验失败。 - 页面只有一个空的
#root或#app。
现代 SPA 的 HTML 往往只有:
真正内容依赖 JS 渲染。如果入口 JS 加载失败,根节点永远不会挂载业务 DOM,用户看到的就是白屏。
怎么证明
重点看 Network:
- JS/CSS 是否都是
200。 - JS 文件是否实际返回了 HTML 错误页。
content-type是否正确,例如 JS 应该是 JavaScript MIME。- CDN 上资源是否存在。
- HTML 引用的 hash 文件是否和部署产物一致。
常见原因
- 用户拿到新 HTML,但 CDN 上新 JS 还没同步完成。
- 用户拿到旧 HTML,但旧 JS 已经被清理。
- 构建产物带 hash,但部署没有做到原子切换。
- Nginx fallback 把 JS 请求转成了 HTML。
- CDN CORS、
crossorigin、SRI hash 配置错误。
怎么处理
- 静态资源带 hash 后长期缓存,不覆盖、不提前删除。
- HTML 使用短缓存或协商缓存。
- 发布顺序改成先上传静态资源,再切换 HTML。
- 保留上一版本资源一段时间。
- 发布失败时能快速回滚 HTML 和静态资源。
面试追问
追问:如何区分资源加载失败和 JS 执行失败?
资源加载失败主要看 Network,入口 JS/CSS 请求会失败、返回错误内容或被浏览器拒绝执行;JS 执行失败通常资源是 200,但 Console 或错误监控里有运行时异常,堆栈指向入口、路由、状态初始化或组件。
追问:为什么发布后老用户白屏,新用户正常?
老用户可能命中了浏览器缓存、CDN 缓存或 Service Worker,拿到了旧 HTML/旧 runtime/旧 chunk 的混合版本;新用户首次访问拿到的是完整新版本。治理要靠 hash 资源长期保留、HTML 短缓存、资源先发再切 HTML、Service Worker 更新策略。
Case 3:JS 执行时报错
现象
- 静态资源加载成功。
- Console 或监控出现 JS runtime error。
- 错误发生在首屏渲染之前。
- 白屏用户和错误用户高度重合。
怎么证明
不要只说“看 Console”,更完整的证据链是:
- 错误发生时间早于首屏渲染时间。
- 错误堆栈指向入口文件、路由初始化、全局状态初始化、首屏组件。
- 错误 release 和白屏 release 一致。
- 错误用户集合和白屏用户集合高度重合。
- 本地切到同版本、同参数、同账号状态可以复现。
常见原因
- 读取空对象:
Cannot read properties of undefined。 - 低版本浏览器不支持新语法或新 API。
- 第三方 SDK 初始化异常阻断主流程。
- 路由懒加载 chunk 加载失败。
- 环境变量缺失,入口初始化直接
throw。 - 本地缓存里的旧 chunk 与新 runtime 不匹配。
监控怎么做
至少要捕获两类错误:
React 项目要有 Error Boundary,Vue 项目要配置 app.config.errorHandler。
面试追问
追问:错误栈只有 app.js:1:12345 怎么定位?
要通过 release 版本找到对应 Source Map,在服务端还原堆栈。错误上报时必须带 release、构建 commit、文件名、行列号、用户环境,监控系统再用对应版本的 Source Map 把压缩位置还原到源码组件和行号。
追问:为什么第三方 SDK 也会导致白屏?
如果 SDK 初始化放在入口主流程里,而且失败后没有 try/catch 或降级,就可能阻断 render。第三方 SDK 应该异步加载、失败降级,不能成为 App 挂载的强依赖。
Case 4:框架没有挂载成功
现象
- HTML 和资源都正常。
- Console 没有明显 JS 报错。
#root或#app下没有业务 DOM。- 页面可能一直停在 Loading 或直接空白。
怎么证明
检查这些点:
#root或#app是否存在,入口选择器是否写错。createRoot(...).render(...)或app.mount(...)是否执行。- 路由是否匹配到页面组件。
- 权限守卫是否把用户重定向到空路由。
- 根组件是否因为状态判断直接返回
null。 - 异步组件、懒加载组件是否一直没有 resolve。
典型例子
如果 loading 因为接口异常一直是 true,页面就永久返回 null。这不是资源问题,也不一定有 JS 报错,但用户看到的是白屏。
更稳妥的写法是:
面试追问
追问:没有报错为什么也会白屏?
因为白屏不一定来自异常,也可能来自“合法地渲染了空”。比如根组件返回 null,路由没有匹配,权限状态一直初始化中,Suspense 没有合适 fallback,这些都可能没有错误栈,但页面没有内容。
追问:如何避免框架挂载层面的白屏?
入口要有兜底 UI;全局异步状态必须有 loading、error、timeout、retry;路由要有 404/兜底页面;懒加载失败要能重试;错误边界不能把整个页面兜成空白。
Case 5:首屏接口阻塞渲染
现象
- 页面壳出现了,但核心内容一直不出来。
- Network 里 XHR/Fetch pending 很久,或者出现
401、403、500、跨域失败。 - 根组件或页面组件把接口成功作为渲染前置条件。
怎么证明
看 XHR/Fetch:
- 是否 pending 时间过长。
- 是否接口失败后没有进入 error 状态。
- 是否一个接口失败阻塞后续所有请求。
- 是否接口返回结构变化导致前端渲染异常。
- 是否权限、用户信息、路由配置等关键接口没有兜底。
怎么处理
首屏接口要分级:
面试中可以这样说:
我不会让所有接口都成为首屏前置条件。首屏只等待决定页面结构的关键数据,其他模块局部 loading、局部失败,不能把整个 App 渲染成空。
面试追问
追问:为什么接口失败会导致白屏?
因为代码可能把接口成功当成渲染前置条件。例如用户信息、权限、路由配置不返回时,根组件一直返回 null 或全局 Loading。解决不是假设接口永远成功,而是关键接口失败要有超时、错误页、重试和降级。
追问:接口 401 导致白屏怎么处理?
401 应该进入登录态处理或刷新 token 流程。如果刷新失败,要跳登录页或展示明确错误,不能让权限初始化一直 pending。权限链路尤其要避免“等待用户信息 -> 用户信息 401 -> 状态不落地 -> 永久 loading”。
Case 6:DOM 已经渲染,但被 CSS 或布局隐藏
现象
- Elements 里能看到业务 DOM。
- 页面肉眼仍然是白色或只有空区域。
- 关闭某些样式后内容出现。
常见原因
- 根节点高度为
0。 - 内容颜色和背景色相同。
- 全屏 Loading、蒙层、空 div 覆盖内容。
z-index层级错误。opacity: 0、visibility: hidden、display: none没被恢复。- 移动端安全区、视口单位、兼容样式导致内容被挤出屏幕。
怎么证明
在 Elements 面板里看:
#root下是否已经有业务 DOM。- 选中首屏元素,看 computed style。
- 临时关闭可疑样式,看内容是否出现。
- 执行
document.body.innerText判断是否有文本内容。 - 截图或采样点判断首屏是否全是背景色。
核心判断:
有 DOM 但不可见,是 CSS/布局问题;没有 DOM,继续查 JS、框架、接口链路。
面试追问
追问:如果 FCP 有,但用户仍说白屏,说明什么?
说明浏览器确实绘制过内容或背景,但首屏主内容可能没出现。可能是 CSS 隐藏、全屏 Loading、主接口慢、LCP 元素迟迟不出现,所以要结合 LCP、关键元素检测、截图和 DOM 状态判断。
Case 7:只有部分用户白屏
现象
- 某些浏览器、WebView、地区、账号、灰度组出现。
- 新用户正常,老用户异常。
- 线上错误率不是全量升高,而是集中在某些维度。
排查维度
兼容性怎么查
典型表现:
- Chrome 正常,低版本 Safari/Android WebView 白屏。
- Console 报
Unexpected token。 - Console 报
Object.fromEntries is not a function、ResizeObserver is not defined。
治理方式:
- 检查 Browserslist、Babel/SWC 转译目标。
- 检查 polyfill 是否注入。
- 检查第三方依赖是否包含未转译的新语法。
- 用真实机型或浏览器云复现。
Service Worker 怎么查
Service Worker 可能让用户拿到“旧 HTML + 新 JS”或“新 HTML + 旧 JS”。
治理方式:
- HTML 使用 network first。
- hash 静态资源使用 cache first。
- SW 更新后提示用户刷新。
- 发布异常时可以远程关闭或跳过 SW。
- 缓存策略区分 HTML、静态资源、接口。
面试追问
追问:灰度问题怎么处理?
先关灰度或实验开关止血,再定位代码。灰度的价值就是把影响面限制住,不能让用户等我们慢慢排查。定位时对比实验配置、远程字段、新组件加载路径和白屏用户集合。
追问:如何证明是兼容性问题?
按 UA 和系统版本聚合错误率。如果白屏集中在低版本 Safari、Android WebView 或某个厂商浏览器,同时错误是语法/API 不支持,再用对应真机复现,就能形成证据链。
Case 8:线上监控如何发现白屏
白屏不能只靠用户反馈,应该主动监控。
白屏检测
基础版本可以检查根节点是否有内容:
但只判断 #root.children.length === 0 不够,它只能发现“根节点没挂载”。更可靠的方案要结合:
- 根节点子元素数量。
- 首屏关键元素是否出现。
- 页面截图或采样点是否都是背景色。
- FP、FCP、LCP 是否异常。
- JS error、resource error、API error 是否同时发生。
资源错误监控
第三个参数要用 true,因为资源加载错误通常不会冒泡,需要在捕获阶段监听。
指标怎么解释
面试追问
追问:白屏检测只看根节点够吗?
不够。有些页面有 DOM,但被 CSS 隐藏;有些页面一直显示全屏 Loading;有些页面只渲染了壳,核心内容没出来。所以要结合关键元素、采样点、性能指标、资源错误、JS 错误、接口错误一起判断。
Case 9:线上如何止血
白屏是高优问题,排查和止血要并行。
全量白屏
优先级:
- 回滚最近发布。
- 切回上一版 HTML。
- 恢复上一版静态资源。
- 关闭高风险远程配置。
- 通知服务端、网关、运维一起看核心链路。
全量白屏不要边猜边修,先恢复用户可用性。
部分白屏
优先级:
- 关闭对应灰度、实验、远程开关。
- 降级问题模块。
- 对特定浏览器或 WebView 走兼容降级。
- 保留现场数据:版本、用户、UA、错误栈、接口状态、资源状态。
新版本白屏
先回滚或暂停发布,然后按 release 定位:
- 新增依赖是否引入兼容问题。
- 构建配置是否变化。
- 路由表、权限、接口字段是否变化。
- 静态资源上传和 HTML 切换顺序是否变化。
面试追问
追问:全量白屏先排查还是先回滚?
先止血。全量白屏影响核心路径,优先回滚、切旧版本、关开关,同时保留日志和现场。恢复后再复盘根因。只有回滚风险更大或无法回滚时,才考虑热修。
最终背诵模板
面试时可以直接按这个版本回答:
一句话总结
白屏排查的核心不是猜原因,而是按页面加载链路逐层证明;线上先止血,定位靠证据,复盘要落到发布机制、兜底渲染和监控告警。

