Tips to Boosting Flutter App Performance
Tips to Boosting Flutter App Performance

Hi Guy’s Welcome to Proto Coders Point. To making your flutter app smooth and better in performance you need to follow some keys points using which you can enhance the performance of your flutter apps.

1. State Management

Making use of State Management in flutter is essential for creating a smooth responsive flutter application.

Ya, Flutter provides it’s default state management ie. setState(). but it has a disadvantage that is it reload full app widget tree just to update few things.

Flutter Developer has to make use of better and optimized State Management Solution to make flutter app perform better.

I recommend to make use of Provider package which offers streamlined state management in flutter.

Example:

To-Do Note App using Flutter Provider


2. Widget Tree Optimization using const

Make use of const constructor on widget where data is not getting updated due to user action.

The const widget make sure that the widget tree & it’s sub child tree will not rebuilt, and prevent unnecessary reload of widget.

By using const keyword in flutter, The widget is instantiated only once during the first build itself.

This will reduce unnecessary load widget or reconstruction and rendering of widget.

class MyTextWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: const Text(
          'Hello, World!',
          style: TextStyle(
            fontSize: 24,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
    );
  }
}

3. Using Lazy loading & Pagination

Lazy loading & pagination in flutter improve app performance as it reducing memory usage & can speed up the rendering process.

Example:

ListView.builder widget is particularly useful for implementing lazy loading & pagination in flutter app as it has properties like how much data should be loaded i.e. The itemCount parameter using which we can specify total number of items should be shown in the listview.

Code:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ListView.builder Example',
      home: Scaffold(
        appBar: AppBar(
          title: Text('ListView.builder Example'),
        ),
        body: ListView.builder(
          itemCount: 20, // Number of items in the list
          itemBuilder: (BuildContext context, int index) {
            // itemBuilder builds each item in the list
            return ListTile(
              title: Text('Item $index'),
              subtitle: Text('Subtitle $index'),
              leading: CircleAvatar(
                child: Text('$index'),
              ),
              onTap: () {
                // Action when an item is tapped
                print('Tapped on Item $index');
              },
            );
          },
        ),
      ),
    );
  }
}

4. Image Compressing & resizing

If you have flutter app where you display images to the user’s then implementing image compression will rapidly improve performance of the app.

The flutter_image_compress library provides a convenient solution for achieving this task.

var result = await FlutterImageCompress.compressAndGetFile(
      _imageFile!.path,
      _imageFile!.path, // Destination path (overwrite the original image)
      quality: 50, // Image quality (0 - 100)
    );

Complete Code Example

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Image Compression Example',
      home: ImageCompressionScreen(),
    );
  }
}

class ImageCompressionScreen extends StatefulWidget {
  @override
  _ImageCompressionScreenState createState() => _ImageCompressionScreenState();
}

class _ImageCompressionScreenState extends State<ImageCompressionScreen> {
  File? _imageFile;
  late File _compressedImageFile;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Image Compression Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _imageFile != null
                ? Image.file(
                    _imageFile!,
                    height: 200,
                  )
                : Text('No Image Selected'),
            ElevatedButton(
              onPressed: () {
                _pickImage();
              },
              child: Text('Select Image'),
            ),
            ElevatedButton(
              onPressed: () {
                if (_imageFile != null) {
                  _compressImage();
                } else {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(
                      content: Text('Please select an image first.'),
                    ),
                  );
                }
              },
              child: Text('Compress Image'),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _pickImage() async {
    // Code to pick an image from the device's gallery
    // (You can use any method you prefer to pick an image)
    // For example:
    // var imagePicker = ImagePicker();
    // var pickedFile = await imagePicker.getImage(source: ImageSource.gallery);
    // setState(() {
    //   _imageFile = File(pickedFile.path);
    // });

    // For this example, I'm just using a placeholder file path
    setState(() {
      _imageFile = File('/path/to/your/image.jpg');
    });
  }

  Future<void> _compressImage() async {
    // Compress the image
    var result = await FlutterImageCompress.compressAndGetFile(
      _imageFile!.path,
      _imageFile!.path, // Destination path (overwrite the original image)
      quality: 50, // Image quality (0 - 100)
    );

    // Update the UI with the compressed image
    setState(() {
      _compressedImageFile = result!;
    });

    // Show a message indicating success
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('Image compressed successfully.'),
      ),
    );
  }
}

5. Using flutter devTools for performance profiling

To leverage flutter DevTools more effectively, always run your flutter app in profile mode.

How to run flutter app in profile mode, use below command:

flutter run --profile

By running your flutter app in profile mode it gives power to flutter developer that allows app developer to collect detailed app performance data during runTime, Using this data, developer can identify performance bottlenecks, understand resource usage & help developer to optimize their apps accordingly.

6. Implementing network caching in flutter

Utilizing caching header will improve performance & reduce unnecessary network traffic. let’s take an example of of using http package to handle network request like fetching data.

In the provided code snippet, the 'fetchData' function demonstrates the usage of the ‘http’ package to perform a GET request to a specified API. The request includes a ‘Cache-Control’ header with a directive of ‘max-age=3600’, indicating a caching duration of 3600 seconds (1 hour).

Future<void> _fetchData() async {
    final url = 'https://api.example.com/data';
    final response = await http.get(
      Uri.parse(url),
      headers: {'Cache-Control': 'max-age=3600'}, // Caching directive
    );

    if (response.statusCode == 200) {
      // If the server returns a successful response, parse the JSON
      final responseData = json.decode(response.body);
      setState(() {
        _data = responseData['data'];
      });
    } else {
      // If the server did not return a successful response, throw an error
      throw Exception('Failed to load data');
    }
  }
}

Conclusion

Well done on mastering crucial performance optimization techniques. Your apps are now turbocharged, boasting enhanced speed, seamless interactions, and heightened efficiency!