Load NavigationLink destination lazily

NavigationLink needs a constructed destination to work, as opposed to modals (.sheet/.fullScreenCover) where the destination is lazy.

Creating views in SwiftUI is very light, but it's not the same when you're working with hundreds of entries on a list and each row creates its own NavigationLink(s), plus those views also create (on init or through a factory) their dependencies (ViewModel, DataModel, Logic, etc).

This means every time the view is updated all the displayed NavigationLinks will be recreated, consuming a lot of resources that are not needed since those destination views could not ever be used if the user doesn't navigate there.

Should we have a NavigationLink that takes a destination lazily, or is there something else I'm missing?

In this regard, there's another issue which is views "popping" on a NavigationView don't get deallocated. This works just fine with modals, views presented modally deallocate as soon as the user go back, but it's not the case for views loaded using NavigationLink. I think it's related to the issue I described above. Is this intended behaviour?

Thank you.
I wonder this too! I wrote a very similar question on StackOverflow! Would love a better solution than the ones I've written in my question: https://stackoverflow.com/questions/62608110/conditional-navigationlink-depending-on-optional-struct-created-by-user-in-view
You can use LazyView (by Chris Eidhof): https://gist.github.com/chriseidhof/d2fcafb53843df343fe07f3c0dac41d5

Luca Bernardi, a SwiftUI engineer, said in a Twitter thread this is how SwiftUI works:

Exactly, SwiftUI expects view creation to be cheap: the system can recreate views often.
For example, allocating NSFormatter in the init is not a good: you’ll pay the cost of heap allocation (and initialization) every time the view hierarchy is updated.
(I can't link the referenced tweet here but the reference id of the tweet is 1144312093597769728.)

That said, I'd like to understand why it works like this for NavigationLink but not for views presented modally, and why not give us, the developers, the option built-in in SwiftUI, so we are left to choose the approach that fits best for us.
Lazy Loading is needed, especially when each view needs to pull data from the backend. Sure apple can have their "cheap" creation and keep what they feel is a perfect design, but in the real world many apps pull data from the backend and this is causing a lot on unnecessary server traffic. I know there is onAppear, but onAppear has all sorts of side effects, in my app it seems onAppear gets called twice for many forms, doubling the network traffic.

It seems to me that the SwiftUI team are great at writing simple test apps, but when you try to write something more complicated, SwiftUI gets exponentially complicated. Defeats the entire purpose...
Additionally, because the destination is constructed, you must construct the view model if you are using MVVM and injecting your view models as @ObservedObjects. This makes IoC patterns really pointless.

Also, these view models (or any dependencies really) are never released that I can see.
Load NavigationLink destination lazily
 
 
Q