Most instances of user-interactable programming ends up being event-driven in some way. In iOS, you'll find this everywhere.
- as lifecycle methods like `viewDidAppear` or `viewWillDisappear`
- as `@IBAction`s that you use to hook up a button to its target
- as `NSNotification`s that trigger when Core Data stores are written to
- as completion handlers that trigger when asynchronous operations complete
- as `tableView(_:didSelectRowAt:)` delegate methods when a user taps on a table view cell
- as `#selector`s when performing KVO
You're notified when users do something, the environment changes, lifecycle functions trigger, etc.
All of these "events" that we handle are the results of side effects – operations performed and handled by the system that are handed to us to react to.
---
I'll actually stop here because there's actually some well-formed literature online about this. A few resources:
- [Performance Docs](https://pointfreeco.github.io/swift-composable-architecture/main/documentation/composablearchitecture/performance/)
- [Composable Architecture @ Scale by Krzysztof Zabłocki](https://www.merowing.info/composable-architecture-scale/)
- Associated [Conference Talk](https://vimeo.com/751173570)