面试的时候,我特别爱问一个问题:从你在地址栏敲下一个网址,到页面完整显示,浏览器都干了哪些事?这个问题能拆出浏览器一大半的底层机制,也最能看出一个前端是真理解了运行环境,还是只背了一堆框架 API。很遗憾,多数人答到一半就卡住了,要么只记得 DNS 和三次握手,要么把渲染流程说得乱七八糟。
其实这不怪谁。前端知识面太宽,这两年框架、构建工具、AI 辅助编程又不停迭代,很少有人愿意静下来把浏览器这层地基认真过一遍。但恰恰是这块地基,决定了你排查线上问题快不快、性能优化准不准、兼容性适配稳不稳。今天我打算把浏览器相关的核心知识从头理一遍:网络请求、渲染管线、JS 执行机制、多进程架构、跨浏览器兼容、安全防线、性能调试。话题确实偏面试,但每一条都来自日常开发场景,适合准备前端面试的人,也适合已经工作两三年、想系统补一遍浏览器知识的同学。
1. 输入一个网址到页面出现,浏览器中间做了什么
1.1 从 DNS 到 TCP/TLS:请求真正发出前的两段“握手”
你在地址栏输入 www.example.com,浏览器第一件事不是发 HTTP 请求,而是先把域名翻译成服务器能认的 IP 地址,这一步叫 DNS 解析。解析顺序大概是:浏览器 DNS 缓存 -> 操作系统 DNS 缓存 -> 本地 hosts 文件 -> 网络配置的 DNS 服务器递归查询。很多人会遇到“换 DNS 之后网页秒开”的情况,就是因为运营商默认 DNS 递归查询慢、命中率低。
拿到 IP 之后,浏览器要和服务器建立 TCP 连接。传统三次握手是 SYN -> SYN+ACK -> ACK,但现代浏览器几乎不会为每次请求都重新握手,而是通过 Connection: keep-alive 复用已有连接,HTTP/2 更进一步,一条连接上可以同时跑多个请求,这就是多路复用。如果站点是 HTTPS,TCP 之上还要走 TLS 握手,用于协商加密套件、交换证书、生成会话密钥。TLS 1.3 把握手压缩到 1-RTT,首次请求已经比老版本快很多。
实操提示:如果你发现首屏慢,先看 DNS 解析和 TLS 握手耗时。用 DevTools Network 面板的 Timing 标签,能清楚看到 DNS Lookup、Initial Connection、SSL 三个阶段各花了多久。偶尔排查到某个第三方字体域名解析要 200ms,直接换一个更稳的字体 CDN,比调业务代码见效快得多。
1.2 强缓存与协商缓存:浏览器如何让第二次访问变快
缓存是前端必须掌握的分层概念。浏览器在真正发请求前,会先检查本地有没有可用副本。如果命中强缓存,直接使用本地资源,不发任何网络请求,状态码显示 200 (from disk cache) 或 200 (from memory cache);如果强缓存失效,浏览器会带上 If-Modified-Since 或 If-None-Match 去问服务器,服务器返回 304 表示“你可以继续用本地那份”,这叫协商缓存。
| 缓存类型 | 相关响应头 | 特点 |
|---|---|---|
| 强缓存 | Cache-Control: max-age=31536000, immutable | 过期前不发请求,性能最好 |
| 强缓存 | Expires | HTTP/1.0 方案,容易被本地时间影响,已不推荐单独使用 |
| 协商缓存 | Last-Modified / If-Modified-Since | 以秒为单位,可能不精确 |
| 协商缓存 | ETag / If-None-Match | 内容指纹,更精确,优先使用 |
实际项目中,我的做法是:index.html 这类入口文件用 Cache-Control: no-cache,保证每次回源校验;带内容 hash 的 JS/CSS 资源用 max-age=31536000 加 immutable,文件名一变就是新请求,不存在“更新不生效”的问题。
1.3 HTML、CSS、JS 的解析顺序:为什么脚本要放底部
服务器返回 HTML 后,浏览器开始从上到下解析,边解析边构建 DOM 树。遇到 ,会去加载并解析 CSS,构建 CSSOM 树;遇到
