别让长列表拖慢首屏:用 AI + LazyVStack 给 iOS 页面减负
2026/7/2 · 8:11

别让长列表拖慢首屏:用 AI + LazyVStack 给 iOS 页面减负

今天这一技教你识别 SwiftUI 里可能拖慢首屏的长列表,并让 AI 把合适的 `ScrollView + VStack` 改成 `LazyVStack`。PM 不用先学性能分析,也能用多组假数据验收页面是否打开更快、滚动更稳。

一条商品列表只有十几项时,VStack 通常没什么问题;一旦你把订单、消息、搜索结果、课程目录这种页面塞到上百项,首屏就可能开始发闷:打开慢、滑动粘、从详情页返回时还要等一下。
这期先不讲性能术语,只抓一个 PM 能直接下给 AI 编码工具的改法:如果一个长列表被写成 ScrollView + VStack,先让 AI 检查能不能改成 ScrollView + LazyVStack。Apple 对 LazyVStack 的定义很直接:它垂直排列子视图,并且只在需要时创建项目。1

这个技巧解决什么问题

普通 VStack 像是让 App 先把整条长列表都摆好,再把第一页给用户看。列表越长,首屏要等的东西越多。
Apple 在 WWDC20 讲过一个类似场景:ScrollView 里放 VStack 展示不断增长的图片列表,内容越多,页面变得可响应所需时间越长;换成 LazyVStack 后,列表会随着内容进入可见区域再逐步加载。2
对 PM 来说,你不用先判断「CPU」「内存」「主线程」这些词。你只需要识别一个产品信号:这个页面本来是给用户滚动浏览的,但用户还没滚动,App 就在为后面几百行买单。
适合先查的页面有这些:
  • 搜索结果、订单列表、消息列表、通知中心、课程目录。
  • 每一行结构相近,只是文字、图片或状态不同。
  • 页面在测试数据多起来以后,打开明显慢于普通详情页。
  • 你希望保留自定义卡片样式,而不是完全套系统列表外观。
不适合一上来就改的地方也要说清楚:只有三五个固定模块的设置页、个人资料页、支付确认页,继续用普通 VStack 更简单。Apple 在同一个 WWDC20 视频里也提醒:不确定该用哪种 stack 时,先用 VStackHStack;Lazy Stacks 更适合作为发现性能瓶颈后的处理手段。2

先让 AI 找出「可疑长列表」

把下面这段直接丢给你的 AI 编码工具,让它先检查,不要马上改代码:
请在当前 iOS SwiftUI 项目里找出可能影响首屏速度的长列表页面。重点检查 ScrollView 里面是否直接包了 VStack,并列出这些页面:页面名、列表数据来源、每行大概包含什么、是否可以安全改成 LazyVStack。先给判断表,不要直接修改代码。
你要看的不是代码漂不漂亮,而是 AI 返回的判断是否像产品事实:这个页面是不是会有很多行?这些行是不是用户滚动时才需要看到?如果答案都成立,再进入下一步。
可以要求 AI 按这个表回你:
页面现在的写法为什么可疑建议动作
搜索结果页ScrollView + VStack结果可能超过 100 条,首屏只显示前几条改为 LazyVStack,保留卡片样式
设置页VStack固定 8 个入口,不是长列表不改
表里如果全是「建议优化」「提升体验」这种空话,就让它重来。你需要它说清楚页面、数据量和可见范围。

再让 AI 做最小改动

确认页面适合后,再给第二条指令:
请只改这个页面的列表容器:把 ScrollView 里的外层 VStack 改成 LazyVStack,保留现有 spacing、padding、卡片样式和点击逻辑。不要重构数据模型,不要改接口,不要改视觉文案。改完后告诉我改了哪一处,以及有没有影响空状态和错误状态。
你要控制 AI 的手,不然它很容易顺手做大重构。这个技巧的目标是减掉首屏多余负担,不是重写页面。
代码层面通常只是这种量级:
ScrollView {
    LazyVStack(spacing: 12) {
        ForEach(items) { item in
            ItemRow(item: item)
        }
    }
}
Hacking with Swift 的示例也强调了同一个点:VStackHStack 在滚动容器里会提前加载内容;想让内容滚入视野时再创建,就用 LazyVStackLazyHStack3
这里有个小坑:Lazy 不等于永远省内存。Hacking with Swift 也提醒,视图第一次显示后会留在内存里。3 所以如果每一行都在下载大图、解析富文本,LazyVStack 只能解决「一开始别全创建」的问题,不能替你解决图片缓存和数据处理。

PM 怎么验收,不用装作工程师

让 AI 帮你造三组测试数据:10 条、100 条、1000 条。你不需要知道这些数据从哪里来,只要它们能把真实行样式撑起来。
然后按这个顺序验收:
  1. 首屏打开:1000 条时,页面是否比改前更快出现第一屏内容。
  2. 快速滚动:从顶部快速滑到底部,卡片是否明显卡住、重复闪烁或跳位。
  3. 返回再进入:从任意一行进入详情页,再返回列表,滚动位置和点击状态是否正常。
  4. 空状态和错误状态:列表为空、接口失败时,原来的提示是否还在。
  5. 小屏和大字号:如果行高变大,列表是否仍然能正常滚动,底部按钮有没有遮住最后几行。
如果第 1 条变好,但第 2 条变差,不要急着发布。把现象写给 AI:
改成 LazyVStack 后首屏变快,但快速滚动时第 30 行以后图片闪烁。请只检查行内图片加载和缓存,不要重写列表结构。
这样你能把问题压在一个小范围里,而不是让 AI 把整个页面拆掉重做。

什么时候该用 List,而不是 LazyVStack

LazyVStack 适合自定义卡片流、瀑布式内容、复杂视觉布局。List 更像系统自带的列表容器,原生支持很多列表行为。Apple 在 WWDC20 里说,List 内容总是懒加载,并且带有选择、滚动等交互支持。2
一个实用判断是:如果你要的是系统通讯录、设置项、邮件列表那种标准手感,先问 AI 能不能用 List。如果你要的是高度自定义的商品卡、课程卡、社区帖子卡,再考虑 ScrollView + LazyVStack。FIVE STARS 的实践文章也把这个差别说得很直白:ScrollView + lazy stacks 更灵活,List 更适合追求 iOS 系统外观和列表特性。4

今天就做这一件事

打开你的项目,让 AI 找出一个 ScrollView + VStack 的长列表。只挑一个页面改,不要全项目扫荡。
你今天的完成标准也很简单:1000 条测试数据能打开、能滚动、能返回,空状态和错误状态没有丢。做到这一步,这个技巧就已经帮你少了一类「页面越做越慢,但不知道哪里慢」的问题。

関連コンテンツ

  • ログインするとコメントできます。