1. JavaScript 引擎的异同与代码区分
主流引擎
- Chrome:V8(C++ 实现,高性能,支持即时编译 JIT)
- Firefox:SpiderMonkey(首个 JavaScript 引擎,逐步优化 JIT)
- Safari:JavaScriptCore(Nitro 引擎,专注内存管理)
- Edge:V8(基于 Chromium 内核)
异同点
- 性能:V8 和 SpiderMonkey 均采用分层编译(解释器 + 优化编译器)
- 内存模型:JavaScriptCore 在移动端优化更好
- ECMAScript 支持:各引擎对新特性支持速度不一致
代码区分
javascript
运行
// 通过User-Agent判断(不绝对可靠)
if (navigator.userAgent.includes("Chrome")) {
console.log("V8引擎");
} else if (navigator.userAgent.includes("Firefox")) {
console.log("SpiderMonkey");
}
// 特性检测更可靠,如检查Proxy支持
2. 请求数据到结束的交互次数
一次典型的 HTTPS 请求流程:
- DNS 查询:1 次(缓存不存在时执行)
- TCP 握手:3 次握手
- TLS 协商:2 次往返(ClientHello/ServerHello 等报文交互)
- HTTP 请求:1 次请求 + 1 次响应
- 资源加载:存在 302 重定向时会产生额外网络交互
总计:无缓存、无重定向场景下,最少 6 次网络交互。
3. 从输入 URL 到页面展现的完整流程
导航阶段
- URL 解析(校验协议、匹配 HSTS 列表等)
- DNS 解析(递归查询流程)
- TCP 连接建立 + TLS 安全握手
请求响应阶段
发送 HTTP 请求,接收服务端响应(解析状态码、响应头 Content-Type 等信息)
解析与渲染阶段
- HTML 解析构建 DOM 树,CSS 解析构建 CSSOM 样式树
- DOM+CSSOM 合并生成渲染树,依次执行布局 (Layout)、绘制 (Painting)
资源加载阶段
图片、脚本等页面子资源依照浏览器优先级策略异步加载
4. HTML 解析与 DOM 树构建
整体流程
- 字节流解码:将网络返回的二进制数据转为文本字符
- 词法分析:扫描文本,生成标签、属性等 Token 令牌
- 语法分析:借助栈结构,基于 Token 逐层生成 DOM 节点
DOM 树构建规则
- 解析过程遇到原生
<script>标签会阻塞 HTML 解析(添加 async/defer 属性除外) - 预加载扫描器会提前识别、预请求页面中的外部静态资源
代码示例
html
预览
<html>
<body>
<div>Test</div>
</body>
</html>
解析完成后生成层级嵌套结构的 DOM 节点树。
5. CSS 解析与样式应用
执行步骤
- 解析 CSS 文本,生成 CSSOM(层叠样式表对象模型)
- 选择器匹配规则:从右向左匹配 (例:
.class div先匹配所有 div 元素,再筛选对应 class) - 计算最终样式:合并浏览器默认样式、继承样式、开发者自定义样式
- 样式挂载:每个 DOM 节点绑定计算完成的最终样式,可通过
window.getComputedStyle()读取
关键注意点
CSSOM 的构建过程会阻塞页面渲染,开发中应尽量避免多层级嵌套选择器,降低解析开销。
6. 渲染树的绘制与合成
- 生成渲染树:仅收录页面可见 DOM 节点,
display: none的节点会被剔除 - 布局 (Layout):计算所有元素的实际位置、尺寸,该行为会触发回流
- 绘制 (Paint):生成每一层画布的绘制指令列表
- 合成 (Composite):图层分片交由 GPU 完成光栅化渲染
性能优化
使用transform、opacity修改样式只会触发合成层重绘,不会触发回流与完整绘制,大幅优化动画性能。
7. 资源加载机制与配置
同步脚本 vs 异步脚本
- 同步:默认
<script>标签,加载与执行过程直接阻塞 DOM 解析 - 异步
- async:脚本下载完成后立刻执行,执行顺序不受页面 DOM 结构影响
- defer:等待完整 DOM 解析完毕后,依照书写顺序依次执行脚本
预加载技术写法
html
预览
<!-- 资源预加载 -->
<link rel="preload" href="font.woff2" as="font">
<!-- 预先建立服务端连接 -->
<link rel="preconnect" href="https://api.example.com">
8. 回流与重绘的优化策略
- 回流(Reflow):元素几何属性发生变更(宽高、坐标、布局结构),浏览器重新计算页面布局
- 重绘(Repaint):仅元素外观样式变化(颜色、背景色、阴影),无需改动布局结构
通用优化手段
- 使用
DocumentFragment完成批量 DOM 操作,减少 DOM 频繁改动 - 高频修改元素时,先设置
display: none脱离文档流,修改完成后恢复显示 - 优先使用 CSS transform 动画,借助 GPU 硬件加速规避回流
9. 垃圾回收与内存泄漏
V8 垃圾回收机制
- 标记 - 清除算法:从全局根对象遍历标记存活对象,回收不可达的堆内存
- 分代收集:V8 将堆内存划分为新生代(采用 Scavenge 算法回收)、老生代分别管理
常见内存泄漏场景
- DOM 事件监听绑定后未手动解绑销毁
- 闭包长期持有外部变量引用,造成变量无法被 GC 回收
- 全局变量无节制持续累积
排查工具
Chrome 开发者工具 Memory 面板、Heap SnapShot 堆快照分析功能
10. 缓存方案选择与控制
两类缓存策略
- 强缓存:依靠
Cache-Control: max-age=3600设置资源绝对缓存时效 - 协商缓存:基于 ETag / Last-Modified 校验资源是否更新,命中则返回 304 复用本地缓存
Nginx 配置示例
nginx
# 静态资源配置长期强缓存
location /static {
expires 1y;
add_header Cache-Control "public";
}
# HTML文件禁用长久缓存
location / {
expires 0;
}
版本更新方案
给静态文件添加文件哈希命名(如app.a3f4.js),文件内容变更哈希自动变化,强制浏览器拉取最新资源。