Flutter – Evitar Jank

El análisis de archivos JSON de gran tamaño puede provocar un rendimiento deficiente de las aplicaciones y el cierre de las animaciones. Si analizar y calcular un archivo JSON grande toma más de 16 milisegundos, los usuarios experimentarán Jank. Dart por defecto usa un solo hilo para realizar estas tareas, aunque es simple y rápido para un cálculo menos costoso, falla cuando el cálculo es grande.

Para evitar estos bloqueos, se pueden usar aislamientos para realizar todos los cálculos en un subproceso diferente en segundo plano. En este artículo, exploraremos el proceso de analizar JSON en segundo plano. Para hacerlo, siga los siguientes pasos:

  1. Importe el paquete http .
  2. Haz una solicitud de red usando el paquete http
  3. Cambie la respuesta a objetos de dardo en forma de lista
  4. Mover este trabajo a un aislamiento diferente

Importación del paquete http:

Para instalar el paquete http, use el siguiente comando en su símbolo del sistema:

pub get

o, si está usando flutter cmd, use el siguiente comando:

flutter pub get

Después de la instalación, agregue la dependencia al archivo pubsec.yml como se muestra a continuación:

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

Solicitando Datos:

Podemos usar el método http.get() para obtener los datos de muestra de 5000 imágenes de la API REST JSONPlaceholder como se muestra a continuación:

Dart

Future<http.Response> fetchPhotos(http.Client client) async {
  return client.get('https://jsonplaceholder.typicode.com/photos');
}

Análisis y conversión de datos:

Ahora tenemos 5000 fotos en formato JSON recibidas de http.response y deben analizarse y convertirse en una lista de objetos Dart. Para mostrar Primero cree una clase de fotografía como se muestra a continuación.

Aquí crearemos una clase de Foto que contenga los datos JSON como se muestra a continuación:

Dart

class Photo_list {
  final int photo_id;
  final String photo_title;
  final String photo_thumbnailUrl;
  
  Photo({this.photo_id, this.photo_title, this.photo_thumbnailUrl});
  
  factory Photo_list.fromJson(Map<String, dynamic> json) {
    return Photo_list(
      photo_id: json['id'] as int,
      photo_title: json['title'] as String,
      photo_thumbnailUrl: json['thumbnailUrl'] as String,
    );
  }
}

Ahora actualice la función getPhoto() para que devuelva un Future<List<Photo>> a través de los siguientes pasos:

  1. Cree una función Photos_parser() para convertir el cuerpo de la respuesta en una List<Photo>.
  2. Utilice la función Photos_parser() en la función getPhotos().

Dart

List<Photo>Photos_parser(String responseBody) {
  final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
  
  return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
}
  
Future<List<Photo>> getPhotos(http.Client client) async {
  final response =
      await client.get('https://jsonplaceholder.typicode.com/photos');
  
  return Photos_parser(response.body);
}

Mover el trabajo a un aislado diferente:

La función de cálculo() se puede usar para mover el trabajo a un aislamiento separado donde se analizará y convertirá en segundo plano. Ejecuta funciones costosas en un segundo plano aislado y devuelve el resultado. 

Dart

Future<List<Photo>> getPhotos(http.Client client) async {
  final response =
      await client.get('https://jsonplaceholder.typicode.com/photos');
  return compute(parsePhotos, response.body);
}

Código fuente completo:

Dart

import 'dart:async';
import 'dart:convert';
  
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
  
Future<List<Photo>> getPhotos(http.Client client) async {
  final response =
  await client.get('https://jsonplaceholder.typicode.com/photos');
  
  // run Photos_parser in a separate isolate.
  return compute(Photos_parser, response.body);
}
  
List<Photo> Photos_parser(String responseBody) {
  final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
  
  return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
}
  
class Photo_list{
  final int Photo_albumId;
  final int Photo_id;
  final String Photo_title;
  final String Photo_url;
  final String Photo_thumbnailUrl;
  
  Photo_list({this.Photo_albumId, this.Photo_id, this.Photo_title, this.Photo_url, this.Photo_thumbnailUrl});
  
  factory Photo_list.fromJson(Map<String, dynamic> json) {
    return Photo_list(
      Photo_albumId: json['albumId'] as int,
      Photo_id: json['id'] as int,
      Photo_title: json['title'] as String,
      Photo_url: json['url'] as String,
      Photo_thumbnailUrl: json['thumbnailUrl'] as String,
    );
  }
}
  
void main() => runApp(MyApp());
  
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final appTitle = 'Isolate Demo';
  
    return MaterialApp(
      title: appTitle,
      home: MyHomePage(title: appTitle),
    );
  }
}
  
class HomePage extends StatelessWidget {
  final String title;
  
  HomePage({Key key, this.title}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: FutureBuilder<List<Photo>>(
        future: fetchPhotos(http.Client()),
        builder: (context, snapshot) {
          if (snapshot.hasError) print(snapshot.error);
  
          return snapshot.hasData
              ? PhotosList(photos: snapshot.data)
              : Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}
  
class PhotosList extends StatelessWidget {
  final List<Photo> photos;
  
  PhotosList({Key key, this.photos}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
      ),
      itemCount: photos.length,
      itemBuilder: (context, index) {
        return Image.network(photos[index].Photo_thumbnailUrl);
      },
    );
  }
}

Producción:

Publicación traducida automáticamente

Artículo escrito por ddeevviissaavviittaa y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *