Chamadas de API paralelas: aumentando o desempenho do aplicativo Flutter

Tempo de leitura: 4 minutes

No mundo acelerado do desenvolvimento de aplicativos móveis, o desempenho é fundamental. Os usuários exigem tempos de resposta extremamente rápidos e qualquer atraso pode causar frustração. Uma das maneiras mais eficazes de aumentar o desempenho do seu aplicativo Flutter é aproveitar o poder das chamadas de API paralelas. Neste mergulho profundo, exploraremos como chamadas de API paralelas podem turbinar seu aplicativo Flutter e fornecer aos usuários uma experiência perfeita.

 

Noções básicas sobre chamadas de API paralelas

Para compreender a importância das chamadas paralelas de API, vamos começar com o básico. As chamadas de API tradicionais no Flutter são normalmente sequenciais, o que significa que uma solicitação é feita após a outra. Embora essa abordagem funcione, ela pode resultar em desempenho mais lento do aplicativo, especialmente ao lidar com diversas fontes de dados ou grandes conjuntos de dados.

As chamadas de API paralelas, por outro lado, permitem que seu aplicativo busque dados de vários endpoints simultaneamente. É como ter várias faixas em uma rodovia, com cada faixa representando uma solicitação de API diferente. Esse processamento paralelo reduz drasticamente o tempo necessário para recuperar dados, resultando em um aplicativo mais rápido e responsivo.

 

Estratégias de Implementação

A implementação de chamadas de API paralelas em seu aplicativo Flutter requer planejamento e codificação cuidadosos. Apresentaremos estratégias passo a passo para integrar chamadas de API paralelas ao seu aplicativo, abordando tópicos como:

  • Gerenciando simultaneidade com async/await do Dart
  • Usando o método Future.wait para paralelizar solicitações
  • Tratamento de erros e degradação elegante
  • Otimizando sequências de chamadas de API para máxima eficiência

 

Cenários do mundo real

Para ilustrar o impacto das chamadas paralelas de API, vamos considerar um cenário do mundo real. Imagine que você está desenvolvendo um aplicativo de mídia social que exibe as postagens dos usuários e seus respectivos comentários. Neste aplicativo, os usuários podem rolar pelo feed e os comentários de cada postagem são obtidos de um endpoint de API separado. Sem chamadas de API paralelas, a experiência do usuário pode ser prejudicada devido aos tempos de carregamento prolongados.

 

# Chamada de API sequencial tradicional:

Future<void> fetchSequentialData() async {
  // Record the start time to measure execution time.
  final startTime = DateTime.now();

  // Executa chamadas de API sequenciais.
  final response1 = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
  final response2 = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/2'));
  final response3 = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/3'));

  // Registra o horário final e calcula o tempo decorrido.
  final endTime = DateTime.now();
  final elapsedTime = endTime.difference(startTime);

  // Imprime o tempo de execução para referência.
  print('Tempo gasto para chamadas sequenciais: ${elapsedTime.inMilliseconds} ms');

  // Atualize a UI com o tempo de execução sequencial (assumindo que setState está disponível em um contexto Flutter).
  setState(() {
    _sequentialExecutionTime = "${elapsedTime.inMilliseconds} ms";
  });

  // Processa e imprime os títulos de cada resposta.
  print('Title: ${json.decode(response1.body)['title']}');
  print('Title: ${json.decode(response2.body)['title']}');
  print('Title: ${json.decode(response3.body)['title']}');
}

 

# Chamada de API paralela:

Future<void> fetchParallelData() async {
  // Registra a hora de início para medir o tempo de execução.
  final startTime = DateTime.now();

  // Inicia chamadas de API paralelas usando Future.wait.
  final responses = await Future.wait([
    http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1')),
    http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/2')),
    http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/3')),
  ]);

  // Registra o horário final e calcula o tempo decorrido.
  final endTime = DateTime.now();
  final elapsedTime = endTime.difference(startTime);

  // Imprime o tempo de execução para referência.
  print('Tempo gasto para chamadas paralelas: ${elapsedTime.inMilliseconds} ms');

  // Atualize a UI com o tempo de execução paralelo (assumindo que setState esteja disponível em um contexto Flutter).
  setState(() {
    _parallelExecutionTime = "${elapsedTime.inMilliseconds} ms";
  });

  // Processa as respostas.
  for (final response in responses) {
    // Decodifique os dados JSON de cada resposta.
    final data = json.decode(response.body);

    // Imprime o título de cada postagem.
    print('Title: ${data['title']}');
  }
}

Demo:

 

Código completo

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class ConcorrenciaExemplo extends StatefulWidget {
  const ConcorrenciaExemplo({Key? key}) : super(key: key);

  @override
  State<ConcorrenciaExemplo> createState() => _ConcorrenciaExemploState();
}

class _ConcorrenciaExemploState extends State<ConcorrenciaExemplo> {
  String _sequentialExecutionTime = "";
  String _parallelExecutionTime = "";

  Future<void> fetchSequentialData() async {
    final startTime = DateTime.now();
    final response1 = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));
    final response2 = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/2'));
    final response3 = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/3'));

    final endTime = DateTime.now();
    final elapsedTime = endTime.difference(startTime);

    print('Tempo gasto para chamadas paralelas: ${elapsedTime.inMilliseconds} ms');

    setState(() {
      _sequentialExecutionTime = "${elapsedTime.inMilliseconds} ms";
    });

    print('Title: ${json.decode(response1.body)['title']}');
    print('Title: ${json.decode(response2.body)['title']}');
    print('Title: ${json.decode(response3.body)['title']}');
  }

  Future<void> fetchParallelData() async {
    final startTime = DateTime.now();
    final responses = await Future.wait([
      http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/1')),
      http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/2')),
      http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts/3')),
    ]);

    final endTime = DateTime.now();
    final elapsedTime = endTime.difference(startTime);
    print('Tempo gasto para chamadas sequenciais: ${elapsedTime.inMilliseconds} ms');
    setState(() {
      _parallelExecutionTime = "${elapsedTime.inMilliseconds} ms";
    });

    for (final response in responses) {
      final data = json.decode(response.body);
      print('Titulo: ${data['title']}');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Concorrência Exemplo"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text("Tempo de execução sequencial: $_sequentialExecutionTime"),
            Text("Tempo de execução paralela: $_parallelExecutionTime"),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                await fetchSequentialData();
              },
              child: const Text("Execução Sequencial"),
            ),
            ElevatedButton(
              onPressed: () async {
                await fetchParallelData();
              },
              child: const Text("Execução Paralela"),
            ),
          ],
        ),
      ),
    );
  }
}

 

Conclusão

Neste artigo, exploramos o poderoso conceito de chamadas de API paralelas no desenvolvimento de aplicativos Flutter. Vimos como a execução simultânea de várias solicitações de API pode aumentar significativamente o desempenho e a capacidade de resposta do seu aplicativo, proporcionando uma experiência de usuário mais tranquila.

Ao comparar chamadas de API paralelas e sequenciais, destacamos as vantagens da simultaneidade, tempos de carregamento reduzidos e interação aprimorada do usuário. Esteja você criando um feed de mídia social, um aplicativo de bate-papo ou qualquer aplicativo Flutter com uso intensivo de dados, compreender e implementar chamadas de API paralelas pode mudar o jogo.