Impulsione seus aplicativos em Flutter ao máximo com estas 6 dicas de desempenho

Tempo de leitura: 3 minutes

Obtenha rolagem e animações mais suaves, menos consumo de memória e mais velocidade de execução com essas dicas de desempenho para aplicativos Flutter.

 

Aqui estão algumas práticas recomendadas fáceis de usar para aplicativos Flutter quando se trata de desempenho. Use-os se notar algum problema, mas não otimize prematuramente. Os aplicativos Flutter são rápidos por padrão e você normalmente não terá problemas.

Prefira StatelessWidget a StatefulWidget

Um StatelessWidget é mais rápido que um StatefulWidget porque não precisa gerenciar o estado como o nome indica. É por isso que você deve preferir, se possível.

Escolha um StatefulWidget quando…
▶ você precisa de uma função de preparação com initState()
▶ você precisa descartar recursos com dispose()
▶ você precisa acionar uma reconstrução de widget com setState()
▶ seu widget tem variáveis variáveis (não finais)

Em todas as outras situações, você deve preferir um StatelessWidget.

❌ Mau exemplo

import 'package:flutter/widgets.dart';

class MyWidget extends StatefulWidget {
    final String header;
    final String subheader;
    const MyWidget({Key? key, required this.header, required 
            this.subheader}): super(key: key);
    @override
    State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
    @override
    Widget build(BuildContext context) {
        return Column(children: [Text(widget.header),
                Text(widget.subheader)]);
    }
}

✅Bom exemplo

import 'package:flutter/widgets.dart';

class MyWidget extends StatelessWidget {
    final String header;
    final String subheader;
    const MyWidget({Key? key, required this.header, required
            this.subheader}): super(key: key);
 
    @override
    Widget build(BuildContext context) {
        return Column(children: [Text(header), Text(subheader)]);
    }
}

Use construtores construtores em listas ou grades longas

Ao lidar com listas ou grids com muitos itens, é recomendável utilizar os construtores builder. Sua vantagem é que apenas os elementos visíveis são renderizados. Portanto, se sua lista ou grade for maior que a tela de um dispositivo, você deve escolher esta abordagem. Para listas e grades menores, os construtores padrão também podem ser usados. Isso se aplica a todos os tipos de listas e grades como ListView, ReorderableListView ou GridView. Sempre verifique se há um construtor construtor e use-o, se possível.

✅Bom exemplo

final List<int> _listItems = <int>[1, 2, 3, 4, 5, 6, 7, 8, 9];

@override
Widget build(BuildContext context) {
    return ListView.builder(
        itemCount: _listItems.length,
        itemBuilder: (context, index) {
            var item = _listItems[index];
            return SizedBox(
                height: 300, child: Center(child:
                    Text(item.toString())));
        }
    );
}

 

Não use OpacityWidget

O widget Opacity pode causar problemas de desempenho quando usado com animações porque todos os widgets filhos do widget Opacity também serão reconstruídos em cada novo quadro. É melhor usar AnimatedOpacity neste caso. Se você quiser esmaecer uma imagem, use o widget FadeInImage. Se você quiser ter uma cor com opacidade, desenhe uma cor com opacidade.

❌ Mau exemplo

Opacity(opacity: 0.5, child: Container(color: Colors.red))

✅Bom exemplo

Container(color: Color.fromRGBO(255, 0, 0, 0.5))

 

Imagens e ícones pré-cache

Flutter contém uma função precacheImage() que pode ser usada para reduzir o tempo de carregamento de imagens e ícones. Você pode utilizá-lo nos métodos initState() ou didChangeDependencies() para agilizar a exibição de imagens, por exemplo.

const List<CatImage> images = [
  CatImage(width: 150, height: 150, caption: 'Watch out'),
  CatImage(width: 150, height: 160, caption: 'Hmm'),
  CatImage(width: 160, height: 150, caption: 'Whats up'),
  CatImage(width: 140, height: 150, caption: 'Miaoo'),
  CatImage(width: 130, height: 150, caption: 'Hey'),
  CatImage(width: 155, height: 150, caption: 'Hello'),
];

@override
void didChangeDependencies() {
    super.didChangeDependencies();
    for (CatImage image in images) {
        precacheImage(NetworkImage(image.url), context);
    }
}

 

Reduzir o consumo de memória do ListView

Um ListView possui duas propriedades (addRepaintBoundary e addAutomaticKeepAlives) que podem levar a um alto consumo de memória em determinados casos. Eles dizem ao ListView para não descartar itens que não estão visíveis na tela no momento. Em termos de desempenho, isso é bom porque a rolagem é rápida. Mas os itens invisíveis ainda ocupam espaço na memória. Se você tiver uma longa lista de imagens, isso pode causar problemas. A solução é definir as propriedades mencionadas como false (elas são definidas como true por padrão).

ListView.builder(
    addAutomaticKeepAlives: false,
    addRepaintBoundaries: false,
    …
);

 

Sempre use as chaves (Keys)

Cada widget tem um parâmetro de construtor chave (key) e cria um elemento na árvore de widgets. Uma chave nos permite reutilizar um elemento em vez de criar um novo. Você pode usar ValueKeys ou GlobalKeys. GlobalKeys pode ser complicado porque nunca pode haver vários widgets com a mesma chave na árvore de widgets. ValueKeys, por outro lado, levará a um código volumoso, pois você precisa defini-los para cada widget.