How we reduced our Flutter CI execution time by around 20%

Hire Remote Developers
Rafael Timbó
By
Rafael Timbó
|
Chief Technology Officer
Linkedin

Table of Contents

We show you how to reduce Flutter CI execution time by reusing artifacts of previous compilations.
Published on
July 20, 2021
Updated on
April 11, 2024

Have you ever thought about how much time is needed to run all the Continuous Integration pipelines of your mobile project, assuring your product’s quality?

Imagine that on each new PR (or PR update), a project’s unit tests verification is automatically run. We can think that the time that this pipeline takes to finish has an impact at the end of the month scaled according to the team’s size.

For instance: if a pipeline takes 5 minutes to complete, the team has 10 developers and the pipeline runs at least 2x a day per dev, we’ll have at least 100 minutes of running pipelines per day — what boils down to an average of 2200 minutes (around 36.6h) per month. 😲

How many cups of coffee would it be possible to drink in 36.6h?

Suffice to say that CI jobs’ time can be something critical. If we can save 1 minute from this job, we already benefit much, being the swiftness of the tasks’ flow or the total cost.

Ok, but… How does this apply to Flutter?

The secret here is to reuse artifacts of previous compilations. If we don’t do this, we will always waste that time compiling the same things over and over.

But we must be careful about what we’re storing on cache — we don’t want to skip verifications on modifications that might end up taking bugs to an application.

Example of a pipeline running before and after cache was implemented

Understanding the build process

There are some necessary steps before starting to run the project’s verifications:

  • Download Flutter
  • Download the project’s dependencies
  • Run Flutter build_runner

Each one of these steps can be optimized independently, in case there are no alterations. For example, you might have added a dependency to the project and modified part of the code without having Flutter version modified — that will trigger Flutter version cache and save some CI preparation time, but other compilations continue to be executed because they will generate new cache keys.

How to configure CI cache

We’ll make this using Github Actions, and the cache action to store and retrieve previous compilations.

This action has some necessary parameters for it to work:

path: This parameter means where we’re listing what will be stored on cache. Its value doesn’t limit to one single file or directory, so we might add many directories, for instance;

key: a key in which we’ll store that files’ group;

restore-keys: a list of keys used to retrieve stored cache. For the sake of this example, we will use a single value.

Flutter version cache

Here we store the current Flutter version, to avoid downloading Flutter image every time the CI runs.All we have to save is the bin directory inside the Flutter installation's directory.We will name the key according to the project’s current Flutter version’s title

[gist]137cdfcb6e50a0d401dd15c8960b35d4[/gist]

Pubspec dependencies

This cache refers to the dependencies listed on pubspec.yaml.Its key changes according to a hash from the pubspec.lock file, therefore, if there are modifications in the dependencies file, it will discard the previous cache.

[gist]a4318d3ec42c05ff84ef34fbbf1af28d[/gist]

Flutter build_runner

At last, we store a cache of the code that was generated by Flutter’s build_runner, and for being a slow process, it is very important that it’s optimized.

In this cache's key, we will add a merge of the asset_graph.json file’s hash with the aforementioned pubspec.lock’s hash.

It’s important to note that if you don’t use build_runner on your project, this step is not necessary.

[gist]7becfae07a8c82aca1ea9461e395579e[/gist]

And where all of this is located on the pipeline?

The cache definitions have to be placed right before the commands that you intend to run in order to make the necessary verifications.

[gist]73c178512bff7589b45b820bf1bd37b2[/gist]

And we’re done! This might be enough for the automatizations of your Flutter project to save up a good amount of your team’s time, for it to focus on what it really needs.

All the code included in this article was written by Cesar Castro and Douglas Iacovelli

Need to source and hire remote software developers?

Get matched with vetted candidates within 3 days.

Related blog posts

Gitlab vs Github: Choosing What's Right for Your Company

Gitlab vs Github

Celso Crivelaro
READING TIME: 
Software Development
AI Components: What They Are, Examples, and Applications

AI Components

Rafael Timbó
READING TIME: 
Software Development
Open Source Tools: What They Are and How To Use Them

Open Source Tools: What They Are and How To Use Them

Rafael Timbó
READING TIME: 
Software Development

Subscribe to the Revelo Newsletter

Get the best insights on remote work, hiring, and engineering management in your inbox.

Subscribe and be the first to hear about our new products, exclusive content, and more.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Hire Developers