macOS Sonoma中ScrollView嵌套LazyVGrid性能优化:如何实现120FPS?
如何让macOS SwiftUI的LazyVGrid在ProMotion显示屏上达到120FPS?
我们开发了一款简单的macOS SwiftUI应用,仅在ScrollView内嵌套显示数字的LazyVGrid,无复杂功能。但在16英寸MacBook Pro M2 Max全屏运行时,帧率仅约50FPS,滚动不流畅。帧率通过Quartz Debug(可从Xcode 15附加工具中获取)测量。
示例代码
struct GridTest: View { @State var data = (1...30000).map { "\($0)" } //doesn't matter if this is adaptive or fixed..it is still slow //there is no way to hit 120Hz on mac? let columns = [GridItem(.fixed(90)), GridItem(.fixed(90)), GridItem(.fixed(90)), GridItem(.fixed(90)), GridItem(.fixed(90)), GridItem(.fixed(90)), GridItem(.fixed(90)), GridItem(.fixed(90)), GridItem(.fixed(90)), GridItem(.fixed(90)), GridItem(.fixed(90)), GridItem(.fixed(90)), GridItem(.fixed(90)), GridItem(.fixed(90)), GridItem(.fixed(90)) ] var body: some View { ScrollView { LazyVGrid(columns: columns) { ForEach(data, id: \.self) {item in Text(item).frame(width: 100, height: 30) } }.frame(width: 1700) } } }//GridTest
优化方案
- 匹配网格项与内容尺寸:GridItem设置为
.fixed(90),但Text的frame是width:100,内容超出网格范围会触发额外布局计算。将Text的width改为90,或调整GridItem尺寸匹配Text,消除布局冲突。 - 移除固定宽度限制:给LazyVGrid设置
.frame(width:1700)会限制自适应能力,改为.frame(maxWidth: .infinity)让网格自动适配ScrollView宽度,减少强制布局开销。 - 优化滚动视图配置:给ScrollView添加
.frame(maxWidth: .infinity, maxHeight: .infinity)占满全屏,让系统更好管理滚动区域;如果不需要滚动指示器,添加.scrollIndicators(.hidden)减少渲染负担。 - 简化文本渲染:给Text添加
.monospaced()使用等宽字体,这类字体的布局计算更高效;若字体大小无特殊要求,设置.font(.system(size: 12))进一步降低渲染压力。 - 检查系统与环境:确保Mac“显示器”设置中启用ProMotion(刷新率设为自动),关闭占用GPU的后台应用,避免资源竞争。
- 借助调试工具定位问题:用Xcode的“Debug View Hierarchy”检查冗余视图层级;用Instruments的“Core Animation”模板分析帧率瓶颈,重点查看是否存在频繁重绘或布局计算耗时。
内容的提问来源于stack exchange,提问作者Juraj Antas
相关产品推荐
相关产品推荐

