游客发表
你在地址栏敲下 https://example.com/index.html 然后回车。屏幕上瞬间出现页面。打开的工这中间大概200毫秒里发生的文件事,比大多数人想象的作过要多得多。我拆过几次浏览器请求,浏览器也抓过包,打开的工下面按实际发生的文件顺序捋一遍——不是教科书顺序,是作过数据包真正流动的顺序。
浏览器先看URL。浏览器协议是打开的工https,域名example.com,文件路径/index.html。作过如果之前访问过这个站点,浏览器浏览器会先翻自己的打开的工缓存:内存缓存、硬盘缓存、文件Service Worker 缓存。有一次我调试一个静态博客,改了CSS但页面死活不变,就是因为硬盘缓存里躺着旧版本。缓存命中就直接渲染,没有网络请求。没命中,才进入下一步。
接下来是DNS查询。浏览器问操作系统:“example.com的IP是多少?”操作系统先查hosts文件——这玩意儿优先级极高,我见过有人用hosts屏蔽广告,结果自己开发环境域名被误伤。hosts没有,就查本地DNS缓存。再没有,才向递归DNS服务器发请求。整个过程UDP 53端口,通常20毫秒内搞定。拿到IP,比如93.184.216.34。
有了IP,浏览器发起TCP连接。三次握手:SYN、SYN-ACK、ACK。如果是HTTPS,还要加一层TLS握手。TLS握手那几步——ClientHello、ServerHello、证书验证、密钥交换——比TCP握手慢得多。我抓包看过,一个冷启动的HTTPS连接,TLS阶段能占掉总时间的60%以上。所以浏览器会复用连接,keep-alive不是摆设。
连接建好,浏览器构造HTTP请求。GET /index.html HTTP/1.1,带上Host、User-Agent、Accept、Cookie这些头。Cookie很关键——服务器靠它识别你是谁。有一次我清空了Cookie,结果后台直接把我踢到登录页,因为会话丢了。请求发出去,服务器处理,返回响应。状态码200,Content-Type: text/html,还有一堆缓存控制头。
响应体到了浏览器,不是直接画出来。先解析HTML。词法分析、构建DOM树。遇到<link rel="stylesheet">,浏览器会暂停渲染,去下载CSS。这就是为什么CSS要放head里——放body底部会导致页面闪一下无样式内容。遇到<script>,默认也会阻塞解析,除非加async或defer。我见过一个页面因为头部塞了三个同步脚本,白屏了整整两秒。
DOM树和CSSOM树都建好,合并成渲染树。然后布局——计算每个节点在屏幕上的确切位置和大小。再然后绘制——把像素填上去。这还没完,如果有JavaScript操作DOM,可能触发重排或重绘。我调过一个动画,用top/left改位置,帧率掉到20;换成transform,立刻60帧。浏览器对合成的优化,比很多人以为的聪明。
最后,页面显示出来。但工作没停——图片、字体、异步接口还在陆续加载。你看到的首屏,可能只是半成品。真正的“打开完成”,得等load事件,甚至networkidle。不过用户不关心这个,他们只关心第一眼有没有内容。
一个冷知识:你敲回车到看到第一个像素,浏览器内部至少经历了缓存查找、DNS、TCP、TLS、HTTP、解析、布局、绘制八个阶段。每个阶段都可能成为瓶颈。下次页面慢,别只骂网速。```
友情链接