title: SwiftUI view updates even if it does not depend on a dynamic property
body: <p>I created an <code>ObservableObject</code> that gathers data and a view that depends on this object. More specifically some parts of the UI depend on one property of it and other parts depend on other properties.</p>
  <p>The way <code>ObservableObject</code> works is that if <strong>any</strong> of its <code>Published</code> property gets updated (event if it does not change) it sends an <code>objectWillChange</code> notification that triggers updates for subscribed views.</p>
  <p>However, I did expect that only the parts of the views that depends on an <code>ObservableObject</code> property that actually changed would be updated, not the entire view because body computations are expensive.</p>
  <p>Unfortunately this it not the behavior I observed during my experiments. For instance in the following code the <code>List</code> view depends only on the <code>color</code> dynamic property of the <code>ObservedObject</code> &quot;preferences&quot; and the <code>TextField</code> updates only the <code>text</code> property of the observed object. I observed with the <code>debugPrint</code>'s that when I type text the List and its rows gets updated each time even if it does not depend on <code>text</code>.</p>
  <pre class="lang-swift prettyprint-override"><code>struct ContentView: View {
      @State private var list = [&quot;foo&quot;, &quot;bar&quot;, &quot;baz&quot;]
      @StateObject private var preferences = Preferences()
      
      var body: some View {
          VStack {
              List(list, id: \.self) { element in
                  Text(element)
                      .foregroundColor(preferences.color)
                      .debugPrint(&quot;Row view updated&quot;)
              }
              
              Spacer()
              
              HStack {
                  TextField(&quot;Text&quot;, text: $preferences.text)
                      .debugPrint(&quot;Text field view updated&quot;)
                  
                  Button(&quot;Toogle Color&quot;, action: toggleColor)
                      .debugPrint(&quot;Button view updated&quot;)
              }
          }
          .padding()
          .debugPrint(&quot;Content view updated&quot;)
      }
      
      func toggleColor() {
          preferences.color = [.blue, .green, .orange, .red].randomElement()!
      }
  }
  
  final class Preferences: ObservableObject {
      @Published var color: Color = .blue
      @Published var text: String = &quot;&quot;
  }
  
  extension View {
      func debugPrint(_ elements: Any...) -&gt; Self {
          #if DEBUG
          print(elements)
          return self
          #else
          return self
          #endif
      }
  }
  </code></pre>
  <p><strong>Is this the correct and intended behavior? How the optimal behavior I described above could be obtained, i.e. not calling <code>body</code> when the <code>ObservedObject</code> changes but only the components that depends on specific properties?</strong></p>
  <p>I observed in bigger SwiftUI projects that this behavior can greatly slow down the application and is not easily debuggable because unique state is often enforced through heavy <code>ObservedObject</code>s (or <code>StateObject</code>) injected at the root view and used in many places. <strong>I Observed this behavior even with small lists of components with heavy UI layout.</strong></p>
  <p><strong>Note 1:</strong> I was bugged by the <code>StateObject</code> definition which suggests that only the views that depend on those properties are updated (and not when the <code>StateObject</code> changes).</p>
  <blockquote>
  <p>SwiftUI creates a new instance of the object only once for each
  instance of the structure that declares the object. When published
  properties of the observable object change, SwiftUI updates the parts
  of any view that depend on those properties [...]</p>
  </blockquote>
  <p><strong>Note 2:</strong> The issue totally disappear if I define the <code>List</code> in its own component, the rendering is fast:</p>
  <pre class="lang-swift prettyprint-override"><code>struct ListView: View {
      let list: [String]  // Also works with a @Binding
      
      let color: Color  // Also works if it would be `preferences`
      
      var body: some View {
          List {
              ForEach(list, id: \.self) { element in
                  Row(text: element, color: color)
              }
          }
      }
  }
  </code></pre>
  <p>Why in this case the view updates are fast?</p>