SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
24.11.2024

Aula 122: Otimização de Desempenho em SwiftUI

No desenvolvimento de aplicativos modernos, o desempenho é fundamental, especialmente ao lidar com interfaces de usuário complexas. SwiftUI oferece muitos recursos poderosos, mas também requer atenção aos detalhes para manter seu aplicativo funcionando sem problemas. Nesta aula, exploraremos diversas técnicas para otimizar o desempenho de suas aplicações SwiftUI.

1. Use @State e @Binding com Sabedoria

SwiftUI utiliza uma sintaxe declarativa e depende fortemente da gestão de estado. Usar @State e @Binding de forma excessiva pode levar a re-renderizações desnecessárias das suas views. Certifique-se de usar essas propriedades apenas quando absolutamente necessário.

struct ContentView: View {
    @State private var contador = 0

    var body: some View {
        VStack {
            Text("Contagem: \(contador)")
            Button("Incrementar") {
                contador += 1
            }
        }
    }
}

Neste exemplo, contador é uma variável de estado simples que permite que a view atualize quando houver mudanças. Garanta que apenas as views que dependem desse estado sejam re-renderizadas.

2. Use @ObservedObject e @EnvironmentObject Eficazmente

Para uma gestão de estado mais complexa, você pode usar @ObservedObject ou @EnvironmentObject. Isso permite compartilhar dados entre diferentes views sem causar re-renderizações desnecessárias.

class Contador: ObservableObject {
    @Published var contador = 0
}

struct ContentView: View {
    @ObservedObject var contador = Contador()

    var body: some View {
        VStack {
            Text("Contagem: \(contador.contador)")
            Button("Incrementar") {
                contador.contador += 1
            }
        }
    }
}

Usando @ObservedObject, apenas as views que observam esse objeto serão atualizadas quando suas propriedades mudarem.

3. Aproveite a Composição de View

SwiftUI permite criar views complexas ao compor subviews menores. Isso ajuda a isolar o estado e minimiza as re-renderizações.

struct CounterView: View {
    @Binding var contador: Int

    var body: some View {
        VStack {
            Text("Contagem: \(contador)")
            Button("Incrementar") {
                contador += 1
            }
        }
    }
}

struct ContentView: View {
    @State private var contador = 0

    var body: some View {
        CounterView(contador: $contador)
    }
}

Neste exemplo, CounterView é uma view composta que só será atualizada quando contador mudar, melhorando o desempenho.

4. Minimize o Uso de ForEach

Ao lidar com listas dinâmicas, use ForEach de forma eficiente. Se possível, evite usá-lo com grandes conjuntos de dados ou quando os dados não mudam com frequência.

struct ContentView: View {
    let itens = Array(0..<1000)

    var body: some View {
        List {
            ForEach(itens, id: \.self) { item in
                Text("Item \(item)")
            }
        }
    }
}

Considere usar List com estruturas de dados identificáveis ou comprometa-se com um gerenciamento de lista mais eficiente para minimizar problemas de desempenho.

5. Use Stacks Preguiçosos para Grandes Conjuntos de Dados

Ao exibir grandes conjuntos de dados, considere usar stacks preguiçosos. LazyVStack e LazyHStack terão um desempenho melhor porque só criam as views que estão atualmente visíveis.

struct ContentView: View {
    let itens = Array(0..<1000)

    var body: some View {
        ScrollView {
            LazyVStack {
                ForEach(itens, id: \.self) { item in
                    Text("Item \(item)")
                }
            }
        }
    }
}

Usar LazyVStack garante que as views só sejam renderizadas quando estão prestes a aparecer na tela.

6. Evite Cálculos Pesados no Corpo

Evite realizar cálculos pesados dentro do corpo das suas views. Em vez disso, compute os valores antes que o corpo seja chamado.

struct ContentView: View {
    let dados: [Int] = Array(0..<1000)

    var dadosDuplicados: [Int] {
        dados.map { $0 * 2 }
    }

    var body: some View {
        List(dadosDuplicados, id: \.self) { item in
            Text("Item Duplicado: \(item)")
        }
    }
}

Ao pré-computar dadosDuplicados, você pode evitar cálculos pesados durante a renderização da view.

7. Use EquatableView

SwiftUI introduziu EquatableView para otimizar views que não mudam com frequência. Isso pode reduzir o número de re-renderizações desnecessárias.

struct ItemView: View, Equatable {
    let título: String

    static func == (lhs: ItemView, rhs: ItemView) -> Bool {
        return lhs.título == rhs.título
    }

    var body: some View {
        Text(título)
    }
}

struct ContentView: View {
    let itens = ["Item 1", "Item 2", "Item 3"]

    var body: some View {
        ForEach(itens, id: \.self) { item in
            EquatableView(content: ItemView(título: item))
        }
    }
}

Usando EquatableView, SwiftUI pode evitar a re-renderização para views que não mudaram.

Conclusão

Ao gerenciar cuidadosamente o estado, compor views de forma eficaz e aproveitar as views preguiçosas e os recursos de desempenho do SwiftUI, você pode otimizar significativamente suas aplicações SwiftUI. A otimização de desempenho é um processo contínuo, e estar atento a como suas views reagem às mudanças de estado proporcionará uma experiência mais suave para seus usuários. Boa codificação!

Video

Did you like this article? Rate it from 1 to 5:

Thank you for voting!