• Parsing large JSON files can lead to poor performance of apps and shuttering animations. If parsing and computing a large JSON file take more than 16 milliseconds, the users will experience Jank. Dart by default uses a single thread to perform these tasks, though being simple and fast for less expensive computation, it fails when the computation is large.

    o avoid these janks, isolates can be used to perform all computations in a different thread in the background. In this article, we will explore the process of parsing JSON in the background. To do so follow the below steps:

    1. Import the http package.
    2. Make a network request using the http package
    3. Change the response into dart objects in list form
    4. Move this work to a different isolate

    Add the below dependency to the pubsec.yml file

    dependencies:
      http: ^0.13.4

     

    We can use the http.get() method to fetch the sample data of 5000 images from JSONPlaceholder REST API as shown below:

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


    Parsing and Converting the Data:

    We now have 5000 photos in JSON form received from the http.response and these need to be parsed and converted into a list of Dart objects. To do show First create a Photo class as shown below.

    Here we will create a Photo class that contains the JSON data as shown below:

    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,
        );
    }
    }
     

    Now update the getPhoto() function to returns a Future<List<Photo>> through the below steps:

    1. Make a Photos_parser() function to convert the response body into a List<Photo>.
    2. Use the Photos_parser() function in the getPhotos() function.

    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);
    }
     

    Moving work to a different Isolate:

    The compute() function can be used to move the work to a separate isolate where it will be parsed and converted in the background. It runs expensive functions in a background isolate and returns the result. 

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

    Complete Source Code:

    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);
        },
        );
    }
    }
     

0 Years in
Operation
0 Loyal
Clients
0 Successful
Projects

Words from our clients

 

Tell Us About Your Project

We’ve done lot’s of work, Let’s Check some from here