Flutter vs Vanilla javascript
tldr: Compare flutter with js for web dev.
You can play with:
vanilla js or
If you are on mobile and whant to see how they look go to Video section
Important: When used with flutter html renderer this app became about 2 Mb in size and just over 500 Kb compressed. Go the apps above look around.
Introduction
Flutter is framework to develop apps for android and ios. It is also a pretty good one. I have been developing apps using flutter for quite some time and it really helped me to work faster (compared to native development that I used to do) and my clients save money. For 99% of the projects that I see I recommend flutter without hesitation as most works required by people that approach could be easily and efficiently done in flutter.
But I often get questions about using flutter for web as it could simplify development even more because of web, android and ios could be developed at the same time. Every single time my answer is “If you care about your customers then don’t use flutter”. Flutter for small and medium sized projects is not ready for web. I could say that because I have long experience with web, built quite a few backends and frontends and have a specific view of how websites should function. The should be light, user friendly and don’t be polite with search engines. Flutter is not delivering this for the web.
I have created several test web apps with flutter before just to see if anything has changed and everytime saw that flutter is not ready yet. And even though I was sure in my reasoning I had little itching that I never did one to one comparison.
Recently I have been cleaning my computer from old junk and came across a tiny app I have built in few hours several years ago. It is a super niche app that helps to color code DNA sequences and manipuate its presentation to assist in finding patterns and was created to help some scientists automate boring manual work.
This app is badly written as it was intended to be written in few hours as proof of concept and later rewritten but it never was. I am saying this just to say that the code had zero optimizaion, no clear structure and just sloppy. So I dicided to write similar solution in flutter for web and compare the results. Of course it is not sientific research but better than nothing.
You might say why vanilla javascript and not some framework like react, vue or angular and that it would make a better comparision. The answer is simple - I am lazy. I didn’t want to spend much time on and since I already had one version written in raw javascript then let that be it.
By popular demand I am adding flutter “html” rendering engine because it drastically reduces file sizes.
Comparison
Setup
I am working an linux desktop machine with 32 Gb of fast memory. Javascript version was developed using vim/chrome and flutter version with android-studio/chrome. Here is my flutter version:
Here is how they look:
They are almost identical in functionality and just slightly differ in looks. For flutter I specifically used only “native” widgets and I didn’t even change any styles. There is nothing in this build that does not come with flutter when you install it. Also there are no packages for state management, everything is don with naive setState(…) calls. Before you say that this is inefficient please consider that naive javascript version goes through the same pass, so comparison is fair.
Time to develop
To be hones I didn’t measure timing for both of these because I didn’t care at the time of the development. From what I recall, javascript took several hours. I dod’t remember how much exactly but definetly more than five and less that 20. For flutter version it also took several hours but I didn’t develop it in one go. During working on flutter version I had some time with family, spent some time arguing with somebody wrong on the internet, went shopping and had dinner. So it took definetly more that 2.5 hours and less that 8 hours.
If just comparing my feeling flutter version felt like way more faster than js version. But keep in mind that when I was building flutter version I already knew how everything should work and flutter is a framework which has prebuilt components.
Development experience
Even though I do a lot of flutter development for mobile and like it, developing for web is horrible. I have good enough machine to handle different workload but with android-studio having a code and chrome rendering output it is the first time that my machine actually froze.
You might say that I need to enable swap but I turned swap off specifically to know when I rich my 32 Gb memory limit and I never did in a year since I bought this computer. For comparison I run Macintosh and Windows in qemu at the same time, run all types of android developement and quite a few other stuff. I guess if I ever decide to create flutter web apps I will need to upgrade to 64 Gb.
Javascript version was created on some 10 years old with 8 Gb of memory, vim and chrome with zero lag (at least that is how I remember it).
Output size
Here were are looking at how much output after we “compile and postprocess” both versions.
Javascript as it is raw does not need no compilation or post processing and in total weighs 48 Kb. There are only 3 files: styles.css, index.html and dna.js.
Flutter version if you go to build/web directory and measure all the files weighs 19.8 Mb. When I ran ‘find . -type f | wc -l’ in that directory it showed 27 files. All this was created by ‘flutter build web’ command. I want to clear that is not what will get downloaded inside the browser but this is what we will have to “carry around” (move to servers and etc).Here is what ncdu thinks about it:
When building with html renderer the output dir is exactly the same and contains (it looks like) all the files that were created when building with canvaskit renderer. The only file that changes is main.dart.js and it looses about 200 Kb and becomes 1.8 Mb.
Download size
For javascript version nothing changes and there were extra processing done and no compression was used. It got a bit larger on the sample site where I put it because that site has its onw javascript and background image. But let’s not remove it and still count it. So in total we get 69.1 kb. If you are curious how much it will be once compressed - it is 24 Kb.
For flutter (canvaskit) it is 7.8 Mb resources but after compression only 2.8 Mb. I include here uncompressed version because this is the size your clients browser will have to deal with - load it, parse it and display it, ocupy memory. For comparison gmail on first load downloads 1.2 Mb of resources (14.2 Mb uncompressed).
For flutter (html renderer) it is 1.9 Mb (a bit more thatn 500 Kb when compressed) when all files combined with almost all the of the weight contribution done by main.dart.js
In the bellow video you can see how they both behave on a LOCAL computer download. Both ‘release’ versions (these one is missing flutter with html renderer which is doing pretty good. Go check example app and see for yourself).
Site speed
For testing these I used https://pagespeed.web.dev/. You are encouraged to go to it and test yourself.
Vanilla
I think it is pretty expected for this to be fast due to small sizes and few files.
Flutter web (canvaskit renderer)
This one surprezed me a little as I think that 60 is too generous. In my opinion is should be around 40 but I guess due to me loading some static content before flutter starts loading it got good FCP and LCP scores and it tricked the system a bit.
Flutter web (html renderer)
UX
As for UX it is hard to say as it is could be unique for each individual but from my perspective using flutter version felt worse. It was slower, rendering of text was bad for my eyes, it felt sluggish at times and in general felt a bit off.
Memory
Javascript tab: 37_984 Kb of memory
Flutter version varied a lot depending on being idle for some time or being used few seconds ago. The lowest I have seen was about 400_000 Kb and as much as 900_000 Kb;
For html renderer I didn’t see much difference. Which leads me to a conclusion that it has to do with problems of rendering individual letters on a canvas because I didn’t have much memory problems with ‘hello world’ applicationn. So these are results for this app, don’t forget to make your own experiments.
Rendering speed.
If you played with it a bit you probably have see that vanilla version is way faster that flutter version. They both are unoptimized (I did tiny optimization to move creating some objects out of loops but not more that that). For flutter if you turn off rendering text it becomes significantly faster. It is due to creation of TextSpan, then TextPainter, then layouting and finaly painting it on canvas. Maybe there is a way to do that out of loop but this is how I knew it is done and didn’t spend any time reasearching how to do it faster. Javascript version does not have this issues as it renders text directly.
Web version is way better due to smaller size and consequent loads do it close to instant. I still have some issues with rendering individual characters (without it it runs faster).
Also html renderer rendered was a bit off with problems of centering icon and some weird artifacts on outer edges.
Conclusion
First of all I want to mention that flutter is awsome tool for android and ios development. The team did a great job and it gave a lot of pleasure to create some interesting projects with it.
But let’s be fair and accept that at the current state flutter is not suited for web apps that are small to medium sizes. I cannot say anything about big projects as the overhead discussed above might be tiny compared to benefits it would bring over othet stuff.
Raw javascript is of course unbeatable in speed and size. Flutter with canvas kits was pretty bad but used with “html” renderer was doing pretty reasonable with about 2 Mb asset size and 500kb when compressed.
I wrote the first to check my feelings and compare with some real numbers. Also this will be an easy answer to people who never tried flutter for web and ask why it is not ready yet for production.
Flutter code is horrible and I din’t put it anywhere online for beginner to copy and learn from it but if you want it and email me, then I will send you a zip file.
Video
In case you are on mobile and what to see how they look here are some videos (these include only js and flutter canvaskit and no html renderer):
Javascript:
Flutter