浏览器面试题
浏览器渲染原理
1. 从输入 URL 到页面渲染的完整流程
- DNS 解析:将域名解析为 IP 地址
- TCP 连接:三次握手建立连接
- 发送 HTTP 请求
- 服务器处理请求并返回响应
- 浏览器解析 HTML 构建 DOM 树
- 解析 CSS 构建 CSSOM 树
- 合并 DOM 和 CSSOM 构建渲染树 (Render Tree)
- 布局 (Layout/Reflow):计算每个节点的位置和大小
- 绘制 (Paint):将渲染树绘制到屏幕上
- 合成 (Composite):将多个图层合成为最终页面
2. 重排 (Reflow) 和重绘 (Repaint)
- 重排:当元素尺寸、位置发生变化,需要重新计算布局
- 重绘:当元素外观发生变化,但不影响布局
触发重排的操作:
- 修改元素尺寸(width、height、padding、margin)
- 修改元素位置(top、left、right、bottom)
- 添加/删除可见 DOM 元素
- 修改浏览器窗口大小
- 读取 offsetHeight、scrollTop 等属性
优化策略:
- 批量修改样式(cssText、className)
- 离线操作 DOM(DocumentFragment、display: none)
- 使用 transform 和 opacity 做动画
- 避免频繁读取布局属性
3. 合成层 (Composite Layer)
浏览器将页面分为多个图层,独立绘制后合成:
- 触发合成层的属性:transform、opacity、will-change、filter
- 合成层优势:避免重排重绘,GPU 加速
- 合成层缺点:占用内存
浏览器存储
1. Cookie、LocalStorage、SessionStorage 对比
| 特性 | Cookie | LocalStorage | SessionStorage |
|---|---|---|---|
| 容量 | 4KB | 5-10MB | 5-10MB |
| 生命周期 | 可设置过期时间 | 永久(除非手动清除) | 页面会话期间 |
| 作用域 | domain + path | 同源窗口共享 | 同一窗口 |
| 服务端读取 | 自动携带 | 不自动携带 | 不自动携带 |
| 应用场景 | 身份认证 | 本地缓存 | 临时数据 |
2. IndexedDB
- 浏览器提供的本地数据库
- 支持结构化数据存储
- 支持索引和事务
- 容量大(通常 50MB+)
- 适合离线应用、大量数据缓存
浏览器安全
1. XSS(跨站脚本攻击)
类型:
- 存储型 XSS:恶意脚本存储在服务器
- 反射型 XSS:恶意脚本在 URL 中
- DOM 型 XSS:通过 DOM 操作触发
防御:
- 输入过滤和转义
- Content Security Policy (CSP)
- HttpOnly Cookie
- 使用框架自动转义(Vue、React)
2. CSRF(跨站请求伪造)
原理:利用用户已认证的会话,诱导用户执行非预期操作。
防御:
- CSRF Token
- SameSite Cookie
- 验证 Referer/Origin
- 双重 Cookie 验证
3. 同源策略 (SOP) 和跨域
同源定义:协议 + 域名 + 端口完全相同。
跨域解决方案:
- CORS(跨域资源共享)
- JSONP(只支持 GET)
- 反向代理
- postMessage
- WebSocket
网络协议
1. HTTP 缓存
强缓存:
- Expires(HTTP/1.0)
- Cache-Control(HTTP/1.1)
- max-age:缓存最大有效时间
- no-cache:强制协商缓存
- no-store:禁止缓存
- public/private:缓存范围
协商缓存:
- Last-Modified / If-Modified-Since
- ETag / If-None-Match
2. TCP 三次握手和四次挥手
三次握手:
- 客户端发送 SYN(seq=x)
- 服务端回复 SYN+ACK(seq=y, ack=x+1)
- 客户端回复 ACK(ack=y+1)
四次挥手:
- 客户端发送 FIN
- 服务端回复 ACK
- 服务端发送 FIN
- 客户端回复 ACK(等待 2MSL 后关闭)
3. HTTP/1.1 vs HTTP/2 vs HTTP/3
| 特性 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| 连接 | 持久连接 | 单一连接多路复用 | 基于 QUIC (UDP) |
| 头部压缩 | 无 | HPACK | QPACK |
| 服务器推送 | 无 | 支持 | 支持 |
| 队头阻塞 | 存在 | 解决(传输层仍存在) | 彻底解决 |
| 加密 | 可选 | 推荐 TLS | 强制 TLS 1.3 |
V8 引擎
1. JavaScript 执行过程
- 词法分析:将代码拆分为 Token
- 语法分析:生成 AST(抽象语法树)
- 编译:Ignition 解释器生成字节码
- 执行:执行字节码
- 优化:TurboFan 将热点代码编译为机器码
2. 垃圾回收
新生代(Young Generation):
- 存放存活时间短的对象
- 使用 Scavenge 算法(复制算法)
- 分为 From 和 To 两个空间
老生代(Old Generation):
- 存放存活时间长或大对象
- 使用 Mark-Sweep(标记清除)和 Mark-Compact(标记整理)
Orinoco 优化:
- 增量标记:将标记过程拆分为小步骤
- 并行标记:多线程并行标记
- 并发标记:主线程执行,后台线程标记
性能优化
1. 资源加载优化
- DNS 预解析:
<link rel="dns-prefetch"> - 预连接:
<link rel="preconnect"> - 预加载:
<link rel="preload"> - 预获取:
<link rel="prefetch">
2. 渲染优化
- 避免阻塞渲染的 CSS 和 JS
- 使用媒体查询加载条件 CSS
- 异步加载非关键 JS(async/defer)
- 减少 DOM 深度和节点数量
3. 性能监控 API
- Performance API
- PerformanceObserver
- Navigation Timing API
- Resource Timing API
- User Timing API
