25 KiB
ProfileMax:基于 CRIU 的 Chromium 浏览器快照实现方案
- 文档类型:实现方案 / PoC 计划
- 状态:已验证(2026-10-20 本机 PoC + node 端到端集成测试通过,实测数据见第 12 节)
- 目标路径:
/home/bigcode/data/dev/bun/SerpMax/docs/01_CRIU_BROWSER_SNAPSHOT.md
1. 目标与范围
ProfileMax 需要保存已启动的 Chromium 浏览器运行现场。示例:浏览器已经打开 Google 并完成搜索,创建快照后结束原浏览器;后续恢复时尽可能直接回到原搜索结果页面,避免再次启动浏览器、打开网站、重新执行页面初始化,从而降低重复作业的启动延迟和 CPU 峰值。
本方案采用 Linux + Chromium + CRIU,先验证技术可行性,再开发快照管理层。
1.1 必须实现
- 对 Chromium 完整相关进程树执行 checkpoint / restore。
- 恢复页面当前的内存状态,重点验证 DOM、JavaScript 堆、滚动位置和页面交互。
- 快照成功后可以结束原进程;恢复时不依赖原 Chromium 进程仍然存在。
- 保存快照元数据,校验浏览器版本、启动参数和运行环境。
- 记录创建耗时、恢复耗时、快照大小、内存占用和 CPU 峰值。
- 恢复失败时能报告具体阶段和错误,后续可回退到普通浏览器启动流程。
1.2 明确不作为目标
- 不要求保持原 TCP、HTTP/2、WebSocket 等网络连接。 恢复后允许浏览器和页面重新建立连接。
- 不保证 Google 或其他网站的服务端会话永远有效。
- 第一阶段不做跨主机迁移、不做快照分叉克隆、不开发通用虚拟机快照系统。
- 不自行实现进程内存快照引擎;使用 CRIU 完成底层检查点与恢复。
- 不修改 Chromium 源码,除非 PoC 证明现有接口无法满足必要条件。
网络连接不需要延续,不代表可以直接忽略进程持有的 socket。CRIU 在 dump 时仍必须能处理进程文件描述符及其内核资源。必须通过 PoC 验证连接相关资源的实际处理方式,不能假设不传输 TCP 就一定可以成功 dump。
2. 总体架构
ProfileMax API / Job Manager
|
v
Browser Snapshot Manager
|
+-- Browser Runtime Manager
| +-- Chromium 启动与进程树识别
| +-- 固定 Profile / 启动参数 / 显示环境
|
+-- Checkpoint Adapter
| +-- CRIU pre-dump / dump / restore 能力探测
| +-- 命令执行、超时、日志和错误归一化
|
+-- Snapshot Store
| +-- CRIU image 目录
| +-- 元数据与环境指纹
| +-- 完整性检查
|
+-- Restore Validator
+-- 进程存活检查
+-- 浏览器 DevTools / 页面状态检查
+-- 页面交互与网络重连检查
建议管理层使用项目现有的 Bun/TypeScript 技术栈实现;CRIU 通过受控子进程调用。若当前项目已有统一任务执行或进程管理模块,应复用,不要另建重复框架。所有 CRIU 命令必须由服务端生成参数数组执行,禁止拼接用户输入到 shell 命令。
3. 关键技术约束
3.1 Chromium 是多进程程序
不能只对 Browser 主进程执行快照。需要识别并纳入同一检查点的相关进程,例如:
- Browser 主进程
- Renderer 进程
- GPU 进程
- Network Service / Utility 等子进程
- 与浏览器运行现场相关的其他子进程
PoC 需验证 CRIU 采用正确的进程树入口和权限设置,且恢复后进程关系及 IPC 可用。禁止仅凭一个 PID dump 就认为整个浏览器已被完整保存。
3.2 固定运行环境
第一阶段固定以下条件,减少变量:
- 同一台 Linux 主机、同一内核版本与 CRIU 版本。
- 同一 Chromium 二进制版本及启动参数。
- 同一用户、UID/GID、工作目录、环境变量和 Profile 路径。
- 相同的挂载点、字体、共享库、临时目录和必要设备。
- 固定显示模式;优先从无头 Chromium 或固定 Xvfb 环境中选定一种进行 PoC,不要在首轮同时测试多种模式。
- 固定代理配置。代理本身可以在恢复后重新连接,但其配置应保持一致。
快照元数据必须记录上述环境。若恢复环境与快照不兼容,应拒绝恢复并给出明确原因。
3.3 Chromium 沙箱与 GPU
Chromium sandbox、namespace、seccomp、GPU 设备、共享内存及文件描述符可能影响 CRIU 兼容性。
- 首轮先使用正常安全配置验证。
- 如果为了定位问题,需要临时关闭 GPU 或在隔离测试环境中调整沙箱,必须作为单独实验变量记录。
- 不得把
--no-sandbox当作生产默认参数,也不得为了通过 PoC 而默默降低生产安全边界。 - 生产部署前必须明确支持矩阵,写明哪些 Chromium 参数和运行模式经过实测。
3.4 网络与 socket 处理
ProfileMax 不需要恢复原 TCP/WS 连接,但进程内仍可能保存 socket 文件描述符、epoll 状态及异步网络请求状态。
实施原则:
- 不将网络连接连续性纳入快照成功标准。
- PoC 分别测试 CRIU 默认行为,以及在 CRIU 支持和环境允许时对已建立 TCP 连接的处理行为。
- 若 dump 因网络文件描述符失败,记录 CRIU 原始错误和对应 FD 类型,再选择可验证的处理方案;不要直接忽略错误。
- 恢复后,允许应用层重建连接;对已经失效的请求和 WebSocket,页面自身必须能恢复或重新加载相关数据。
- 如需在恢复后关闭陈旧连接,应采用可验证的浏览器/页面层策略;不要从外部任意关闭 Chromium 的 FD,这可能破坏进程内部状态。
3.5 页面状态边界
进程内存快照的目标是保留运行现场,但不能保证每个网站页面都能无缝续跑:
- 页面已渲染的 DOM 和 JavaScript 堆是重点验证项。
- 页面计时器、Promise、Service Worker、后台标签页、扩展进程和浏览器内部任务需要单独测试。
- 恢复后页面可能检测到网络断开、请求失败或登录状态失效。
- 页面现场恢复与网站业务状态恢复是两回事。服务端数据可能已经改变。
4. 快照目录与元数据
建议每个快照使用独立目录,CRIU image 文件和元数据分离管理:
data/snapshots/
<snapshot-id>/
criu/
# CRIU 生成的 checkpoint image 文件
manifest.json
checkpoint.log
restore.log
manifest.json 建议字段:
{
"schemaVersion": 1,
"snapshotId": "uuid",
"createdAt": "ISO-8601",
"status": "ready",
"browser": {
"name": "chromium",
"version": "exact-version",
"executable": "/usr/bin/chromium",
"rootPid": 1234,
"launchArgsHash": "sha256"
},
"runtime": {
"kernelRelease": "exact-release",
"criuVersion": "exact-version",
"uid": 1000,
"gid": 1000,
"profilePath": "/data/profiles/example",
"displayMode": "xvfb-or-headless",
"networkContinuityRequired": false
},
"metrics": {
"checkpointDurationMs": null,
"restoreDurationMs": null,
"snapshotBytes": null
},
"validation": {
"processTreeRestored": false,
"pageStateVerified": false,
"interactive": false
}
}
上例仅为结构示意。实际实现必须从运行环境采集真实值,不能硬编码 PID、版本或路径。敏感代理凭据、Cookie 和页面数据不得写入普通日志或 manifest。
5. 生命周期与状态机
建议快照状态:
creating:正在执行 checkpoint。ready:checkpoint 完成,元数据和文件校验通过。restoring:正在恢复。restored:进程恢复成功且基础检查通过。failed:创建或恢复失败。deleting:正在清理。
创建流程(浏览器关闭前自动快照):
- ProfileMax 统一管理浏览器关闭入口。任务完成、任务管理器要求关闭或用户主动关闭时,先进入
closing流程;不要等 Chromium 已经开始退出后才监听close事件。 - 检查目标浏览器实例和所有权,并确认任务已结束、没有正在执行的关键操作。
- 记录 Chromium 版本、进程树、启动参数、运行环境及当前作业 URL。
- 创建临时快照目录并执行 CRIU checkpoint/dump。
- 收集退出码、stdout/stderr、CRIU 日志和耗时;校验检查点文件完整并写入 manifest。
- 校验通过后,原子地将快照标记为
ready,并将其关联到对应浏览器实例/任务。 - 只有快照已可靠落盘并标记为
ready后,才完成浏览器关闭流程。注意:常规 CRIU dump 通常会让被 dump 的进程停止/退出,因此应由 CRIU 的实际 dump 语义完成进程收尾,不能再无条件调用 Chromium 的正常关闭。 - 如果快照失败,记录错误并按配置执行普通关闭;不要把不完整快照标记为
ready。若产品要求必须先保留一个仍运行的 Chromium 再正常关闭,需要单独验证 leave-running 模式与 Profile 文件一致性,不能直接把它当作安全默认方案。
关闭事件的实现要求:使用 ProfileMax 自己的统一关闭方法/生命周期钩子作为触发点;浏览器进程已经退出后的 close/exit 通知只用于清理和记录结果,不用于启动快照。
恢复流程:
- 校验 manifest、快照文件、版本和运行环境。
- 确保没有冲突的同一实例正在运行;首版不支持从同一快照并发恢复多个实例。
- 准备恢复所需的用户、目录、挂载、网络命名空间和显示环境。
- 执行 CRIU restore,保存日志和耗时。
- 验证恢复后的进程树、浏览器调试接口(如果启用)、原页面状态及用户交互。
- 对网络重连进行观察,但不要求旧连接继续存在。
- 只有验证通过才标记为
restored;失败时保留诊断材料,避免自动覆盖原快照。
注意:CRIU 的具体命令行参数、权限要求和网络选项必须以部署机器上安装版本的 criu --help、官方文档和 PoC 结果为准。本文不预设某一组命令在所有内核/CRIU 版本上通用。
6. 模块接口建议
管理层可先实现以下内部接口,具体参数根据现有 ProfileMax 代码规范调整:
type SnapshotStatus =
| "creating"
| "ready"
| "restoring"
| "restored"
| "failed"
| "deleting";
interface SnapshotManifest {
schemaVersion: number;
snapshotId: string;
createdAt: string;
status: SnapshotStatus;
browser: {
name: "chromium";
version: string;
executable: string;
rootPid: number;
launchArgsHash: string;
};
runtime: {
kernelRelease: string;
criuVersion: string;
uid: number;
gid: number;
profilePath: string;
displayMode: string;
networkContinuityRequired: false;
};
}
interface CheckpointResult {
snapshotId: string;
durationMs: number;
snapshotBytes: number;
logPath: string;
}
interface RestoreResult {
snapshotId: string;
durationMs: number;
restoredPids: number[];
validationPassed: boolean;
}
interface CheckpointAdapter {
checkCapabilities(): Promise<{
available: boolean;
criuVersion?: string;
reasons: string[];
}>;
checkpoint(browserRootPid: number, snapshotDir: string): Promise<CheckpointResult>;
restore(snapshotDir: string): Promise<RestoreResult>;
}
这些接口是设计草案,不代表项目中已经存在对应模块。需要先查看 ProfileMax 当前目录结构和现有进程管理实现,再决定最终落点。
7. PoC 实施计划
P0:环境检查
- 确认 Linux 发行版、内核版本、CRIU 版本及所需权限。
- 运行 CRIU 自检,并保存完整输出。
- 检查 Chromium 的实际进程树、命名空间、打开的 FD、共享内存和设备依赖。
- 记录当前 Chromium 版本、启动参数和运行模式。
交付物:环境报告、CRIU capability 报告、浏览器进程树样本。
P1:最小 checkpoint / restore
- 启动 Chromium 并打开固定测试页面。
- 在页面内创建可验证的 JavaScript 状态标记,例如计数器、随机 token、滚动位置和 DOM 文本。
- 执行 checkpoint,确认原实例已按预期停止或退出。
- restore 后读取页面标记,验证其与 checkpoint 前一致。
- 检查页面是否可点击、输入和滚动。
交付物:可重复执行的测试脚本、CRIU 日志、成功/失败原因。
P2:真实搜索页面
- 打开 Google 并执行固定关键词搜索,按正常流程完成测试任务。
- 任务完成、浏览器准备关闭时,由 ProfileMax 关闭流程触发快照;不使用定时快照,也不需要单独监听页面稳定事件。
- 快照完成并可靠落盘后,按 CRIU dump 的实际语义结束原进程,再执行恢复测试。
- 验证 URL、DOM、滚动位置和页面交互。
- 观察网络重连后的页面行为;不把旧 TCP/WS 保持连接作为成功条件。
交付物:真实网站验证记录。若网站行为不稳定,使用本地测试页面作为可重复基线,并将网站测试作为补充。
P3:基准测试
至少重复 20 次,分别测量普通冷启动和快照恢复:
| 指标 | 冷启动 | CRIU 恢复 |
|---|---|---|
| 总耗时 P50 / P95 | 测量 | 测量 |
| CPU 峰值 | 测量 | 测量 |
| 恢复后可交互耗时 | 测量 | 测量 |
| 快照体积 | 不适用 | 测量 |
| 失败率 | 测量 | 测量 |
必须统一测试条件:相同主机、Chromium 版本、Profile、页面、代理和资源状态。单次结果不能作为结论。
P4:管理器封装
只有 P1/P2 证明可行后再实施:
- snapshot create / restore / inspect / delete。
- 状态机和并发锁。
- 日志、错误分类、超时和取消。
- 快照容量限制及过期清理。
- 环境兼容性校验和失败降级。
- 权限隔离,避免普通用户对任意系统进程执行 dump/restore。
8. 验收标准
首阶段必须全部满足:
- 能对目标 Chromium 进程树成功 checkpoint。
- 原浏览器进程停止后,能够从快照恢复。
- 恢复后原页面的验证标记、URL、主要 DOM 状态及滚动位置符合预期。
- 页面可继续交互,且允许网络连接重新建立。
- 失败时能够通过日志定位到具体 CRIU 错误或资源依赖。
- 测得冷启动与恢复的耗时、CPU 峰值、快照大小和失败率。
性能目标在取得基线数据后设定,不预先承诺快照恢复一定比冷启动快。快照读取、内存恢复和页面恢复验证都可能消耗显著的磁盘 IO 与 CPU。
9. 安全与运维要求
- 快照可能包含 Cookie、认证令牌、页面内容及其他敏感内存数据,按敏感数据保护。
- 快照目录仅允许浏览器运行用户和快照管理服务访问,权限默认最小化。
- 不在日志中输出 Cookie、Authorization、代理密码或页面表单内容。
- 只允许管理器操作其登记的 Chromium 进程,不接受任意 PID 的外部请求。
- CRIU dump/restore 使用最小必要权限;如需 root 权限,限定服务边界并记录审计日志。
- 删除快照时清理完整目录,并记录清理结果。
- 版本、内核或启动参数不兼容时拒绝盲目恢复。
10. 参考资料
- CRIU:https://github.com/checkpoint-restore/criu
- CRIU 官方文档:https://criu.org/
- CRIU 使用手册:https://criu.org/Basic_usage
- Podman checkpoint/restore(用于参考容器集成方式):https://docs.podman.io/
11. 当前结论
采用“CRIU 底层 + ProfileMax 自有管理层”的路线。第一阶段只交付 PoC,不提前承诺 Chromium 全进程树一定可恢复。优先验证真实运行环境中的沙箱、GPU、共享资源和 socket 处理。TCP/WS 连续性不是验收目标;进程仍需正确处理网络相关 FD,恢复后允许应用重新连接。PoC 通过后再扩展为多实例快照管理。
12. 实测结论与落地记录(2026-10-20)
12.1 环境与实测数据
- 环境:Zorin OS 18.1(Ubuntu noble 基),内核 7.0.0-31-generic,veil-chromium 153.0.8010.52;
CRIU 4.2(源码编译,
/usr/local/bin/criu,文件能力cap_sys_ptrace,cap_sys_admin,cap_net_admin+eip, 非 root 可用,免改 ptrace_scope)。 - PoC(直启 chrome → baidu 搜索页 → dump → restore):
| 指标 | 实测值 |
|---|---|
| 冷启动(进程拉起 → CDP 就绪) | ≈ 0.6s |
| dump(9 进程树,RSS ≈ 1.13GB) | ≈ 1.3s,镜像 ≈ 354MB(397 个 .img) |
| restore(detached) | ≈ 0.36s |
| 现场校验 | URL/标题/JS 堆标记/滚动位置/搜索结果 DOM/localStorage 全部一致,navigator.onLine=true |
| 可交互 | 恢复后二次搜索成功(网络自动重连) |
- node 端到端(经 ProfileMax API:创建快照 Profile → 启动 → 搜索 → 停止自动 dump → 再启动):
停止含 dump ≈ 1.3s;再次启动 ≈ 0.4s 且
restored:true,CDP 端口原样恢复,现场校验同上全绿 (复测脚本node/scripts/criu-poc.ts、node/scripts/criu-e2e.ts)。
12.2 关键结论(实测定论)
- 沙箱与 CRIU 的结构性冲突:criu 拒绝对「非根进程自建的嵌套 PID namespace」执行 dump
(
CLONE_SUBNS仅含 mount/net),而 chromium namespace 沙箱的 zygote/渲染进程恰在嵌套 pidns 中。 → 快照模式 Profile 启动时显式追加--no-sandbox(browser.managersnapshotSandboxArgs); 生产节点为 root 容器,ProfileMax 本就强制--no-sandbox,此处仅影响非 root 环境,非全局降级。 - 仅支持 headless:有头模式连接的 X11/Wayland socket 是树外 STREAM unix socket,
criu 的
--ext-unix-sk仅支持 DGRAM 外部连接 → 有头实例停止时不做快照(回退常规关闭)。 - D-Bus 必须「干净失败」隔离:chrome 对已建立后断开的 dbus 连接会 FATAL
("D-Bus connection was disconnected. Aborting.")。快照模式启动 env 将
DBUS_SESSION_BUS_ADDRESS/DBUS_SYSTEM_BUS_ADDRESS指向unix:path=/nonexistent-bus(与生产容器无 bus 的现实一致);地址格式非法(如/dev/null)会导致导航失败,不可用。 - crashpad handler 在树外:chrome 会把 handler daemonize 到进程树外(subreaper 接管), 其 SEQPACKET socketpair 端为树外对端。已给 criu 打补丁:dump 允许外部 STREAM/SEQPACKET, restore 侧对非 DGRAM 外部对端跳过 connect(以「未连接」语义恢复,客户端优雅降级); 补丁内容两处(criu/fsnotify.c 悬空 inotify watch 跳过 + criu/sk-unix.c 外部 socket 放行), 生产镜像需携带补丁版 criu。
- chromium 共享内存临时文件(
.org.chromium.Chromium.*,实测 4MB 起步)远超 criu 默认 1MB ghost 限额 → dump/restore 统一--ghost-limit=512MB(envCRIU_GHOST_LIMIT_MB可调)。 - dump 参数:
--file-locks --tcp-close --ext-unix-sk --ghost-limit=N [--unprivileged];--tcp-close表示已建 TCP 连接按「关闭」落镜像(符合 1.2 节「不要求连接连续性」), 恢复后由页面/浏览器自行重连,实测 baidu 页面正常。 - 启动方式约束:快照 Profile 由本服务直启(setsid 保证 session leader + 显式
--user-data-dir),不经 playwright 管道(管道对端在树外无法 dump);CDP 经 connectOverCDP 挂接,停止时 playwright 句柄 close() 仅断连不杀进程。 - 参数哈希与端口绑定:dump 时将完整启动参数(含
--user-data-dir打头)哈希入 manifest, restore 前重算比对,任一不一致拒绝恢复回退冷启动;impersonate MITM 端口记入 manifest, 恢复时ensureImpersonate优先复用同端口(浏览器重连无缝),端口被占则拒绝恢复。 - 陈旧 DevToolsActivePort:dump 后该文件残留,直启前必须删除,否则 CDP 就绪探测 可能打在死端口上(实测踩坑)。
- criu 单次操作超时 180s,dump/restore 失败不重试:回退常规关闭/冷启动,
失败快照保留
failed状态与日志供诊断(manifest.json / dump.log / restore.log)。
12.3 落地范围(本版)
- Profile 新增
snapshot.enabled配置(admin「快照模式」开关,缺省关闭;仅 veil + headless 生效); - 停止浏览器时自动 checkpoint(存储快照抓取先于 dump),启动时优先 restore 并回写 CDP/条目;
- 节点 API:
GET/DELETE /profiles/:id/snapshot;admin 中继同路径 GET/DELETE + PUT 快捷开关; - admin 概览卡:快照(含大小)/ 自动CF挑战 / 自动挑战 reCAPTCHA 三开关同行;
- 快照目录:
<profileDir>/<profileId>/snapshot/(manifest.json + criu/ 镜像 + dump/restore 日志), 随 Profile 删除一并清理;同一 Profile 仅保留最近一次快照。
13. 镜像压缩与 USER_DATA 清理(2026-10-21,node v0.38.0 / admin v1.55.0)
13.1 镜像压缩(zstd 后处理)
CRIU 4.x 核心已移除内建压缩选项(旧版 -z/--compress 不存在,criu-image-streamer 需额外组件),
采用「dump 后 zstd 压缩大镜像 / restore 前解压还原」的后处理方案(snapshot.manager):
- dump 成功后(进程已退出)对镜像目录中 >1MB 的
*.img逐文件zstd -3 -T0压缩, 压缩成功才删原文件,单文件失败保留原样不阻塞;SNAPSHOT_COMPRESS=off可整体关闭。 - restore 前把
*.img.zst解压还原(criu 不识别压缩镜像),耗时记入 manifestmetrics.decompressDurationMs;压缩前/后体积分别记snapshotBytesRaw/snapshotBytes。 - 实测(同环境同场景,baidu 搜索现场,两轮):
| 指标 | 压缩前(10-20 基线) | 压缩后(10-21 实测) |
|---|---|---|
| 快照镜像大小 | 308~312MB | 67.5~70.6MB(约 4.4x 缩小) |
| dump 耗时 | ≈1.0~1.3s | ≈1.0~1.3s(不变) |
| 停止总耗时(含 dump+压缩) | ≈1.2~1.3s | ≈2.4s(压缩约 +1.1s,zstd -3 -T0) |
| restore(criu 自身) | ≈0.3s | ≈0.3s(不变) |
| restore 前解压 | — | ≈0.58s |
| 再次启动总耗时 | ≈0.43~0.58s | ≈1.11~1.16s(解压 +0.6s) |
| 现场校验(8 项) | 全绿 | 全绿(URL/标题/JS 标记/滚动/localStorage/结果数/在线/二次搜索) |
结论:以「每次停止 +≈1.1s、每次恢复 +≈0.6s」换「磁盘占用 -77%」,默认开启; 磁盘敏感场景收益显著,对恢复可用性无影响。
13.2 USER_DATA 静态缓存清理
- 自动清理(默认开启):浏览器停止时实测 USER_DATA 体积(关闭前采样)超过
USERDATA_CLEAN_THRESHOLD_MB(默认 100MB)→ 进程完全退出后软清理静态缓存 (cache.managerautoCleanOnStop);清理后体积才回传 admin(profiles.user_data_size)。 - 软清理范围(CACHE_DIRS):根级 +
Default/子目录双布局——HTTP Cache、Code Cache、 GPUCache、Dawn/GrShader/Graphite 缓存、Media Cache、Shared Dictionary、组件 crx 缓存等; Cookie/LocalStorage/IndexedDB/Service Worker/登录态一律保留(实测主要占用Default/Cache+Default/Code Cache,约占 USER_DATA 80%)。 - 手动清理:节点
POST /profiles/:id/cleanup(admin 中继POST /api/profiles/:id/cleanup, Profile 详情页「编辑」与「复制」之间的「清理」按钮):软清理 + 删除现有 CRIU 快照 (快照镜像含缓存页,restore 会原样还原缓存,不删等于没清;下次停止自动重建快照); 浏览器运行中节点拒绝(CACHE_CLEAR_FAILED,提示先停止)。返回 before/after/freedBytes 与 snapshotDeleted,前端 toast 展示释放体积。 - 验证:130MB 假缓存(Default/Cache)触发清理释放 120MB,Cookie/LocalStorage 保留; 50MB 未触发;E2E 全流程(含手动清理后快照 bytes=0)通过。
13.3 启动方式对比:正常冷启动 vs 快照恢复(到达同一现场)
口径:从 POST /browser/start 发起,到「baidu 同一关键词搜索结果页 DOM 已渲染」为止
(CDP 连接与现场确认均计入);基准脚本 node/scripts/criu-bench-compare.ts,两轮实测:
| 阶段 | 冷启动(非快照) | 快照恢复 |
|---|---|---|
| 启动 → CDP 就绪 | 0.80~0.96s | 0.99~1.51s(含解压≈0.6s + restore≈0.3s) |
| 导航加载搜索结果 | 2.52~4.08s(随网络波动) | 0(现场已在,免导航) |
| 现场确认 | 0.08~0.11s | 0.04~0.32s |
| 到达同一现场总计 | 3.69s / 4.44s | 1.18 / 1.40 / 1.49 / 1.59s(均值 ≈1.4s) |
| 现场一致性 | — | 4/4 轮 URL/标题/结果数完全一致 |
| 加速比 | — | 2.86x / 2.88x(两轮稳定) |
附:快照 Profile 自身冷启动(3.61s/5.14s)与普通 Profile 无差异,快照模式不拖累冷启动; 本组 dump 耗时 1.7~3.3s、快照 60.4~70.9MB(压缩后),dump 耗时随当时浏览器内存占用浮动。