Speed-Up your Flutter Web App

4 tips that might help you to increase loading performance

Fintasys
6 min readOct 18, 2022
AI generated header image

Recently I was working on an App that will also released on the Web and the first feedback that I received from my friends & family was that the speed to load the website is way too slow. So I started to investigate and tried to look a bit outside of Flutter in order to optimize the loading time of my Web App. Let me share with you what I’ve figured out.

My Setup

Quick overview what I was using before I started to optimize my Project.

Flutter: 3.3.4
Web-Server: Node-JS + Express
Host: Heroku — Hobby-Plan

My initial loading time of the Web-App was about 30–40 seconds in average.
(Heroku Hobby-Plan might not be the fastest server)

Tip 1: Use Compression / Caching

The most easiest way to increase the speed is to reduce file size of the files provided by the server, especially main.dart.js can be multiple MB big.

Good: With Node-JS you can use a Middleware like Compression to easily return the static files compressed with gzip
var compression = require(‘compression’)

var compression = require('compression')
var express = require('express')
var app = express()
// compress all responses
app.use(compression())

This helped me to reduce some files like the main.dart.js by 75%.

Beside the file size I also realized that my files were not being cached and the response header showed max-age=0 , which means that those files are not suppose to be cached.

Eventually this was an issue with my Node-JS setup, but it’s possible to manipulate the header for static files in order to tell the Browser to cache those files:

app.use(express.static('www', { maxAge: 3600000 })); // 1h

Better: If you aim for a more scaleable web-app I would recommend to use instead a CDN service like CloudFront or CloudFlare. Those services offer much more features than only compression, like Caching of static files and provide those faster to your users and reduce pressure towards your web-server.
Also they are using mostly Brotli which compresses your files even better sometimes than gzip .

If you already use Amazon as host for your App then I would recommend to use CloudFront. If you hosted your app on some third party cloud service like me I would recommend to use Cloudflare, because you can use it for free in combination with domain provider like Google Domain (Check this Youtube video for more info). In order to use it with Amazon you need to create a non-free DNS entry on Amazon Route53 which you can then add to your custom records .

Cloudfare DNS-Config Example

After setting up your Cloudflare the DNS-Settings should like like this.
Important: Make sure to remove any A and AAA entries if they were pre-filled! Otherwise it can be that the service is not working correctly.

Content can be obtained from Heroku under Settings:

With this CDN-Service in front of my Web-Server I was able to reduce the loading time down to 4–6 seconds on first load without cached files. Every following request finished within 2–3 seconds.

Awesome! But I wanted to see if I can optimize further…

Tip 2: Remove unused files / Dependencies

One thing I’ve noticed when loading my web-app was that I was loading some fonts which I wasn’t actually using.

Material-Icons and Cupertino-Icons font

I actually wasn’t usingCupertino Icons anywhere in my App, I just had it because it was there from the start when I created the Flutter App and it was loaded every time even although I wasn’t using it.
Removing it from my dependencies help me to recover a little bit of bandwidth. So make sure to check all files that being loaded and make sure you actually need them.

Tip 3: Parallelize the download of your files

Current Flutter initialization flow on Web is partly like a Waterfall, after one thing is finished the next thing will be loaded. This is very inefficient and I took a look what are the most time consuming files and when in the loading flow they being requested.

As you can see canvaskit.js , canvaskit.wasm and MaterialIcons-Regular.otf are not being requested before main.dart.js has been fully downloaded.

If we want to go the extra step we can try to request those files already beforehand and after main.dart.js has been fully loaded it will get those files directly from cache and safe some time.

We can achieve this by adding the files we want to preload inside the index.html in our project’s web folder:

<link
rel="preload"
href="./assets/fonts/MaterialIcons-Regular.otf"
as="font"
/>
<link
rel="preload"
href="https://unpkg.com/canvaskit-wasm@0.35.0/bin/canvaskit.wasm"
as="fetch"
/>

As you can see, we managed to load those files in parallel at the beginning of the the site loading and after main.dart.js was finished they were ready immediately.

Optimized request with pre-fetching

This works fine with files like MaterialIcons-Regular.otf because they won’t change over time. But as you can see in the html code that we’ve added is that canvaskit.wasm is version based and with every Flutter update the chance that this version changes is high and requires manual editing of the index.html every time. There is a high risk to forget about this, so be careful using this for files like that.

Tip 4: Reduce size of images

I guess this is very general advice for any frontend app and is also valid for Flutter Web Apps. As you could see in the Screenshot above images are not always being loaded immediately and therefore it is helpful to make sure those have the resolution they need and not unnecessary bigger.

Conclusion

I hope those tips might be helpful for some people and I think Flutter is able to make some optimizations in future to improve the behavior by default (parallel loading, compression etc.).
Also I think there is space for more optimizations but at some point it is necessary to weigh how much effort is meaningful.

Optimized Loading Time

Feel free to checkout my Project Wai-Wai-App, which I used to for this article. Press “join Event” to get to the Flutter-App!

Please leave a comment if you have questions or if this article helped you. Thank you very much!

--

--