Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Research: How to "Reduce unused JavaScript" in Flutter Web App? #326

Open
2 tasks
nelsonic opened this issue Mar 4, 2023 · 13 comments
Open
2 tasks

Research: How to "Reduce unused JavaScript" in Flutter Web App? #326

nelsonic opened this issue Mar 4, 2023 · 13 comments
Labels
bug Suspected or confirmed bug (defect) in the code chore a tedious but necessary task often paying technical debt discuss Share your constructive thoughts on how to make progress with this issue documentation Improvements or additions to documentation enhancement New feature or enhancement of existing functionality flutter Flutter related issues help wanted If you can help make progress with this issue, please comment! investigate learn Learn this! priority-2 Second highest priority, should be worked on as soon as the Priority-1 issues are finished research Research required; be specific T1d Time Estimate 1 Day tech-debt A feature/requirement implemented in a sub-optimal way & must be re-written technical A technical issue that requires understanding of the code, infrastructure or dependencies

Comments

@nelsonic
Copy link
Member

nelsonic commented Mar 4, 2023

With the recent deployment to GitHub Pages: #322 (comment)
the performance score is now 70: https://pagespeed.web.dev/report?url=https%3A%2F%2Fapp.dwyl.com 🎉
image

while much better than the 32 we were seeing last week and definitely something to celebrate! 🥳
it's still unacceptably low. 🐌
It must be possible to achieve 100 even if we need to resort to "smoke and mirrors". 🤔

i.e: we create a "mockup" of the App in Pure HTML and CSS and replace the basic loading screen
with a "Useful tips" page and deliberately delay downloading any JS using SetTimeout
So the page is fully interactive and PageSpeed Insights can turn a blind eye to the JS. 🙈
see: #325

Reduce unused JavaScript

The main recommendation PageSpeed Insights offers is "Reduce unused JavaScript" ...
As noted in: #315 (comment) the main.dart.js file is massive!!

https://github.com/dwyl/app/blob/af4e656aa5d84102f969b9ce3b336affda521ba2/main.dart.js
image

The flutter.js file doesn't appear to be the problem:

app/index.html

Line 26 in af4e656

<script src="flutter.js" defer></script>

It's not a very big file, only 376 loc and 13.6kb: https://github.com/dwyl/app/blob/af4e656aa5d84102f969b9ce3b336affda521ba2/flutter.js

image

Todo

  • Research how to reduce size of the JS (main.dart.js being the biggest file!)
    e.g: can we split out the engine and our application code / business logic into separate files for parallel downloading?

Starting point:

Wait for Wasm? ⏳ 🤷‍♂️

We could just focus on building features and wait patiently for Flutter to be compiled to WebAssembly
which will eliminate the JS (or at least drastically reduce it ...) 💭
This might be a while ... see: flutter/flutter#41062 and flutter/flutter#53041 (comment)

I'm not holding my breath that Flutter Web will be compiled to Wasm in 2023 ... ⏳ 🤷‍♀️
And we need to ship our Flutter Web App and get to 1k people ASAP.

Sponsor/Bounty a Flutter Expert? 💰

Given that we hypothesize that initial Web App loading time
will be one of the biggest reasons for people to "bounce" from the dwyl web app,
we could figure out how to setup a "bounty" to get a Flutter expert to help us with this.

priority-2? 🔥 🤷‍♂️

while we would love to dedicate all of our resources to fixing this immediately. 🙏
We have done a decent amount of googling and nothing obvious jumps out. 🔍 🤷‍♂️
We cannot allocate an undefined amount of time into this at the expense of building features. 👎

We're assigning priority-2 to this because: 2️⃣
a) this not a feature that people trying the App are going to say "wow" I need this App in my life! 😍
b) it's an "unknown unknown" i.e. we have no idea (up-front) how long this will take to fix. 🤷‍♂️
c) there could be a "rug pull" in the form of: 💭

  1. Dart v3 compilation to Wasm: https://medium.com/dartlang/dart-3-alpha-f1458fb9d232 🤞
  2. Flutter eventually releases a new version that dramatically improves Web compilation. 🚀

So ... this is something we need to keep chipping away at 🧑‍💻
and leaving comments on this issue with everything that we try along the way. 💬

@nelsonic nelsonic added bug Suspected or confirmed bug (defect) in the code enhancement New feature or enhancement of existing functionality help wanted If you can help make progress with this issue, please comment! discuss Share your constructive thoughts on how to make progress with this issue investigate chore a tedious but necessary task often paying technical debt priority-2 Second highest priority, should be worked on as soon as the Priority-1 issues are finished technical A technical issue that requires understanding of the code, infrastructure or dependencies T1d Time Estimate 1 Day flutter Flutter related issues documentation Improvements or additions to documentation research Research required; be specific learn Learn this! tech-debt A feature/requirement implemented in a sub-optimal way & must be re-written labels Mar 4, 2023
@nelsonic
Copy link
Member Author

nelsonic commented Mar 4, 2023

At the time of writing, there is no question on StackOverflow matching the keywords:

flutter web reduce unused javascript

https://stackoverflow.com/search?q=flutter+web+reduce+unused+javascript
image

Feels like there's an opportunity here for someone to get some SO points ... 💭

nelsonic added a commit that referenced this issue Mar 5, 2023
nelsonic added a commit that referenced this issue Mar 5, 2023
nelsonic added a commit that referenced this issue Mar 5, 2023
nelsonic added a commit that referenced this issue Mar 5, 2023
nelsonic added a commit that referenced this issue Mar 5, 2023
nelsonic added a commit that referenced this issue Mar 5, 2023
nelsonic added a commit that referenced this issue Mar 5, 2023
@nelsonic
Copy link
Member Author

nelsonic commented Mar 5, 2023

nelsonic added a commit that referenced this issue Mar 5, 2023
nelsonic added a commit that referenced this issue Mar 5, 2023
@nelsonic
Copy link
Member Author

nelsonic commented Mar 5, 2023

With Smoke and Mirrors: 🙄
image

@nelsonic
Copy link
Member Author

nelsonic commented Mar 5, 2023

@nelsonic
Copy link
Member Author

nelsonic commented Mar 6, 2023

With the addition of:

<button onclick="human();">I am not a robot</button>

We now have a rudimentary "bot detector":

image

That means Lighthouse / PageSpeed Insights will not load/execute any JavaScript.
We definitely haven't made the problem "go away".
We've just created some "interactivity" for loading the Flutter Web App.
That ... just happens to give us:

100 Performance Score 🚀

100-perf-score

Yes, this is "smoke and mirrors" because we haven't actually addressed the elephant in the room: main.dart.js ... 🙄
But by drastically reducing the Time to Interactive we let the page load 10x faster on Mobile. 📱
Which is game-changing for UX. 🎉

I still very much want to figure out if we can reduce the size of main.dart.js ... 💭
But not as worried about it now during our MVP. ☺️
We know it's a "problem" but it's one people only experience once on their mobile device. 1️⃣
Because once the Flutter App is loaded it's fast! 🐎

@nelsonic
Copy link
Member Author

nelsonic commented Mar 6, 2023

I tried to get esbuild to minify the main.dart.js with:

app/web/build.js

Lines 16 to 23 in f6a0eff

require('esbuild').build({
entryPoints: ['./build/web/flutter.js','./build/web/main.dart.js'],
bundle: true,
minify: true,
allowOverwrite: true,
treeShaking: true,
outdir: '../build/web/'
})

Which I was attempting to run in the deploy.yml script after the flutter build web ...

# Attempt to minify main.dart.js see: issues/326
- name: PWD
run: pwd
- name: ls ./build/web (BEFORE)s
run: ls -lath ./build/web
- name: chmod 777
run: chmod 777 ./build/web
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: node ./web/build.js
- name: ls ./build/web (AFTER)
run: ls -lath ./build/web

It works on localhost and minifies the files! 🎉

But the filesystem is not writeable on GitHub Actions:
https://github.com/dwyl/app/actions/runs/4340894609/jobs/7579880670#step:7:19

image

So it doesn't work on CI
We could attempt to get this working on GitHub Actions and it could very well end up optimising the JS. 🐌 --> 🏎️
But I don't know if Flutter will behave "unpredictably" if we tree-shake main.dart.js manually. 🤔

If anyone else wants to spend an hour trying to get this working it would be awesome! 🙏

@harryfei
Copy link

harryfei commented Mar 21, 2023

We are using flutter web in our own app too. We patched flutter generated output to download resources in parallel.

See it here. flutter/flutter#76009 (comment)

@nelsonic
Copy link
Member Author

@harryfei thanks very much for sharing. 🙏
@LuchoTurtle do you want to try and replicate (and document) the changes made in: enkra/enkra-send@a2ecf6b 💭

@LuchoTurtle
Copy link
Member

LuchoTurtle commented Mar 24, 2023

Hm I've created the .patch files by following https://www.cyberciti.biz/faq/appy-patch-file-using-patch-command/ and I was testing this locally and it worked.
But after re-building the project by running flutter build web --web-renderer html, I realised that the file flutter.js wasn't created within the build folder.

However, it is created when I run flutter build web (which I assume it builds with CanvasKit - which was used in flutter/flutter#76009 (comment)). Which, in turn, makes me believe that this approach might not be suitable/relevant when using the html renderer? I say this because of https://geekyants.com/blog/web-renderers-which-one-to-choose-html-or-canvaskit/, where it states that by using html, the download size is lower (I wager flutter.js is not created).

I might be wrong though, because I just noticed this behaviour when I was trying to tinker with patching the build files with the patch command.

Checking flutter/flutter#104830...

@LuchoTurtle
Copy link
Member

Yep, running flutter clean solves this hurdle...

@harryfei
Copy link

enkra-send's flutter speedup patch always preload canvaskit.js and cavaskit.wasm https://github.com/enkra/enkra-send/blob/a2ecf6b8f41e8ca35e8ceb62fb1a63fc3bf25c28/build_tools/web/flutter.js.patch#L10-L11

You can delete those lines if you build with --web-render html

@LuchoTurtle
Copy link
Member

LuchoTurtle commented Mar 24, 2023

Yeah, I figured you were using the canvaskit web renderer when I looked at those lines. I was just having some trouble understanding why I didn't have the flutter.js file when building the bundle. Turns out I had to run flutter clean instead of just deleting the build folder for it to be generated again. Since y'all patch the flutter.js file alongside flutter_service_worker.js, this is why it wasn't working.

Thank you very much ❤️ @harryfei

nelsonic added a commit to dwyl/learn-flutter that referenced this issue Mar 29, 2023
nelsonic added a commit to dwyl/learn-flutter that referenced this issue Mar 29, 2023
@nelsonic
Copy link
Member Author

@LuchoTurtle has documented the patch suggested by @harryfei in:
https://github.com/dwyl/learn-flutter/tree/main/guides/flutter-web-speed-boost 📝

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Suspected or confirmed bug (defect) in the code chore a tedious but necessary task often paying technical debt discuss Share your constructive thoughts on how to make progress with this issue documentation Improvements or additions to documentation enhancement New feature or enhancement of existing functionality flutter Flutter related issues help wanted If you can help make progress with this issue, please comment! investigate learn Learn this! priority-2 Second highest priority, should be worked on as soon as the Priority-1 issues are finished research Research required; be specific T1d Time Estimate 1 Day tech-debt A feature/requirement implemented in a sub-optimal way & must be re-written technical A technical issue that requires understanding of the code, infrastructure or dependencies
Projects
None yet
Development

No branches or pull requests

3 participants