DEV Community

Cover image for Lazy Loading in Flutter: Boosting Performance for Large Lists
مصعب يوسف
مصعب يوسف

Posted on Originally published at blog.stackademic.com on

Lazy Loading in Flutter: Boosting Performance for Large Lists

Lazy Loading in Flutter: Boosting Performance for Large Lists

Flutter’s ability to create beautiful and high-performing UIs is unmatched, but performance can become an issue when dealing with large data sets or lists. This is where lazy loading comes in. Lazy loading is a design pattern used to defer initialization of objects until the point at which they are needed, which helps improve performance, especially for long lists or grids. In this article, we will explore how to implement lazy loading in Flutter using ListView.builder and GridView.builder, and how to apply these techniques for infinite scrolling.

What is Lazy Loading?

Lazy loading is a technique that loads content only when it is needed. Instead of rendering every item in a list or grid at once, Flutter loads items dynamically as they come into view. This approach conserves memory and improves performance, making it especially useful for large data sets. When displaying content like social media feeds or product catalogs, lazy loading can ensure a smooth scrolling experience for the user.

ListView.builder: Efficiently Loading Lists

ListView.builder is one of Flutter’s most effective widgets for handling large lists. Unlike a standard ListView, which renders all its children at once, ListView.builder creates items only when they are about to be displayed on the screen. This reduces the app’s memory usage and keeps the UI responsive.

Example: Using ListView.builder

Here is a simple example of using ListView.builder to implement lazy loading in Flutter:

import 'package:flutter/material.dart';

class LazyLoadingListPage extends StatelessWidget {
  final List<String> items = List.generate(1000, (index) => 'Item $index');
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Lazy Loading List'),
      ),
      body: ListView.builder(
        itemCount: items.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(items[index]),
          );
        },
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

In this example, ListView.builder only creates the items as they are about to be displayed. This way, Flutter manages memory more efficiently, which is especially useful if the list contains thousands of items.

Infinite Scrolling with ListView.builder

To implement infinite scrolling, you need to dynamically add more items to the list as the user scrolls to the end. Here’s an example of how you can do it:

import 'package:flutter/material.dart';

class InfiniteScrollingListPage extends StatefulWidget {
  @override
  _InfiniteScrollingListPageState createState() => _InfiniteScrollingListPageState();
}
class _InfiniteScrollingListPageState extends State<InfiniteScrollingListPage> {
  final List<int> items = List.generate(20, (index) => index);
  final ScrollController _scrollController = ScrollController();
  @override
  void initState() {
    super.initState();
    _scrollController.addListener(() {
      if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
        _loadMoreItems();
      }
    });
  }
  void _loadMoreItems() {
    setState(() {
      items.addAll(List.generate(20, (index) => items.length + index));
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Infinite Scrolling List'),
      ),
      body: ListView.builder(
        controller: _scrollController,
        itemCount: items.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('Item ${items[index]}'),
          );
        },
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

In this example, a ScrollController is used to detect when the user reaches the end of the list, and additional items are then added. This pattern allows for an infinite scrolling effect, commonly used in apps like social media feeds.

GridView.builder: Efficiently Loading Grids

Similar to ListView.builder, Flutter’s GridView.builder is used to lazily build a scrollable grid of widgets. This approach is very useful when working with image galleries or e-commerce product grids.

Example: Using GridView.builder

Here is an example of how to use GridView.builder for lazy loading a grid of items:

import 'package:flutter/material.dart';

class LazyLoadingGridPage extends StatelessWidget {
  final List<String> items = List.generate(100, (index) => 'Item $index');
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Lazy Loading Grid'),
      ),
      body: GridView.builder(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          crossAxisSpacing: 10,
          mainAxisSpacing: 10,
        ),
        itemCount: items.length,
        itemBuilder: (context, index) {
          return Card(
            child: Center(
              child: Text(items[index]),
            ),
          );
        },
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

GridView.builder only creates grid items when they are about to come into view, which helps maintain smooth performance even with a large number of items.

Infinite Scrolling with GridView.builder

Implementing infinite scrolling with GridView.builder follows a similar approach to ListView.builder. Use a ScrollController to load more items when the user reaches the end of the grid:

import 'package:flutter/material.dart';

class InfiniteScrollingGridPage extends StatefulWidget {
  @override
  _InfiniteScrollingGridPageState createState() => _InfiniteScrollingGridPageState();
}
class _InfiniteScrollingGridPageState extends State<InfiniteScrollingGridPage> {
  final List<int> items = List.generate(20, (index) => index);
  final ScrollController _scrollController = ScrollController();
  @override
  void initState() {
    super.initState();
    _scrollController.addListener(() {
      if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
        _loadMoreItems();
      }
    });
  }
  void _loadMoreItems() {
    setState(() {
      items.addAll(List.generate(20, (index) => items.length + index));
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Infinite Scrolling Grid'),
      ),
      body: GridView.builder(
        controller: _scrollController,
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          crossAxisSpacing: 10,
          mainAxisSpacing: 10,
        ),
        itemCount: items.length,
        itemBuilder: (context, index) {
          return Card(
            child: Center(
              child: Text('Item ${items[index]}'),
            ),
          );
        },
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Best Practices for Lazy Loading in Flutter

  1. Use Pagination for Large Data Sets: Instead of loading all items at once, break your data into smaller chunks (pages) and load them as the user scrolls down.
  2. Loading Indicators: Show a loading indicator at the bottom of the list or grid when more items are being loaded to enhance user experience.
  3. Error Handling: Always handle errors that may occur during data fetching. Display appropriate messages if something goes wrong.
  4. Throttle Scroll Events: If your data fetching is resource-intensive, use a throttling mechanism to avoid frequent API calls as the user scrolls.

Conclusion

Lazy loading is crucial for enhancing performance in Flutter apps that display large lists or grids of items. By using ListView.builder and GridView.builder, you can ensure that your app only loads the content that is needed, which helps in reducing memory usage and providing a smoother user experience. Adding infinite scrolling to your lists and grids further enhances the usability of your app by allowing users to seamlessly browse through large amounts of content without overwhelming the device’s resources.

With the examples and techniques discussed here, you can efficiently implement lazy loading and infinite scrolling in your Flutter applications, ensuring a responsive and enjoyable experience for your users.

Wait for me in a good article but for professionals

Top comments (0)