从回车到渲染:浏览器背后那几十毫秒发生了什么
作为面试题它被问烂了,但真正有意思的是拿着DevTools的性能面板和网络面板,对着一次真实加载把每个阶段耗时的数字对上号。上周给首屏慢的页面做优化,正好完整走了一遍。
拆开的时间线
第一步URL解析和缓存检查。浏览器先查强缓存(Cache-Control的max-age未过期直接用本地副本,network面板显示200 from disk cache),再问协商缓存(If-None-Match带ETag,304则用本地副本)。我们的页面命中了HTML的304,省了一次传输但往返仍在。
第二步DNS、TCP、TLS。域名若启用了HTTP/3,还会先发UDP的CAPABILITY_EXCHANGE。这次抓包看:DNS递归解析18ms、TCP三次握手1个RTT 32ms、TLS 1.3一次飞行28ms。跨境场景里这三步能吃掉几百毫秒,CDN和dns-prefetch/preconnect就是打这里的:
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
<link rel="dns-prefetch" href="https://cdn.example.com">
第三步请求响应。HTTP/2多路复用让30个静态资源并行,瀑布图里一列拉齐。响应到达后进入解析:HTML逐字节解析成DOM,遇到CSS建CSSOM,两者合成渲染树。CSS不改布局的加载也会阻塞渲染(render-blocking),这就是关键CSS内联、其余异步加载的由来。
第四步脚本执行。默认<script>是解析阻塞的,defer保持顺序推迟到DOM完成后,async下载完就执行不保序。改defer后主线程空闲提前了约300ms。
第五步布局绘制合成。计算几何(layout)、画像素(paint)、分层合成(composite)。动画只动transform和opacity时只走合成,GPU搞定,不掉帧;改width会触发整片重排,帧率立降。
数字对账
优化前后的performance面板:LCP从3.8秒到1.9秒。细项里DNS+TCP+TLS占410ms(preconnect省掉重复握手)、JS执行620ms(拆包加defer省400ms)、图片LCP元素加载900ms(转webp加preload降到380ms)。每个优化动作都对应时间线上一段的缩减,有账可查。
容易忽略的事实
重定向链条(http到https到www)每一跳都是完整的DNS加TCP加TLS重来;服务端响应慢(TTFB大)时前端任何优化都白搭;标签页在后台时浏览器会降频,测试性能务必在前台。这道题的价值不在背流程,在于每个环节你都有手段量化和动手。
- 点赞
- 收藏
- 关注作者
评论(0)