从输入URL到页面显示的完整链路:缓存、渲染与排障实战 前几天模拟面试我给候选人出了这道经典题——从输入URL到浏览器显示页面到底发生了什么。候选人一听就笑了说这道题背过。然后他从DNS解析开始背一路背到渲染没有卡壳。但我追问了一个小问题如果服务端返回的Content-Type是text/plain浏览器会把HTML当普通文本直接显示源码吗他愣住了。那一刻我意识到很多人把这道题当成背诵题在准备但实际上它是一道综合应用题横跨网络协议、浏览器内核、前端工程化三个领域任何一个环节答浅了都会被识破。这篇文章我准备以面试官和开发者的双重视角把整条链路重新拆一遍。无论你是正在准备面试还是在排查页面白屏这套链路都值得反复走一遍你会发现真正重要的是理解每个环节在解决什么问题而不是背出某个标准答案。1. 这道面试题到底在考什么1.1 面试官想听的不只是一条流水线先说面试官的出题意图。很多候选人以为这道题考的是记忆力和背诵能力其实恰恰相反它考的是你把大问题拆成小问题的能力。面试官会观察你是能把整个访问过程分层拆开拆成“输入处理、网络请求、响应接收、浏览器渲染”这几个大块还是只会把零碎知识点像撒芝麻一样倒出来。我见过一个典型回答先讲浏览器缓存再讲DNS解析然后TCP握手、HTTP请求、服务器返回HTML最后说浏览器解析渲染。看起来完整但每个点都只有一句话。面试官追问“缓存命中的时候为什么Network面板有时还能看到请求”“DNS解析为什么通常用UDP而不用TCP”“DOM树和渲染树有什么区别”他就接不上了。这说明他背过流程但没有建立知识体系。不同职级对这道题的期望也不一样。初级岗位能完整讲清楚主干链路、关键协议有概念就够了中高级岗位面试官会希望你能从链路自然延伸到缓存策略、浏览器多进程、性能优化、异常排查这些都是工程中真正会用到的东西。所以这篇文章我不只讲流程也会在每个关键节点补充“面试官可能追到哪里”以及“实际开发中你大概率会遇到什么”。1.2 先记住两段式骨架网络链路加渲染链路我给这道题定了一个固定回答骨架每次面试都能用把全过程切成两大段第一段是网络链路从输入URL开始到浏览器拿到服务器返回的资源结束第二段是渲染链路从浏览器开始解析HTML到像素显示在屏幕上结束。网络链路大概是地址栏输入URL浏览器判断是搜索词还是网址然后补全协议网络进程先查本地缓存命中就直接用没命中就做DNS解析拿到IP建立TCP连接如果是HTTPS还有TLS握手发送HTTP请求服务器返回响应浏览器检查响应状态码、缓存头决定直接用缓存还是重新拉取资源。渲染链路大概是浏览器拿到响应字节流交给渲染进程HTML解析器一边解码一边构建DOM树遇到CSS就构建CSSOM遇到JavaScript就暂停DOM解析先下载和执行脚本DOM和CSSOM合成渲染树浏览器计算布局、绘制最后交给GPU合成屏幕才显示出来。这个骨架的好处是逻辑闭环而且方便你在讲的时候做取舍。比如面试官对缓存感兴趣你就在第一段网络链路里把强缓存、协商缓存展开然后自然跳到第二段说资源如何被渲染进程复用。如果面试官对渲染性能感兴趣你就在第二段重点讲回流、重绘和合成。主干稳定分支灵活这样你永远是在“回答问题”而不是在“背诵答案”。1.3 一个好的回答长什么样我模拟一个高分版本的开头你们感受一下节奏“用户在地址栏输入内容后浏览器进程里的UI线程会先判断这串内容像不像一个URL。如果像就补全协议并交给网络进程如果不像是URL就当成搜索词跳转到默认搜索引擎。网络进程拿到URL后先查浏览器缓存和服务端协商结果来决定是否真正发请求。如果决定发请求就做DNS解析然后经过TCP三次握手和TLS握手建立可信连接最后发出HTTP请求。服务端处理完请求返回响应浏览器网络进程检查Content-Type确认是HTML之后才把数据提交给渲染进程。渲染进程的解析器开始解析HTML这里会边下载边解析遇到脚本会阻塞解析遇到CSS会阻塞渲染最终生成DOM和CSSOM合成渲染树完成布局和绘制用户才看到页面。”这个回答好在哪第一它有角色分工浏览器进程、网络进程、渲染进程各司其职说明你不是把浏览器当黑盒第二它有缓存、有加密、有解析阻塞细节取舍合理第三它始终围绕“每一步解决什么问题”来讲。对比一个低分版本“浏览器先DNS解析再TCP握手再发送HTTP请求拿到HTML后构建DOM树再渲染页面。”这就像报菜名听着流畅其实什么都没说。面试官追问任何一个点你都得重新组织语言那就来不及了。2. 从URL解析到数据包出网网络侧的关键细节2.1 URL解析有些东西根本不会发给服务器地址栏输入不一定是完整URL。比如你输入example.com浏览器默认会给它补上http://或者https://你输入“今天天气怎么样”浏览器会判断这是搜索词直接带你进搜索引擎结果页。这一步虽然简单但面试官可能会顺带问“浏览器怎么判断是URL还是搜索词”答案就是看格式有没有点、有没有协议前缀、有没有常见域名后缀。一个URL的标准结构是协议://主机名:端口/路径?查询参数#片段。以http://example.com:8080/page?id123#section为例协议是http主机名是example.com端口是8080路径是/page查询参数是id123片段是section。这里面有个很容易被忽略的点#号后面的片段fragment只在浏览器端使用不会发到服务器。因为片段是用来定位页面内某个锚点的比如滚动到某个位置服务端根本不需要知道它。还有URL编码问题。如果地址栏里有中文或空格浏览器会先做百分号编码比如空格变成%20中文变成一串%开头的十六进制字符。这看起来是小事但实际开发里经常踩坑服务端拿到的路径和你预期的不一样前端和后端对特殊字符转码方式不一致导致接口404。你可以自己试一下把一个带#的URL粘到地址栏网络面板里看请求路径会发现#后面内容确实不会出现在请求里。2.2 DNS解析从网址到门牌号慢起来能让你怀疑人生DNS解析就是把域名翻译成IP。为什么需要这一步因为人记域名友好但网络传输靠IP地址。这一步的完整顺序是浏览器缓存→操作系统缓存走hosts文件→本地DNS服务器比如家用路由器的DNS或者你手动配置的公共DNS→根DNS服务器→顶级域服务器→权威DNS服务器。每一层如果都查不到才会往下一层走。这里有两个术语容易被问到递归查询和迭代查询。本地DNS服务器向根服务器问“example.com的IP是多少”根服务器不说具体答案而是告诉它“你去问.com的顶级域服务器”这就是迭代。本地DNS服务器替浏览器逐级去找答案对浏览器来说是一次递归查询。实际面试中能说出“查询是分层分级”就足够了但如果能说出每一级缓存会更有说服力。为什么DNS通常用UDP而不是TCP因为一个域名解析的报文很小UDP一个来回就能完成开销低、速度快。TCP需要先三次握手一来一回耗时长对于一个小查询来说太浪费。那丢失了怎么办应用层会重试。如果响应超过512字节或者需要传输区域数据比如DNS区域转移才会切到TCP这也是面试里可以提一句的细节。实际工程里DNS慢是页面加载慢的隐形杀手。一次DNS解析几十到几百毫秒都很正常如果页面有几十个不同域名的子资源光是域名解析就能吃掉大量时间。所以我建议在HTML里用dns-prefetch或者preconnect来提前解析关键第三方域名比如放视频资源、文件CDN的域名。我自己在优化一个多子域名的站点时加了几条preconnect首屏时间直接少了近300毫秒这个优化很划算。2.3 TCP三次握手为什么不是两次或者四次TCP三次握手的目的是让通信双方都确认对方的收发能力是正常的并且同步初始序列号。第一次客户端发送SYN第二次服务端回SYNACK第三次客户端回ACK。三次之后就建立了可靠的连接。为什么不是两次因为服务端没法确认客户端是否已经准备好了接收数据。第二次握手时服务端收到了客户端的SYN也知道自己能发能收但客户端还没有确认自己能收到服务端的SYN。如果只有两次可能会出现客户端压根没准备接收服务端却开始发送数据导致数据白白丢失。为什么不是四次因为第三次握手的ACK已经足够告诉服务端“我收到你了可以开始发”再握一次就是纯浪费一个RTT。实际面试中TCP握手还能延伸到网络安全概念SYN Flood攻击就是恶意客户端只发SYN不回ACK导致服务端维护大量半连接队列资源被打满。这个问题在真实运维中很常见能说出来会显得你有工程经验。从性能角度看TCP握手消耗的是一个完整的RTT往返时间。如果用户在偏远地区访问服务器网络延迟可能上百毫秒光是TCP握手就够用户感知卡顿。所以HTTP/1.1提出了Keep-Alive让多个请求复用同一个TCP连接HTTP/2更进一步在同一个连接里多路复用HTTP/3干脆换成了基于UDP的QUIC握手更快队头阻塞也更少。这些演进本质都是在和“网络延迟”作战。2.4 HTTPS握手证书、密钥和“为什么中间人很难骗你”现在绝大多数网站都是HTTPS也就是在HTTP的基础上加了一层TLS。TLS握手要解决两个问题确认服务器身份以及安全地协商出一个只有你和服务器知道的对称密钥。对称加密速度快但密钥怎么安全送到对方手里所以TLS里先用非对称加密来协商。服务器持有私钥公钥通过证书发布给客户端。客户端拿到证书后要验证两点证书是否由可信CA签发、证书是否过期或域名是否匹配。验证通过后双方再通过一段密钥交换过程比如ECDHE算出同一个会话密钥后续通信全部用这个对称密钥加密。面试里如果被问到“HTTPS握手需要几个RTT”TLS 1.2一般需要2个RTTTLS 1.3优化到1个RTT。这个数字对性能影响很大尤其在高延迟的弱网环境里。还有一个经常被追问的安全细节为什么中间人抓包能抓到你浏览器的HTTPS内容因为抓包工具在自己机器上安装根证书你的客户端信任了那个根证书于是中间人可以伪装成服务器。如果证书链验证失败浏览器会直接拦截地址栏出现红色的“不安全”提示。实际开发中总是能用curl请求接口但前端报证书错误多半是因为本机没有安装对应的根证书。2.5 构造HTTP请求请求行、请求头、请求体以及版本差异连接建立后浏览器开始发送HTTP请求。一个GET请求长这样GET /page?id123 HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 ... Accept: text/html,application/xhtmlxml,... Accept-Encoding: gzip, deflate, br Connection: keep-alive Cookie: sessionidabc123第一行是请求行包含方法、路径、协议版本。后面是请求头Host必填User-Agent标识客户端Accept告诉服务器自己能处理什么类型Accept-Encoding告诉服务器自己能解压什么格式Cookie是身份凭证。这里有个常被问的点POST和GET的区别理论上没有强制的安全语义区别但规范约定GET用于获取数据、不应该有副作用POST用于提交数据实际开发里GET参数会出现在URL上POST参数在请求体里所以敏感信息别用GET传。HTTP版本也是热门考点。HTTP/1.1的问题在于一个TCP连接上同一时间只能处理一个请求对虽然Keep-Alive能复用连接但并发请求还是得靠开多个连接HTTP/2引入了多路复用一个连接里可以同时跑很多个请求和响应还做了头部压缩解决了HTTP/1.1的队头阻塞但仍然受TCP层面的队头阻塞影响HTTP/3用QUIC替代TCP从根本上解决这个问题。面试时能理解到这一层已经明显超过多数候选人。实际操作层面我强烈建议你用curl看一眼真实的耗时分布。这行命令在排查页面加载慢时很实用curl -v https://example.com -o /dev/null -w DNS:%{time_namelookup} TCP:%{time_connect} TLS:%{time_appconnect} TTFB:%{time_starttransfer}\n输出结果会把DNS解析、TCP连接、TLS握手、首字节时间拆开哪个环节慢一目了然。我在实际项目中多次靠这个命令定位过问题比如某次接口TTFB居高不下最后发现是服务端网关加了限流导致排队时间过长跟网络一点关系都没有。3. 服务器处理和响应这不是一个黑盒3.1 服务端处理链路过一遍请求从浏览器发出后第一步通常不是直接到达应用服务器而是一层层网关。请求先到负载均衡器负载均衡器根据策略选择一台后端节点再到反向代理比如Nginx反向代理负责接收请求、处理静态文件、转发动态请求然后是应用服务器可能还要做权限校验、业务逻辑、查数据库、拼装返回数据最后响应原路返回。这个过程中每一步都可能成为TTFB变长的原因。常见的坑包括负载均衡超时设置不合理导致请求反复重试服务端框架启动了模板引擎明明应该返回JSON却返回了HTML代理层缓存了旧版本文件。面试的时候不需要把服务端链路讲得多细但你应该知道TTFB不只取决于网络还与服务端处理时长强相关。DevTools里如果发现TTFB很高而curl测TCP和TLS都不慢问题大概率在后端。还有一个点经常被忽略重定向。有的网站访问根路径会返回301或302跳到带www的域名或者http跳https。浏览器收到重定向响应后会重新发起一次请求这就是为什么Network面板里同一个资源会出现两条记录。面试里如果被问到“为什么Network面板里有两个请求”你就要能想到重定向。3.2 状态码这些数字背后的含义状态码不需要每个都背下来但常见的必须条件反射。我整理了一张速查表状态码含义说明200成功本次请求正常返回201已创建通常用于POST创建资源204无内容请求成功但响应体为空301永久重定向搜索引擎会更新索引浏览器会缓存302临时重定向每次都需要重新访问原地址304未修改协商缓存命中直接使用本地缓存400请求错误参数格式、请求体有问题401未认证需要登录或携带Token403禁止访问权限不够服务端知道你是谁但拒绝404未找到路径不存在500服务器内部错误代码层面异常常见于服务端Bug502网关错误反向代理无法连到后端503服务不可用服务过载、限流或正在维护面试里最容易被坑的是301和302的区别301是永久重定向浏览器会缓存这个重定向结果后续直接访问新地址302是临时重定向每次还是先访问旧地址再跳走。缓存设计时这点更要命一个错误的301会让客户端和搜索引擎长期访问到错误地址。304也是高频考点它表示服务端资源没有变化浏览器可以使用本地缓存响应体为空所以304响应通常很小这一般是协商缓存命中的结果。3.3 缓存强缓存与协商缓存面试必考点缓存是浏览器性能优化的核心也是这道面试题里面试官最爱深挖的分支。强缓存和协商缓存的区别很简单强缓存命中时浏览器根本不发请求直接用本地副本Network面板里状态会显示“200 from disk cache”或“200 from memory cache”协商缓存命中时浏览器会发一个带条件请求头的请求服务端判断资源没变返回304然后浏览器用本地副本。强缓存依赖Cache-Control响应头常见取值有max-age3600缓存一小时、public/private是否允许中间代理缓存、no-cache可以缓存但必须每次校验、no-store完全不缓存。Expires是HTTP/1.0的老方案因为服务器时间和本地时间不一致现在基本被Cache-Control替代。协商缓存则靠Last-Modified和ETag浏览器分别在请求头里带上If-Modified-Since和If-None-Match服务端对比后决定返回200还是304。工程上的最佳实践是HTML资源保持短缓存或no-cache因为HTML是页面的入口一旦被强缓存发版后用户永远看到旧页面JS、CSS、图片这类静态资源文件名带上内容哈希引用变化时URL会变自然绕过缓存所以可以直接给max-age31536000一年。很多团队上线后遇到“用户看到旧版本”的问题多半就是HTML被缓存住了。我这里说的哈希方案是最难出错的。3.4 几个关键响应头Content-Type、Cookie和CSP拿到响应时浏览器第一个看的是状态码第二个就是Content-Type。它告诉浏览器响应体是什么类型如果是text/html就进入HTML解析流程如果是application/json就当成数据如果是text/plain浏览器会把它当普通文本展示不会渲染HTML标签。这也是为什么某次接口返回了HTML错误页前端却显示成一堆代码本质上就是Content-Type没有对齐。Set-Cookie响应头用来在浏览器种Cookie。工程上有两个安全属性非常重要HttpOnly是让JavaScript读不到这个Cookie能降低XSS窃取Cookie的风险SameSite是限制跨站请求携带Cookie能在很大程度上防御CSRF。面试里如果聊到安全问题你能主动提到这两个属性比单纯说“用Token认证”要专业得多。另外CSPContent-Security-Policy响应头能限制页面上脚本和资源的来源比如指定只能加载本站和自己信任的CDN域名其他一律拦截。它不是一个面试冷点很多团队靠这个头来防止XSS注入实际效果非常好。4. 从字节流到像素浏览器渲染页面的完整过程4.1 拿到HTML之后谁在干活现代浏览器不是单进程干到底的它把任务拆给了多个进程。浏览器进程负责界面、标签页管理、导航等全局任务网络进程负责下载资源渲染进程负责解析HTML、CSS、执行JS、生成页面GPU进程负责把页面内容合成并输出到屏幕。每个标签页默认有独立的渲染进程这样做最大的好处是稳定和隔离某个页面崩溃不会拖垮整个浏览器恶意页面也不能直接访问另一个页面的数据。这套多进程架构和“从输入URL到显示页面”有什么关系因为导航的交接过程可以这么理解网络进程先发起请求、接收响应当响应类型是HTML时浏览器进程会让渲染进程准备一个空白页面再把响应数据“提交”给渲染进程提交完成后渲染进程开始解析。面试官如果追问“渲染进程怎么知道该解析什么”你要能说出是Content-Type决定的如果是application/octet-stream则触发下载而不是渲染。4.2 字节流到DOM树HTML解析不是一次性读完的渲染进程拿到的是字节流不是现成的DOM。浏览器要先把字节流按字符编码解码成字符串这个过程受响应头里的charset和HTML里的meta charset影响编码顺序乱了就会出现中文乱码。然后字符串被词法分析器切成一个个Token比如开始标签、结束标签、文本内容再根据Token构建节点最终形成DOM树。这里有个关键认知HTML解析是边下载边解析的不是等全部字节到齐才开始。浏览器主线程一边接收字节流一边解析DOM一边往页面里添加节点。所以你能看到超大页面滚动加载时顶部内容先显示底部还没解析完。那遇到外部CSS和JavaScript怎么办CSS本身由preload scanner提前发现并发下载但不会阻断HTML解析可是CSSOM的构建会阻塞渲染因为浏览器在CSSOM完整之前不知道每个元素该怎么画没法渲染。JavaScript则更麻烦遇到普通script标签HTML解析会停下来等脚本下载、执行完才继续。为什么因为JS可能通过document.write等方式修改DOM解析器必须等它执行完才知道后面的HTML该怎么解析。这也是面试题“为什么说CSS阻塞渲染、JS阻塞解析”的出处。4.3 CSSOM与样式计算样式不会直接“套”到DOM上CSS不会直接“套”到DOM上。浏览器先解析CSS文件或style标签生成一份样式规则叫CSSOMCSS Object Model。CSSOM和DOM是独立的两个树。之后浏览器遍历DOM结合CSSOM为每个节点计算最终的样式值这个过程是样式计算。有个细节值得说CSS选择器虽然能嵌套很深但现代浏览器引擎在匹配样式时做了大量优化会从右向左匹配所以实际的性能问题通常不在选择器复杂度而在元素数量。如果一个页面有上万个DOM节点每个节点都要参与样式计算那这个耗时是不可忽略的。我测试过一些后台系统表格几千行时样式计算时间能占到帧预算的30%优化手段之一就是减少无效DOM节点、避免写通配符选择器。DOM树和渲染树不是一回事这是面试里几乎必问的点。渲染树只包含屏幕上会显示的内容。比如某个节点display:none它不会出现在渲染树里而opacity:0、visibility:hidden这种看不见但占空间的节点还在渲染树里。样式计算完成后浏览器会构建布局树布局树里的每个节点都有具体的几何位置为后面的布局做准备。4.4 布局、绘制与合成页面从结构到像素的三大关布局Layout也叫回流是浏览器计算每个可见元素在页面上的几何位置的过程。宽度、高度、位置、浮动、定位等变化都会触发布局。这里有一个关键概念一个元素的布局变化可能导致其他元素跟着变牵一发动全身所以布局是渲染流水线里成本很高的环节。绘制Paint是在布局结果上给像素填充颜色、边框、阴影、文本等。绘制通常发生在多个图层上浏览器会按图层顺序合成最终画面。合成Composite是最后一步GPU负责把各个图层按正确的位置叠加起来再输出到屏幕。为什么transform和opacity实现动画性能好因为这两个属性变化时元素的大小和位置没有重新计算布局和绘制都不用重新执行浏览器只需要把已有的纹理交给GPU去做平移或透明度的处理直接进入合成阶段。而用left/top做位移动画每一帧都要重新计算布局和绘制代价高得多。你可以打开DevTools的Performance面板录一段动画用left做的话你会看到Layout和Paint频繁出现用transform做的话只有Composite阶段有活动整个时间能差一个数量级。这就是为什么CSS动画规范推荐用transform和opacity不要用left、top、width、height。4.5 从白屏到可交互性能指标到底在测什么面试如果从渲染链路延伸出去大概率会聊性能指标。先记住几个最常见的指标全称含义TTFBTime To First Byte从请求发出到收到第一个字节的时间FPFirst Paint页面第一次出现像素的时间FCPFirst Contentful Paint第一次出现文本或图片内容的时间LCPLargest Contentful Paint最大内容主图、标题等渲染出来的时间CLSCumulative Layout Shift页面加载过程中布局偏移的累计分数TTITime To Interactive页面可以稳定响应用户交互的时间实际项目里我经常用Lighthouse或者Performance面板来量化页面性能。假设一个页面TTFB是0.8秒FCP 1.5秒LCP 3.2秒TTI 5秒。这说明首字节响应较慢而且JavaScript主线程占用过高用户虽然看到了内容但点了没反应这就是TTI和LCP脱节的原因。优化思路就是减少后端耗时、压缩静态资源、把大脚本拆成异步加载、减少不必要的第三方库。“白屏”这一点也经常在面试里出现。白屏一般分两种情况一种是FCP之前页面根本没有内容可能是关键CSS加载慢或渲染被JS阻塞另一种是用户看得到结构但数据没出来那通常不是渲染问题而是数据请求慢或接口异常。区分清楚再谈优化才不会南辕北辙。5. 面试官最爱追问的隐藏考点与排障实战5.1 追问一缓存命中时还会发请求吗很多候选人说“缓存命中就不请求了”这个说法不严谨。强缓存命中确实不发请求但如果你访问一个资源服务端返回了ETag或Last-Modified浏览器即使本地有缓存也会带着条件请求头去问一次服务端服务端说没变返回304。所以你会发现Network面板里一个资源显示“200 from disk cache”另一个显示“304 Not Modified”出现这两种情况意味着走的是完全不同的缓存策略。还有一个实战判断技巧普通回车访问时浏览器可能直接命中强缓存按F5刷新时浏览器通常会跳过强缓存强制发请求走协商缓存按CtrlF5强制刷新时可能会直接绕过缓存请求头里带上Cache-Control: no-cache或Pragma: no-cache让服务器重新返回全部内容。这也是排查“改了代码为什么刷新还是不生效”时首先要确认的问题。5.2 追问二CDN、缓存和DNS是怎么配合的有些动态域名通过CNAME记录指向CDN的域名浏览器解析这个域名时DNS服务器会根据用户的地区、运营商返回离他最近的CDN节点IP这个过程叫域名解析调度。用户访问的是这个CDN节点静态资源在CDN上有缓存CDN缓存里没有时才回源到真正的源站拉取拉回来后缓存在CDN上。这里有一个常见的思维陷阱很多人以为第一个HTML请求会先经过CDN其实不一定。首页HTML如果是动态接口可能直接回源静态资源JS、CSS、图片、字体才会走CDN缓存。所以优化策略通常是HTML不设长缓存或用no-cache保证发版能及时拿到新版本带内容哈希的静态资源可以放心地在CDN上缓存一年因为文件名变了就能拿到新资源。面试中聊到这里最好能补充一句“部署时只更新HTML静态资源全部走CDN靠文件名版本控制”这句话就能体现出你有真实的工程经验。5.3 追问三页面打不开怎么用工具快速定位这是我认为这道题最有价值的地方。背完流程后你得能用于实战。我总结了一套定位页面加载问题的排查顺序你在面试里可以直接拿出来讲第一步用curl看接口或页面的状态码和响应头确认服务端到底返回了什么。比如判断一个URL是200、304还是404看响应内容是不是预期HTML。第二步用curl -w看时间分布判断慢在DNS、TCP、TLS还是TTFB。第三步看浏览器Network面板按时间排序看哪个请求是瓶颈哪些资源被阻塞了。第四步看Console和Sources确认有没有JS异常中断了渲染。第五步如果响应正常但页面白屏用Performance录制分析渲染过程看是不是主线程被脚本拖死。我遇到过一个真实案例某页面刷新后偶发白屏Network面板里主文档请求是200响应头也有Content-Type: text/html但页面就是什么都没有。打开Console发现一个第三方统计脚本抛了未捕获异常异常发生在DOMContentLoaded之前把主流程打断了导致后面的渲染初始化代码没执行。定位方式就是Console优先先看JS有没有报错。很多前端一遇到白屏就去查服务器日志其实第一步应该打开DevTools看Console。5.4 面试中的失分点和加分点总结失分点很典型只背流程不解释为什么比如说不清为什么三次握手把DOM和渲染树混为一谈不知道defer和async的区别回答里完全没提缓存碰到追问就用“你说得对但我没细看”这种话来糊弄。这些都是减分严重的信号。加分点我列几个回答时能主动区分“阻塞解析”和“阻塞渲染”能主动提到HTTP/2多路复用、资源预加载、CDN分发能结合DevTools、curl等工具说明自己排查过真实问题能在讲性能和缓存时给出“文件名哈希长缓存”这类工程实践建议。面试官问“然后呢”的时候你补出的这些关键词越多你的分就越高。我这里给一个很实用的建议不要试图在回答里把所有细节一次讲完。你先把主干讲完然后在某个点上故意停顿比如讲到浏览器遇到script标签会暂停解析时停下来面试官大概率会问“那怎么优化”这时候你再把defer、async、preload、模块化拆包讲出来。这样一来流程是你自己控制的而不是被面试官逼着问的。最后分享一个我自己的习惯每次遇到“页面加载慢”或者“页面白屏”这种问题我都会顺着这道面试题在DevTools里重新走一遍链路先看网络请求再看渲染进程再看脚本异常。走多了之后你会明显感觉到这道面试题不再是应付面试的八股文它其实就是一张浏览器工作原理的完整地图。你能把这张地图讲清楚面试官心里对你有底你在真实环境里能拿着这张地图排障同事对你有底。道理就是这样背是背不出工程能力的但把原理一条条对照到实际现象里收获会超出你的预期。