<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	
	>
<channel>
	<title>
	Comments on: The Composable Architecture: How Architectural Design Decisions Influence Performance	</title>
	<atom:link href="http://www.swiftyplace.com/blog/the-composable-architecture-performance/feed" rel="self" type="application/rss+xml" />
	<link>http://www.swiftyplace.com/blog/the-composable-architecture-performance?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=the-composable-architecture-performance</link>
	<description>Learn how to build amazing apps with SwiftUI and Combine</description>
	<lastBuildDate>Wed, 26 Mar 2025 09:47:02 +0000</lastBuildDate>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1</generator>
	<item>
		<title>
		By: Karin Prater		</title>
		<link>http://www.swiftyplace.com/blog/the-composable-architecture-performance#comment-1001365</link>

		<dc:creator><![CDATA[Karin Prater]]></dc:creator>
		<pubDate>Wed, 26 Mar 2025 09:40:04 +0000</pubDate>
		<guid isPermaLink="false">https://www.swiftyplace.com/?p=1005492#comment-1001365</guid>

					<description><![CDATA[In reply to &lt;a href=&quot;http://www.swiftyplace.com/blog/the-composable-architecture-performance#comment-1001341&quot;&gt;TCAUser&lt;/a&gt;.

I appreciate your comment, but I think you might be misunderstanding how TCA&#039;s architecture actually works under the hood.

Yes, TCA has scoping - but scoping doesn&#039;t change the fundamental dependency flow in the architecture. Let me explain the difference:

&lt;strong&gt;What Actually Happens in TCA&lt;/strong&gt;

1. Dependency Flow: The `Store&lt;AppState, AppAction&gt;` is indeed passed down through the entire view hierarchy as a dependency. Look at how views are structured in TCA:

&lt;code&gt;
struct RootView: View {
    let store: Store&lt;AppState, AppAction&gt;
    
    var body: some View {
        HomeView(store: store) // Passing the entire store down
    }
}

struct HomeView: View {
    let store: Store&lt;AppState, AppAction&gt; // Gets the ENTIRE store as a dependency
    
    var body: some View {
        WithViewStore(store, observe: { state in
            // Only observe the specific parts we need
            return state.userProfile
        }) { viewStore in
            Text(&quot;Hello, \(viewStore.name)&quot;)
            ProfileView(store: store) // Continues passing the entire store down
        }
    }
}

struct ProfileView: View {
    let store: Store&lt;AppState, AppAction&gt; // Again, the ENTIRE store
    
    var body: some View {
        // More UI and potentially more views that receive the store
    }
}
&lt;/code&gt;

The store containing the entire global state is passed down through initializers at each level. This is not something I made up - it&#039;s directly from TCA&#039;s design and standard usage pattern.

2. ViewStore as an Optimization: The `WithViewStore` wrapper is precisely the workaround TCA introduced to deal with the performance problems of having the entire state available everywhere.

The confusion comes from conflating two different things:
- The actual dependency (the Store with full state that flows through initializers)
- The optimization layer (ViewStore that projects specific parts for SwiftUI updates)

&lt;strong&gt;Scoping Doesn&#039;t Change the Dependency Flow&lt;/strong&gt;

When you use `scope()` to create a child store:

&lt;code&gt;let profileStore = store.scope(
    state: { $0.profile },
    action: { AppAction.profile($0) }
)&lt;/code&gt;


You&#039;re creating a lens into the parent store. But the parent store (with the full state) still exists, and the child store is still connected to it. Actions sent to the child store flow back to the parent store and go through the entire reducer hierarchy.

The scoping is indeed &quot;tricking&quot; the view updating system. It&#039;s an optimization layer on top of an architecture that fundamentally passes the entire state tree through the system.

&lt;strong&gt;Why This Matters&lt;/strong&gt;

This distinction is important because the performance issues reported by many developers stem from this exact architectural decision. Even with scoping, TCA still:

1. Processes all actions through the entire reducer hierarchy
2. Maintains a single global state struct
3. Requires diffing the entire state to detect changes

Scoping helps with view updates, but it doesn&#039;t change these fundamental aspects of the architecture that create performance bottlenecks at scale.

&lt;strong&gt; Not a Criticism, Just Architecture Analysis&lt;/strong&gt;

This isn&#039;t about criticizing TCA - it&#039;s about understanding the trade-offs in its design. Every architecture makes trade-offs, and TCA prioritizes predictability and testability over raw performance. That&#039;s a valid choice, but one developers should understand when adopting it.]]></description>
			<content:encoded><![CDATA[<p>In reply to <a href="http://www.swiftyplace.com/blog/the-composable-architecture-performance#comment-1001341">TCAUser</a>.</p>
<p>I appreciate your comment, but I think you might be misunderstanding how TCA&#8217;s architecture actually works under the hood.</p>
<p>Yes, TCA has scoping &#8211; but scoping doesn&#8217;t change the fundamental dependency flow in the architecture. Let me explain the difference:</p>
<p><strong>What Actually Happens in TCA</strong></p>
<p>1. Dependency Flow: The `Store<AppState, AppAction>` is indeed passed down through the entire view hierarchy as a dependency. Look at how views are structured in TCA:</p>
<p><code><br />
struct RootView: View {<br />
    let store: Store<AppState, AppAction></p>
<p>    var body: some View {<br />
        HomeView(store: store) // Passing the entire store down<br />
    }<br />
}</p>
<p>struct HomeView: View {<br />
    let store: Store<AppState, AppAction> // Gets the ENTIRE store as a dependency</p>
<p>    var body: some View {<br />
        WithViewStore(store, observe: { state in<br />
            // Only observe the specific parts we need<br />
            return state.userProfile<br />
        }) { viewStore in<br />
            Text("Hello, \(viewStore.name)")<br />
            ProfileView(store: store) // Continues passing the entire store down<br />
        }<br />
    }<br />
}</p>
<p>struct ProfileView: View {<br />
    let store: Store<AppState, AppAction> // Again, the ENTIRE store</p>
<p>    var body: some View {<br />
        // More UI and potentially more views that receive the store<br />
    }<br />
}<br />
</code></p>
<p>The store containing the entire global state is passed down through initializers at each level. This is not something I made up &#8211; it&#8217;s directly from TCA&#8217;s design and standard usage pattern.</p>
<p>2. ViewStore as an Optimization: The `WithViewStore` wrapper is precisely the workaround TCA introduced to deal with the performance problems of having the entire state available everywhere.</p>
<p>The confusion comes from conflating two different things:<br />
&#8211; The actual dependency (the Store with full state that flows through initializers)<br />
&#8211; The optimization layer (ViewStore that projects specific parts for SwiftUI updates)</p>
<p><strong>Scoping Doesn&#8217;t Change the Dependency Flow</strong></p>
<p>When you use `scope()` to create a child store:</p>
<p><code>let profileStore = store.scope(<br />
    state: { $0.profile },<br />
    action: { AppAction.profile($0) }<br />
)</code></p>
<p>You&#8217;re creating a lens into the parent store. But the parent store (with the full state) still exists, and the child store is still connected to it. Actions sent to the child store flow back to the parent store and go through the entire reducer hierarchy.</p>
<p>The scoping is indeed &#8220;tricking&#8221; the view updating system. It&#8217;s an optimization layer on top of an architecture that fundamentally passes the entire state tree through the system.</p>
<p><strong>Why This Matters</strong></p>
<p>This distinction is important because the performance issues reported by many developers stem from this exact architectural decision. Even with scoping, TCA still:</p>
<p>1. Processes all actions through the entire reducer hierarchy<br />
2. Maintains a single global state struct<br />
3. Requires diffing the entire state to detect changes</p>
<p>Scoping helps with view updates, but it doesn&#8217;t change these fundamental aspects of the architecture that create performance bottlenecks at scale.</p>
<p><strong> Not a Criticism, Just Architecture Analysis</strong></p>
<p>This isn&#8217;t about criticizing TCA &#8211; it&#8217;s about understanding the trade-offs in its design. Every architecture makes trade-offs, and TCA prioritizes predictability and testability over raw performance. That&#8217;s a valid choice, but one developers should understand when adopting it.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Karin Prater		</title>
		<link>http://www.swiftyplace.com/blog/the-composable-architecture-performance#comment-1001364</link>

		<dc:creator><![CDATA[Karin Prater]]></dc:creator>
		<pubDate>Wed, 26 Mar 2025 09:28:19 +0000</pubDate>
		<guid isPermaLink="false">https://www.swiftyplace.com/?p=1005492#comment-1001364</guid>

					<description><![CDATA[In reply to &lt;a href=&quot;http://www.swiftyplace.com/blog/the-composable-architecture-performance#comment-1001354&quot;&gt;NoNeed&lt;/a&gt;.

My personal preference is Vanilla Swiftui. Use MVVM with Reposiory pattern to separate out logic and get testing capabilities.
For larger more complex flows, Coordinators are greate because they can take care of the navigation logic. This allows you thinks like programmatic navigation, deep linking.
I prefer a simple approach when starting a project and then adapt and introduce more design patterns as the app grows. 
These topics are quite vaste and I will for sure write and make videos about them (including more complex demo projects)]]></description>
			<content:encoded><![CDATA[<p>In reply to <a href="http://www.swiftyplace.com/blog/the-composable-architecture-performance#comment-1001354">NoNeed</a>.</p>
<p>My personal preference is Vanilla Swiftui. Use MVVM with Reposiory pattern to separate out logic and get testing capabilities.<br />
For larger more complex flows, Coordinators are greate because they can take care of the navigation logic. This allows you thinks like programmatic navigation, deep linking.<br />
I prefer a simple approach when starting a project and then adapt and introduce more design patterns as the app grows.<br />
These topics are quite vaste and I will for sure write and make videos about them (including more complex demo projects)</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Manu		</title>
		<link>http://www.swiftyplace.com/blog/the-composable-architecture-performance#comment-1001362</link>

		<dc:creator><![CDATA[Manu]]></dc:creator>
		<pubDate>Tue, 25 Mar 2025 16:01:39 +0000</pubDate>
		<guid isPermaLink="false">https://www.swiftyplace.com/?p=1005492#comment-1001362</guid>

					<description><![CDATA[I&#039;ve used TCA on a mid-to-large project, and I have found a lot of problems:
- Performance Issues
- When the compiler doesn&#039;t understand something, the error is not meaningful
- I hate all the 3rd party dependencies that it introduces
- Developer learning curve is really long
- Additional compile time that adds up over time
- Not really straight forward rules (ie: when to share a reducer vs when to add a child reducer)
- Child reducers introduced a lot of extra complexity
In my experience, I&#039;d never pick TCA again, I&#039;d go with vanilla MVVM and only add complexity as needed]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve used TCA on a mid-to-large project, and I have found a lot of problems:<br />
&#8211; Performance Issues<br />
&#8211; When the compiler doesn&#8217;t understand something, the error is not meaningful<br />
&#8211; I hate all the 3rd party dependencies that it introduces<br />
&#8211; Developer learning curve is really long<br />
&#8211; Additional compile time that adds up over time<br />
&#8211; Not really straight forward rules (ie: when to share a reducer vs when to add a child reducer)<br />
&#8211; Child reducers introduced a lot of extra complexity<br />
In my experience, I&#8217;d never pick TCA again, I&#8217;d go with vanilla MVVM and only add complexity as needed</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Andy W.		</title>
		<link>http://www.swiftyplace.com/blog/the-composable-architecture-performance#comment-1001361</link>

		<dc:creator><![CDATA[Andy W.]]></dc:creator>
		<pubDate>Tue, 25 Mar 2025 13:50:40 +0000</pubDate>
		<guid isPermaLink="false">https://www.swiftyplace.com/?p=1005492#comment-1001361</guid>

					<description><![CDATA[Good article, and ties in with my experience. I used TCA in a major project at a former employer, and on top of a significant—and constantly changing—learning curve, very little documentation from third parties, Point Free videos that spent far too long talking about *how* they built rather than how to *use* it, we hit major scaling issues with large state maxing out stack memory. This caused serious out of memory errors that we struggled to fix. What documentation there was, was contradictory, and the constant rewrites and alterations on &#039;best practice&#039; made it hard to know what was the correct way to use it. Going forward, I have vowed never to work for a company using it again, as it felt like it was fighting SwiftUI and Apple standards, rather than working with them. Technically brilliant, but for all its good points we found one or more downsides that sucked up any speed advantage we gained.]]></description>
			<content:encoded><![CDATA[<p>Good article, and ties in with my experience. I used TCA in a major project at a former employer, and on top of a significant—and constantly changing—learning curve, very little documentation from third parties, Point Free videos that spent far too long talking about *how* they built rather than how to *use* it, we hit major scaling issues with large state maxing out stack memory. This caused serious out of memory errors that we struggled to fix. What documentation there was, was contradictory, and the constant rewrites and alterations on &#8216;best practice&#8217; made it hard to know what was the correct way to use it. Going forward, I have vowed never to work for a company using it again, as it felt like it was fighting SwiftUI and Apple standards, rather than working with them. Technically brilliant, but for all its good points we found one or more downsides that sucked up any speed advantage we gained.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Wow		</title>
		<link>http://www.swiftyplace.com/blog/the-composable-architecture-performance#comment-1001355</link>

		<dc:creator><![CDATA[Wow]]></dc:creator>
		<pubDate>Tue, 25 Mar 2025 13:10:25 +0000</pubDate>
		<guid isPermaLink="false">https://www.swiftyplace.com/?p=1005492#comment-1001355</guid>

					<description><![CDATA[Nice insights wow]]></description>
			<content:encoded><![CDATA[<p>Nice insights wow</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: NoNeed		</title>
		<link>http://www.swiftyplace.com/blog/the-composable-architecture-performance#comment-1001354</link>

		<dc:creator><![CDATA[NoNeed]]></dc:creator>
		<pubDate>Tue, 25 Mar 2025 13:09:11 +0000</pubDate>
		<guid isPermaLink="false">https://www.swiftyplace.com/?p=1005492#comment-1001354</guid>

					<description><![CDATA[Can you give us better architecture implementation?]]></description>
			<content:encoded><![CDATA[<p>Can you give us better architecture implementation?</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Oliver		</title>
		<link>http://www.swiftyplace.com/blog/the-composable-architecture-performance#comment-1001344</link>

		<dc:creator><![CDATA[Oliver]]></dc:creator>
		<pubDate>Mon, 24 Mar 2025 17:29:59 +0000</pubDate>
		<guid isPermaLink="false">https://www.swiftyplace.com/?p=1005492#comment-1001344</guid>

					<description><![CDATA[A lot of this article is based on things that have long since been updated in TCA or things that just aren&#039;t true and never have been.

It is never the case that the &quot;entire app state&quot; is passed to every view and every child view.

Not is it true that the state has to hold everything in it. It is quite common (and good practise) for views (reducers/state) to get state from dependencies. Whether that&#039;s an in memory cache, or core data, or the network etc... it doesn&#039;t need to be stored globally for the whole stack to access. TBF that was an initial misunderstanding I had when I first used TCA several years ago before I used TCA in anything more than a tutorial sized app.]]></description>
			<content:encoded><![CDATA[<p>A lot of this article is based on things that have long since been updated in TCA or things that just aren&#8217;t true and never have been.</p>
<p>It is never the case that the &#8220;entire app state&#8221; is passed to every view and every child view.</p>
<p>Not is it true that the state has to hold everything in it. It is quite common (and good practise) for views (reducers/state) to get state from dependencies. Whether that&#8217;s an in memory cache, or core data, or the network etc&#8230; it doesn&#8217;t need to be stored globally for the whole stack to access. TBF that was an initial misunderstanding I had when I first used TCA several years ago before I used TCA in anything more than a tutorial sized app.</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: TCAUser		</title>
		<link>http://www.swiftyplace.com/blog/the-composable-architecture-performance#comment-1001341</link>

		<dc:creator><![CDATA[TCAUser]]></dc:creator>
		<pubDate>Mon, 24 Mar 2025 15:06:07 +0000</pubDate>
		<guid isPermaLink="false">https://www.swiftyplace.com/?p=1005492#comment-1001341</guid>

					<description><![CDATA[Every view in your hierarchy, no matter how deeply nested, receives the entire application state struct. This is by design in TCA – it ensures every component has access to the full state.

that is so wrong have you heard of scoping ?]]></description>
			<content:encoded><![CDATA[<p>Every view in your hierarchy, no matter how deeply nested, receives the entire application state struct. This is by design in TCA – it ensures every component has access to the full state.</p>
<p>that is so wrong have you heard of scoping ?</p>
]]></content:encoded>
		
			</item>
		<item>
		<title>
		By: Fotis		</title>
		<link>http://www.swiftyplace.com/blog/the-composable-architecture-performance#comment-1001339</link>

		<dc:creator><![CDATA[Fotis]]></dc:creator>
		<pubDate>Mon, 24 Mar 2025 12:59:24 +0000</pubDate>
		<guid isPermaLink="false">https://www.swiftyplace.com/?p=1005492#comment-1001339</guid>

					<description><![CDATA[&#062; Recent versions have introduced significant improvements like the new reducer protocol, and they’re actively working on Observation framework integration

The reducer protocol was announced in October 2022: https://www.pointfree.co/blog/posts/81-announcing-the-reducer-protocol and Observation in January 2024: https://www.pointfree.co/blog/posts/130-observation-comes-to-the-composable-architecture
WithViewStore has been deprecated since 1.7: https://pointfreeco.github.io/swift-composable-architecture/main/documentation/composablearchitecture/withviewstore/]]></description>
			<content:encoded><![CDATA[<p>&gt; Recent versions have introduced significant improvements like the new reducer protocol, and they’re actively working on Observation framework integration</p>
<p>The reducer protocol was announced in October 2022: <a href="https://www.pointfree.co/blog/posts/81-announcing-the-reducer-protocol" rel="nofollow ugc">https://www.pointfree.co/blog/posts/81-announcing-the-reducer-protocol</a> and Observation in January 2024: <a href="https://www.pointfree.co/blog/posts/130-observation-comes-to-the-composable-architecture" rel="nofollow ugc">https://www.pointfree.co/blog/posts/130-observation-comes-to-the-composable-architecture</a><br />
WithViewStore has been deprecated since 1.7: <a href="https://pointfreeco.github.io/swift-composable-architecture/main/documentation/composablearchitecture/withviewstore/" rel="nofollow ugc">https://pointfreeco.github.io/swift-composable-architecture/main/documentation/composablearchitecture/withviewstore/</a></p>
]]></content:encoded>
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 

Served from: www.swiftyplace.com @ 2026-08-24 11:48:44 by W3 Total Cache
-->