外观
Stage05|Performance
Lesson069|启动速度、首屏时间与分阶段加载
Tags: #Creator2.x #Stage05 #Startup #Loading #FirstScreenDifficulty: ⭐⭐⭐⭐☆
真实问题:启动总时长缩短了,玩家为什么觉得更慢
旧版本 4 秒后直接进入可操作大厅。新版本总加载只需 3.5 秒,但前 3 秒一直黑屏,最后 0.5 秒才出现 UI。技术指标变好,感知体验变差。
启动至少有三个指标:
text
First Frame:第一次有画面
First Meaningful Paint:第一次有意义内容
Time To Interactive:第一次可操作
All Ready:后台内容全部完成优化不能只看 All Ready。
一、本课目标
启动性能关注的是用户从点击到可操作的时间,而不是单个资源加载函数耗时。本课建立启动阶段分解和分阶段加载方案。
二、启动时间线
text
进程启动
→ 引擎初始化
→ 脚本加载
→ 首场景加载
→ 资源解码
→ Node / Component 创建
→ 首次布局和渲染
→ 用户可操作每一步都可能成为首屏瓶颈。
三、首屏可用和资源完整不是一回事
可以把资源分为:
text
启动必需
首屏展示必需
首屏交互必需
首屏后增强
用户触发时加载优先让用户看到稳定且可操作的最小界面,再延迟非关键资源。
四、分阶段加载示例
text
阶段 1:启动 Logo 和基础配置
阶段 2:登录界面和网络必需资源
阶段 3:主界面首屏资源
阶段 4:后台预加载下一页面
阶段 5:用户进入时再加载大型模块每一阶段都要有失败、取消和重试策略。
五、首屏优化的常见手段
- 减少启动 Scene 的节点和依赖。
- 拆分大 Prefab 和大图集。
- 延迟非关键 Label、动画和特效。
- 预热关键资源,避免首次交互时卡顿。
- 控制并发解码和纹理上传。
- 避免在
onLoad做同步重计算。
六、案例:启动页过度预加载
text
启动页一次 preload 全部商城、活动、战斗、排行榜资源结果:
- 首屏等待时间变长。
- 内存峰值提高。
- 低端设备可能解码失败或被系统杀死。
- 用户只打开主界面,却承担了所有模块成本。
应按用户路径和首屏需要拆分资源。
七、启动优化必须测什么
text
进程启动时间
首屏可见时间
首屏可交互时间
首个操作响应时间
首屏内存峰值
首次进入大模块耗时不要把“加载条走完”当成唯一用户体验指标。
八、常见误区
误区一:启动时把所有资源加载完最安全
会增加首屏等待和内存峰值。
误区二:加载条百分比就是用户等待时间
不同资源阶段的成本不相同,进度应基于真实任务设计。
误区三:只测开发机启动
低端设备、弱网和不同存储速度会改变结果。
误区四:延迟所有资源就一定更快
首屏后首次操作可能出现新的卡顿,需要预热关键资源。
九、练习与答案
- 启动性能至少要区分哪些时间点?
- 为什么不能启动时 preload 所有模块?
- 延迟加载的风险是什么?
- 首屏资源应该如何分层?
答案:
- 进程启动、首屏可见、首屏可交互和首次操作响应。
- 增加等待、峰值和低端设备风险。
- 用户首次进入模块时可能出现等待或卡顿,需要预热和兜底。
- 按启动、首屏、首屏后、用户触发等优先级分层。
给启动链路打标
text
T0 进程/页面开始
T1 引擎启动
T2 Boot Scene 可见
T3 登录/本地配置就绪
T4 Lobby 基础 UI 可见
T5 输入可用
T6 非关键内容完成每个平台选择可获取的最早 T0,并保持版本间口径一致。
Creator 2.4.x 实验:关键与非关键资源拆分
StartupProbe.ts
ts
const { ccclass, property } = cc._decorator;
@ccclass
export default class StartupProbe extends cc.Component {
@property(cc.Node)
basicUi: cc.Node = null;
private startAt = Date.now();
onLoad() {
this.mark('boot-onLoad');
}
start() {
this.basicUi.active = true;
this.mark('first-meaningful-ui');
this.loadDeferred();
}
private loadDeferred() {
cc.resources.load(
'startup/non-critical-panel',
cc.Prefab,
(err) => {
this.mark(err ? 'deferred-failed' : 'deferred-ready');
}
);
}
private mark(name: string) {
cc.log(
'[STARTUP]',
name,
Date.now() - this.startAt
);
}
}对照
- 启动前加载所有资源再显示 Boot。
- 先显示基础 UI,再后台加载非关键。
- 模拟弱网和冷缓存。
- 记录 T2/T4/T5/T6、内存峰值和失败降级。
- 确认后台加载不抢占登录/大厅关键路径。
什么资源属于首屏关键
问:
- 没它能否显示品牌/进度?
- 没它能否登录或进入核心功能?
- 能否用占位图/默认配置?
- 失败是否阻塞用户?
- 后台加载是否会抢 CPU/IO/内存?
不按“以后总会用到”判定关键。
真实项目故障:为了零等待预加载全部 Bundle
启动阶段并发加载大厅、战斗、商城和活动。高速设备总时长不错,低端机却因并发解码和内存峰值崩溃。
修复阶段:
text
Boot 必需
→ 账号/配置
→ Lobby 可交互
→ 空闲时预取高概率下一步
→ 用户选择后加载具体模块加上并发限制、优先级、取消和内存预算。
启动回归矩阵
| 条件 | 必测 |
|---|---|
| 冷/热缓存 | 首次安装、二次启动 |
| 网络 | 离线、弱网、正常 |
| 设备 | 低端、主流、高端 |
| 账号 | 新用户、老用户、大存档 |
| 版本 | 首次升级、资源缓存迁移 |
| 状态 | 后台恢复、来电/切应用 |
版本边界与练习答案
Creator 2.4.x Web、小游戏和 Native 启动入口/工具不同,标记点要映射到各平台,但产品指标保持一致。
- First Frame 与 TTI 有何区别? 前者只要求有画面,TTI 要求核心输入可响应。
- 延后加载是否一定提升体验? 不一定,后台任务可能抢资源,或用户很快进入模块又等待。
- 为什么测新用户与老用户? 存档、缓存、迁移和内容规模不同。
- 启动优化如何防止功能回归? 为每阶段定义依赖和失败回退,做离线/弱网/升级矩阵测试。
十、本课总结
text
启动优化的目标是尽早可见、尽早可操作,同时控制首屏峰值。
加载时机应服务用户路径,而不是把资源一次性全部搬进内存。十一、下一课预告
text
Lesson070|微信小游戏的包体、内存、渲染与平台限制