Chamadas de API paralelas: aumentando o desempenho do aplicativo Flutter
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.
Conteudo
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.