#flutter
#engineering

Save Time! Optimizing Rebuilds With Flutter

5/9/2022    
Alberto Miola   Engineering

Quick Dart recap

Before diving into the details, we want to briefly review how the Dart language treats constant objects. For example, consider this extremely simple piece of code:

class Example {
  const Example();
}

void main() {
  print(Example() == Example()); // false
  print(const Example() == const Example()); // true
}
class Example {
  const Example();
}

void main() {
  const a = Example();
  const b = Example();
  
  print(identical(a, b)); // true
}
// 'child' is the old widget that needs to be removed.
// 'newWidget' is the new widget to be inserted in the tree
Element? updateChild(Element? child, Widget? newWidget, Object? newSlot) {
  if (newWidget == null) { // 1
    return null;
  }

  final Element newChild;
  if (child != null) {
    if (child.widget == newWidget) { // 2
      newChild = child;
    } else if (Widget.canUpdate(child.widget, newWidget)) { // 3
      child.update(newWidget);
      newChild = child;
    } else {
      deactivateChild(child);
      newChild = inflateWidget(newWidget, newSlot); // 4
    }
  }

  return newChild;
}
Code Sample side by side

The function allows you to write less code but in Dart you cannot use a constant constructor in front of a function! As such, cannot do this...

@override
Widget build(BuildContext context) {
  return const buildContainer(); // Compiler error!!!
}

... but can do this, which is much better:

@override
Widget build(BuildContext context) {
  return const Example();
}

Manually caching widgets

Sometimes, you may wish to create a constant widget but you cannot because it has some external dependencies that forbids the const usage. For example, look at this Container:

class Example extends StatelessWidget {
  final Color color;
  const Example({
    super.key,
    required this.color,
  });

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        const Text('Here we have the list:'),
        const SizedBox(height: 20),
        Container(
          height: 30,
          width: 30,
          decoration: BoxDecoration(
            color: Colors.blue,
            borderRadius: BorderRadius.all(Radius.circular(10)),
          ),
          child: SomeOtherWidget(
            color: color,
          ),
        ),
      ],
    );
  }
}

Both Container and its child depend on color, but it may not always change. It may not change at all but we still cannot use const. In this case, we can manually cache the widget:

class Example extends StatefulWidget {
  final Color color;
  const Example({
    super.key,
    required this.color,
  });

  @override
  State<Example> createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  late var child = _ExampleChild(widget.color);

  @override
  void didUpdateWidget(covariant Example oldWidget) {
    super.didUpdateWidget(oldWidget);

    if (widget.color != oldWidget.color) {
      child = _ExampleChild(widget.color);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        const Text('Here we have the list:'),
        const SizedBox(height: 20),
        child,
      ],
    );
  }
}

class _ExampleChild extends StatelessWidget {
  final Color color;
  const _ExampleChild(this.color);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 30,
      width: 30,
      decoration: BoxDecoration(
        color: Colors.blue,
        borderRadius: BorderRadius.all(Radius.circular(10)),
      ),
      child: SomeOtherWidget(
        color: color,
      ),
    );
  }
}

There is some more code to write but the result is the same as using a const constructor! Since the widget is now located in the state...

class _ExampleState extends State<Example> {
  late var child = _ExampleChild(widget.color);

More Articles  |  All

Why Every Digital Product Needs to be Powered by a Design System
#design
#engineering

Why Every Digital Product Needs to be Powered by a Design System

Read More
 
Book Release! Flutter Complete Reference 2.0
#flutter
#news

Book Release! Flutter Complete Reference 2.0

Read More
 

More Superformula insights, delivered.

Stay up to date on our products, services, case studies and articles.