Skip to content

性能优化

VirtualViewList 通过智能缓存、自适应刷新率、分帧加载等机制,确保在大数据量场景下保持流畅体验。

智能性能管理

自适应刷新率(3档)

启用 autoOptimizePerformance 后,组件会根据滚动速度自动调整刷新频率:

滚动速度刷新率适用场景
快速(> 50px/帧)30fps减少渲染压力,避免掉帧
中速(5-50px/帧)60fps标准流畅度,平衡性能
慢速/静止(≤ 5px/帧)120fps超流畅显示,细腻动画

关键特性

  • 一次滑动固定刷新率:滑动开始时确定刷新率,整个过程保持不变,避免刷新率波动导致的闪烁
  • 智能判断:可通过 GetStatus().isLowPerformanceMode 检测当前模式,动态关闭特效

动态缓冲区

配置默认值说明
cacheRatio0.1基础预加载比例(0.1 = 可见区域的 10%)
快速滚动加成2x速度 > 50px/帧时自动扩大到 2 倍缓冲

推荐配置

  • 普通列表:0.1 - 0.2(节省内存)
  • 快速滚动场景:0.2 - 0.3(减少白屏)
  • 慢速浏览场景:0.05 - 0.1(最小化开销)

分帧加载策略

组件内置分帧加载机制,避免大量节点一次性创建导致卡顿:

ts
// 预加载节点(在 start 前调用)
list.PreloadItems(10);

// 分批加载数据
list.ReloadData(types);  // 自动启用分帧加载

自动分帧触发条件

  • 数据量 > 50 项
  • 可见节点 > 20 个
  • 首次加载场景

增量更新优化

使用增量更新方法可避免全量重建,大幅提升性能:

方法性能优势适用场景
PrependData只创建新增节点聊天刷新、消息推送
AppendData只创建新增节点分页加载、滚动加载更多
RefreshData仅更新变化项数据刷新、排序、筛选
UpdateItemAt仅更新单项单条数据变更

示例:增量刷新排行榜

ts
// ❌ 差:全量重建(慢)
list.ReloadData(newRankData);

// ✅ 好:增量刷新(快)
list.RefreshData(newRankData, true, (oldItem, newItem, index) => {
  return oldItem.id === newItem.id && oldItem.rank === newItem.rank;
});

大数据集优化

内置优化

  • 10000+ 数据:采样计算,避免全量遍历
  • 尺寸缓存:自动缓存已计算的布局数据
  • 可见区间缓存:减少重复计算

建议

  • 单列表数据量 < 50000 项(超大数据建议后端分页)
  • 动态高度列表 < 10000 项(计算开销较大)

节点与资源优化

1. 轻量化节点结构

ts
// ❌ 差:复杂结构
Item (10+ 子节点,多个组件)
  └─ Background
      └─ Icon
          └─ Badge
              └─ Label

// ✅ 好:简化结构
Item (3-5 个子节点)
  ├─ Icon
  ├─ Label
  └─ Badge

2. 延迟资源加载

ts
onItemInit(node: Node, index: number) {
  // ✅ 先显示占位
  const icon = node.getComponent(Sprite);
  icon.spriteFrame = this.placeholderFrame;
  
  // ✅ 异步加载资源
  resources.load(iconPath, SpriteFrame, (err, frame) => {
    if (node.isValid) {
      icon.spriteFrame = frame;
    }
  });
}

3. 模板复用策略

ts
// ❌ 差:每种样式一个模板
list.RegisterTemplates([
  { type: 'text', node: textPrefab },
  { type: 'text-bold', node: textBoldPrefab },
  { type: 'text-red', node: textRedPrefab },
  // ...太多模板,对象池效率低
]);

// ✅ 好:统一模板,动态调整样式
list.RegisterTemplate('text', textPrefab, true);
onItemUpdate(node, index) {
  const label = node.getComponent(Label);
  label.string = data[index].text;
  label.fontSize = data[index].large ? 24 : 18;
  label.color = data[index].isRed ? Color.RED : Color.WHITE;
}

调试与监控

开启调试模式

ts
list.EnableDebugMode(true);  // 仅开发环境使用

// 查看性能状态
const status = list.GetStatus();
console.log('数据量:', status.itemCount);
console.log('可见节点:', status.visibleCount);
console.log('对象池大小:', status.poolSize);
console.log('低性能模式:', status.isLowPerformanceMode);

性能检测清单

  1. 帧率监控:保持 60fps,滚动时允许降至 30fps
  2. DrawCall:单次滚动新增 DrawCall < 10
  3. 内存占用:对象池大小适中(通常为可见节点数的 2-3 倍)
  4. 白屏检测:快速滑动时观察是否出现空白区域

常见性能问题排查

问题可能原因解决方案
滚动卡顿节点结构复杂简化节点层级,减少组件数量
首屏加载慢未预加载调用 PreloadItems(10)
快速滚动白屏缓冲区太小提高 cacheRatio 到 0.2-0.3
内存占用高缓冲区过大降低 cacheRatio,减少模板种类
动画卡顿同时播放太多使用动画队列,限制并发数量

性能基准参考

在标准移动设备(骁龙 660 级别)上的测试数据:

场景数据量帧率内存增量
简单文本列表1000060fps~15MB
图文混排列表500060fps~30MB
网格布局(3 列)1000060fps~40MB
动态高度聊天300060fps~25MB

若性能达不到预期,建议使用 Cocos Profiler 深入分析,或联系技术支持。