← ClaudeAtlas

cocos-creator-ui-listlisted

做 Cocos Creator 大量条目列表时使用。虚拟列表、节点复用。
Wade-DevCode/awesome-coding-skills-cn · ★ 3 · Web & Frontend · score 78
Install: claude install-skill Wade-DevCode/awesome-coding-skills-cn
# Cocos Creator 长列表优化 ## 何时用 - 排行榜、好友列表、背包物品、聊天记录等条目数量超过 50 条时。 - ScrollView 滑动时帧率下降,Profiler 显示大量 `Layout` 或 `Sprite` 更新耗时时。 - 启动时一次性 `instantiate` 了几百个 item 节点导致进入场景卡顿时。 - 列表数据频繁刷新(如实时排行榜推送)但整体 CPU 占用居高不下时。 - 图片异步加载导致列表滚动时出现闪烁或短暂空白占位时。 ## 核心规则 ### 1. 虚拟列表:只实例化可视区 + 缓冲节点,滚动时复用 **规则:** 不论列表数据有多少条,同时存在于场景节点树中的 item 节点数量 = 可视区可容纳数量 + 固定缓冲量(通常 4~6 个);滚动时将移出可视区的节点重新定位到新进入可视区的位置并更新数据,不增减节点数量。 **为什么:** 这是长列表性能的根本问题。AI 生成列表代码时的惯用写法是循环 `cc.instantiate(itemPrefab)` 并 `addChild` 全部数据——500 条排行榜就创建 500 个节点,每个节点含 Sprite、Label、Button,光是节点树渲染遍历就够卡的。实测在中端安卓机上,一次性创建 200 个含图片的列表节点耗时超过 1 秒,直接导致进入场景的白屏卡顿。更致命的是:ScrollView 的 `content` 节点拖 Layout 组件后,每次 `addChild` 都会触发整个 Layout 的重排,200 次 `addChild` = 200 次全量重排,复杂度是 O(n²)。 **怎么做:** - 计算可视区高度 / 单个 item 高度,得到可见数量 `visibleCount`,加缓冲 `visibleCount + 6` 作为实际节点池大小。 - `onLoad` 里只创建这么多节点放入节点池,`content` 节点不挂 Layout 组件(手动控制 `y` 坐标)。 - `content` 节点高度设为 `总条目数 × itemHeight`,让 ScrollView 滚动条正确反映总量。 - 监听 ScrollView 的 `SCROLL_EV` 或在 `update` 里用节流检测滚动偏移,计算当前第一个可见索引 `firstIndex`,遍历节点池把每个节点的 `y = -(firstIndex + i) * itemHeight`,并调用 `refreshItem(node, data[firstIndex + i])` 更新数据。 --- ### 2. 节点复用池:对象池管理 item 节点,避免滚动时频繁创建销毁 **规则:** item 节点用 `NodePool`(或简单数组)管理复用,不在滚动回调里 `instantiate`/`destroy`;归还节点时在 `unuse` 钩子里重置所有可视状态(图片、文字、选中态),避免残留数据。 **为什么:** 即使实现了虚拟列表,如果每次 item 滑出可视区就 `destroy`、滑入就 `instantiate`,性能依然很差。`instantiate` 一个含多个子节点的 prefab 在移动端耗时 5~20 ms,60fps 的帧预算只有 16ms,几个 item 同时进入视野就直接掉帧。更隐蔽的问题:归还节点时不重置状态,下次从池里取出的节点仍然显示上一个位置的数据(旧头像、旧分数),等异步加载完成后才刷新,用户会看到数据"