What are Flutter good practices

By default, Flutter Applications are performant. However, there are some good practices that we can follow to speed up our Flutter Applications.

At the same time, we can avoid some common pitfalls. Consequently that will help us to get excellent performance.

Flutter Application’s performance depends on a few factors.

How do we design a Flutter Application? At the time of planning we need to know what can speed up our Flutter Application.

Consider the following screenshot. How should we design the following welcome page? What good practices should we follow? So it renders efficiently on the screen.

Flutter good practices
Flutter good practices

In this section, we will take a look at the key factors that influence Flutter Application’s speed.

How can I speed up my flutters?

First thing first.

We need to remember one important point when we design a Flutter Application.

The Flutter Framework generates a painting of code. Subsequently the build() method is called.

Therefore, we should avoid repetitive and costly work in the build() method.

If the ancestor Widget rebuilds it affects the whole Widget tree.

How can we avoid that?

Very simple.

We should avoid a large single Widget with a large build() method.

What we can do?

The good practices tell us to split the build() methods into different Widgets.

Let us take a look at the code that has built the above Welcome screen.

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Scaffold(
      body: ListView(
        padding: const EdgeInsets.fromLTRB(16.0, kToolbarHeight, 20.0, 20.0),
        children: [
          Align(
            child: SizedBox(
              width: 320.0,
              child: Card(
                color: theme.primaryColor,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: const [
                    DesignTitle(),
                    FacebookButtonDesign(),
                    TextDesign(
                      fontSize: 15.0,
                      text: 'or',
                    ),
                    TextDesign(
                      fontSize: 15.0,
                      text: 'Sign up with your email address',
                    ),
                    InputFieldDesign(
                      labelText: 'Email',
                      hintText: 'name@yoursite.com',
                      isHiding: false,
                    ),
                    InputFieldDesign(
                      labelText: 'Password',
                      hintText: '',
                      isHiding: true,
                    ),
                    SizedBox(
                      height: 20.0,
                    ),
                    SignUpDesign(),
                    TextDesign(
                      fontSize: 15.0,
                      text:
                          'By signing up you agree with our Terms & Conditions.',
                    ),
                    SizedBox(
                      height: 20.0,
                    ),
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

Instead of making a very large build() method, we have split them into separate Widgets.

children: const [
                    DesignTitle(),
                    FacebookButtonDesign(),
                    TextDesign(
                      fontSize: 15.0,
                      text: 'or',
                    ),
...

Let us take a look at the code of Widget FacebookButtonDesign(). It is one of the custom Widgets we have made so the build() is split up.

class FacebookButtonDesign extends StatelessWidget {
  const FacebookButtonDesign({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return SizedBox(
      width: 250.0,
      child: TextButton(
        onPressed: () {},
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            const Icon(
              MdiIcons.facebook,
              size: 20.0,
            ),
            const SizedBox(
              width: 10.0,
            ),
            Text(
              'Use Facebook Account',
              style: TextStyle(
                color: theme.primaryColorLight,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

For full code snippet please visit the respective GitHub repository.

Now each Widget like FacebookButtonDesign() can build themselves individually.

Moreover, since we have declared them constant, they will not rebuild unless the state of them changes.

If we had used the several default Flutter Widgets under the main build() method, it would slow our Flutter Application.

Therefore, always try to split the code into multiple small Widgets. As a result, there is no longer a large Widget with a heavy build() method.

How do I get better at fluttering?

Last but not least.

Always use const or constant Constructors while building the Widgets.

Even when using the default Widgets, keep them constant.

It helps the performance.

These good practices will add performance benefits to our Flutter Application.

In case, we use the “Stateful Widget”, we need to keep a few key points in our mind.

We’ll discuss them in a separate article.

So stay tuned.

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

GitHub repository

Technical blog

Twitter

Comments

2 responses to “What are Flutter good practices”

  1. […] this context, we have not discussed the Class, Object and the “Object-Oriented-Programming” […]

  2. […] One such example is TextStyle Widget. […]

Leave a Reply