Summary:
When using the new .focused modifier to track focus within a large LazyVStack or LazyHStack, we observe a major frame-rate drop and stuttering on Apple TV (1st and 2nd generation).
Steps to Reproduce:
- Create a LazyVStack (or LazyHStack) displaying a substantial list of data models (e.g., 100+ GroupData items).
- Attach the .focused(::) modifier to each row, binding to an @FocusState variable of the same model type.
- Build and run on an Apple TV device or simulator.
- Scroll through the list using the remote.
static func == (lhs: GroupData, rhs: GroupData) -> Bool { lhs.id == rhs.id } var id: String var name: String var subName: String var subGroup: [GroupData] = [] var logo: URL? } struct TestView: View { @FocusState var focusedGroup: GroupData? let groupsArr: [GroupData] var body: some View { ScrollView { LazyVStack { ForEach(groupsArr, id: \.id) { group in Button { } label: { GroupTestView(group: group) } .id(group.id) .focused($focusedGroup, equals: group) } } } } } struct GroupTestView: View { let group: GroupData var body: some View { HStack { KFImage.url(group.logo) .placeholder { Image(systemName: "photo") .opacity(0.2) .imageScale(.large) } .resizable() .scaledToFit() .frame(width: 70) VStack { Text(group.name) Text(group.subName) } } } }
Expected Behavior
- Scrolling remains smooth (60 fps) regardless of list size.
- Focus updates without introducing visible lag.
Observed Behavior
- Frame rate drops significantly when .focused is applied.
- Scrolling becomes visibly laggy, especially on older Apple TV hardware.
- Even when binding an @FocusState<String?> (storing only the id), performance improves slightly but remains suboptimal.
Workarounds Tried
- Switched to @FocusState of type String to track only the ID of each group, this has helped but there is still a big performance decrease.
- Minimised view-body complexity and removed other modifiers.
- Verified that excluding .focused entirely restores smooth scrolling.
Any guidance or suggestions would be greatly appreciated.