为何遍历数组索引的ForEach会降低列表滚动性能?
为什么用数组元素ID的ForEach比用索引的滚动性能好?
这本质是SwiftUI的视图身份追踪机制在起作用,直接决定了视图的复用逻辑,进而影响滚动性能:
用元素自身ID的情况
因为你的数组元素遵循Identifiable协议,每个元素的id是唯一且稳定的标识(和它在数组里的位置无关)。当列表滚动时,SwiftUI会通过这个id精准识别每个元素对应的视图实例:- 滚出屏幕的视图会被系统缓存,当对应元素再次滚回屏幕时,直接复用已有的视图实例,只需要更新视图内部的内容(如果有变化),不需要重新初始化
MyRowView。 - 对于5万条的大数据量,这种复用能极大减少视图创建/销毁的开销,滚动自然流畅。
- 滚出屏幕的视图会被系统缓存,当对应元素再次滚回屏幕时,直接复用已有的视图实例,只需要更新视图内部的内容(如果有变化),不需要重新初始化
用数组索引当ID的情况
索引代表的是元素在数组中的位置,而非元素本身。当列表滚动时,屏幕上显示的索引会不断变化(比如从显示0-20变成显示3-23),SwiftUI会把每个新出现的索引当成全新的视图身份:- 哪怕某个位置的元素内容和之前屏幕上的某个元素完全一样,只要索引变了,系统就会重新创建
MyRowView实例。 - 5万条数据滚动时,会频繁触发大量视图的初始化和销毁,CPU和内存开销剧增,直接导致滚动卡顿。
- 哪怕某个位置的元素内容和之前屏幕上的某个元素完全一样,只要索引变了,系统就会重新创建
哪怕你完全没修改数组,只要滚动时屏幕上的索引在变动,用索引当ID就会持续触发不必要的视图重建——这就是两种写法性能差异的核心原因。
内容的提问来源于stack exchange,提问作者User95797654974
相关产品推荐
相关产品推荐

