Understanding and Improving SwiftUI Performance

New techniques we’re using at Airbnb to improve and maintain performance of SwiftUI features at scale

Cal Stephens
11 min readadvanced
--
View Original

Overview

The article discusses techniques used at Airbnb to enhance and maintain the performance of SwiftUI features at scale. It highlights the challenges faced with SwiftUI's performance, particularly in view diffing, and presents solutions such as the use of an @Equatable macro and breaking down complex views into smaller components.

What You'll Learn

1

How to optimize SwiftUI view performance by understanding view diffing

2

Why using the @Equatable macro can improve SwiftUI performance

3

When to refactor complex SwiftUI views into smaller components

Prerequisites & Requirements

  • Understanding of SwiftUI and its declarative UI patterns
  • Familiarity with Xcode and SwiftLint(optional)

Key Questions Answered

How does SwiftUI's view diffing algorithm work?
SwiftUI uses a reflection-based diffing algorithm to determine if a view's body needs to be re-evaluated. It compares stored properties of the view, using Equatable conformance for types that support it, and checks value types recursively while reference types are compared by identity. This process ensures efficient rendering by avoiding unnecessary updates.
What are the benefits of using the @Equatable macro in SwiftUI?
The @Equatable macro automatically generates Equatable conformances for SwiftUI views, ensuring that views are only re-evaluated when necessary. This reduces boilerplate code and helps prevent performance regressions, making it easier to maintain large codebases with multiple contributors.
What common pitfalls should be avoided when using SwiftUI?
Common pitfalls include using non-diffable properties like closures in views, which can lead to unnecessary re-evaluations. Additionally, failing to break down complex views into smaller, diffable components can result in performance degradation as the view grows in size and complexity.
How can view complexity be managed in SwiftUI?
Managing view complexity can be achieved by using a custom SwiftLint rule that measures the complexity of view bodies. This rule alerts developers when a view exceeds a predefined complexity threshold, encouraging them to refactor into smaller, more manageable components.

Key Statistics & Figures

Reduction in scroll hitches
15%
Achieved on the main Search screen by adopting the @Equatable macro and breaking apart large view bodies.

Technologies & Tools

Frontend
Swiftui
Used for building user interfaces in iOS applications.
Tools
Swiftlint
Used for enforcing coding standards and best practices in Swift code.

Key Actionable Insights

1
Implement the @Equatable macro in your SwiftUI views to ensure efficient rendering.
This macro simplifies the process of maintaining Equatable conformance, reducing the risk of performance issues as your codebase evolves.
2
Break down large SwiftUI views into smaller components to enhance performance.
By creating smaller, diffable views, you can minimize unnecessary re-evaluations and improve the overall responsiveness of your application.
3
Utilize SwiftLint to enforce view complexity rules in your projects.
Setting up a linting rule for view complexity can help catch potential performance issues early in the development process, ensuring maintainable and efficient code.

Common Pitfalls

1
Using closures in SwiftUI views can lead to performance issues due to non-diffable properties.
Closures typically compare as not-equal, causing unnecessary re-evaluations of the view body. To avoid this, ensure that properties used in views are diffable.
2
Failing to break down complex views into smaller components can degrade performance.
When views are large and complex, SwiftUI must re-evaluate the entire view body on state changes, leading to inefficiencies. Refactoring into smaller views can mitigate this issue.

Related Concepts

Swiftui Performance Optimization
View Diffing Techniques
Declarative UI Patterns