Ответ
SwiftUI по умолчанию инициализирует представление, переданное в destination у NavigationLink, или дочерние представления в List/ForEach, сразу при построении родительского view. Это может вызвать ненужные вычисления и потребление памяти, если представление тяжелое и пока не отображается.
Проблемный код:
struct ContentView: View {
var body: some View {
NavigationView {
// HeavyView создается и инициализируется СРАЗУ, даже без перехода.
NavigationLink("Перейти", destination: HeavyView())
}
}
}
struct HeavyView: View {
// Тяжелые вычисления в инициализаторе или body
init() { print("HeavyView инициализирован") }
var body: some View { /* сложная структура */ }
}
Решение: обертка LazyView
Создайте обертку, которая откладывает создание контента до момента, когда он действительно понадобится для отрисовки.
struct LazyView<Content: View>: View {
let build: () -> Content
init(_ build: @autoclosure @escaping () -> Content) {
self.build = build
}
var body: some View {
build() // Создание происходит здесь, при первом рендеринге body LazyView.
}
}
// Использование
NavigationLink("Перейти", destination: LazyView(HeavyView()))
// Теперь HeavyView будет создан только в момент фактического перехода по ссылке.
Где это критично:
NavigationLink(destination:)- Сложные, условно отображаемые представления внутри
ifилиswitch. - Глубоко вложенные иерархии представлений.
Примечание: В современных версиях SwiftUI NavigationLink с инициализатором, принимающим value и destination, часто ведет себя «ленивее». Однако LazyView остается универсальным и явным решением.