依赖校验戳缓存(18.6s→0.1s)、并发化库/资产校验、启动计时埋点、过渡动画200ms、窗口客户区精确对齐、遮罩即时显示、debug构建写文件日志。
Starlight Launcher — 实例启动性能优化记录
内部文档,非上线说明。本分支聚焦「实例启动慢」问题的定位与修复。
背景
用户反馈:点击实例启动后,要等很久才看到游戏窗口。
经实测定位,问题由多个独立环节叠加造成,本分支逐项修复。
改动清单
1. 依赖校验戳缓存(packages/app-lib/src/launcher/direct_ensure.rs)
问题:PCL/HMCL 直连实例每次启动都要对全部库文件与资产对象重算 SHA1。 实测某整合包:118 个库 + 3911 个资产对象,合计约 670 MB,机械硬盘顺序读仅 27.8 MB/s,串行校验耗时约 17.7 秒,占整个启动准备阶段的 97%。
方案:新增持久化「已验证」戳缓存,key 为文件绝对路径,value 为
(size, mtime)。file_is_current 先做 stat,命中戳则跳过 SHA1 读取;
文件被替换或修改(size/mtime 变化)时自动回退到完整 SHA1 校验,不弱化
损坏检测。
- 缓存文件:
<caches>/linked-verify-stamps.json(存 Axolotl 自己的缓存目录, 不污染直连安装目录) - 首次启动建立缓存仍走完整校验;后续启动(含跨进程重启)直接命中
效果:asset_scan 15788ms → 62ms,ensure_deps 整体 18.6s → 0.1s。
2. 库/资产校验并发化(packages/app-lib/src/launcher/direct_ensure.rs)
在戳缓存基础上,把库扫描与资产扫描从串行 for 循环改为
try_for_each_concurrent(并发度与下载器一致,task_concurrency_limit * 2)。
首次建缓存时也能吃到并发收益。
注:并发对机械硬盘的随机小文件读取提升有限(IOPS 瓶颈),真正的 数量级提升来自上面的戳缓存。
3. 启动阶段计时埋点(packages/app-lib/src/api/instance/run.rs、packages/app-lib/src/launcher/mod.rs)
在启动链路插入 [launch-timing] 前缀的计时日志,覆盖:
hosted_prepare_launch / hosted_java_arguments / resolve_version_info /
resolve_java / resolve_gc / assemble_client / ensure_deps(细分
dep_lib_scan / asset_scan / dep_assets / dep_log_config)/
remove_old_natives / extract_linked_natives / process_spawn。
用于定位瓶颈,grep [launch-timing] 即可。
4. 启动过渡动画优化(apps/app/src/mc_transition.rs)
a. 动画时长:400ms → 200ms,帧数 50 → 25。缓解卡顿。
b. 窗口对齐修复:全屏放大与缩回游戏窗口时,左侧留缝、整体偏右。
根因是无边框窗口的不可见 resize border(实测窗口比目标大 16×9px,
可见内容从 (8, 4.5) 才开始)。改用 set_client_rect,通过
GetWindowRect / GetClientRect 计算边框并补偿,让可见客户区精确
落在目标矩形。
c. 单次 SetWindowPos:每帧从两次调用(set_position + set_size)
改为单次 SetWindowPos,减少重绘。
d. 恢复可见:动画前先 show() + unminimize(),避免轻量模式遗留
导致遮罩建了却不可见。
5. 遮罩即时显示(apps/app/src/lightweight_mode.rs)
问题:点击启动后遮罩要等约 10 秒才出现。
根因:收到 launched 事件后,代码先 await maximize_minecraft_window
(最多轮询 5 秒等游戏窗口),跑完才启动遮罩动画。
方案:把最大化游戏窗口丢到独立任务,遮罩动画立即启动,两者并行。
6. debug 构建写文件日志(packages/app-lib/src/logger.rs)
问题:debug 构建的 start_logger 只输出到控制台、不落盘,GUI 进程
关闭后无法回溯日志,导致性能计时无法采集。
方案:debug 版 logger 增加一层文件输出,写入与 release 相同的
launcher_logs 目录,文件名带 session_debug_ 前缀。
结论与边界
- 启动器侧:准备阶段已从 18.6s 优化到约 0.1s,拉起进程约 0.6s,已到极限。
- 游戏侧:窗口出现前约 11s、完整加载约 45.8s(230 mod 的 NeoForge 整合包), 属整合包固有成本,任何启动器无法缩短。
- 曾尝试开启 NeoForge 早期窗口(
fml.toml的earlyWindowControl), 该整合包下与 mod 冲突导致更慢(11s → 30s),已回滚。
构建
# debug(含计时埋点、文件日志)
cargo build -p theseus_gui
# release
cargo build --release -p theseus_gui