Skip to content

Conversation

@ditman
Copy link
Member

@ditman ditman commented Jul 27, 2023

This PR modifies the web build slightly to create an AssetManifest.json, that is a JSON(base64)-encoded version of the AssetManifest.bin file.

(This should enable all browsers to download the file without any interference, and all servers to serve it with the correct headers.)

It also modifies Flutter's AssetManifest class so it loads and uses said file if (kIsWeb).

Issues

Tests

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@github-actions github-actions bot added tool Affects the "flutter" command-line tool. See also t: labels. framework flutter/packages/flutter repository. See also f: labels. labels Jul 27, 2023
@jonahwilliams
Copy link
Contributor

base64 decoding is pretty slow. Have you benchmarked this versus the new binary for and/or the old JSON format?

@ditman
Copy link
Member Author

ditman commented Jul 27, 2023

Have you benchmarked this versus the new binary for and/or the old JSON format?

@jonahwilliams Nope, do those benchmarks exist or do they need to be written?

@jonahwilliams
Copy link
Contributor

@jonahwilliams
Copy link
Contributor

This change will also still require us to make an additional network requst before any assets can be downloaded.

@ditman
Copy link
Member Author

ditman commented Jul 27, 2023

@jonahwilliams @yjbanov

I took the microbenchmark that Jonah suggested here (thanks!), and modified it slightly to run on the web.

I had to:

  • Add a web/index.html (I actually did flutter create --platform web .)
  • Changed the number of iterations from 1000 to 10000 (with 1k, each time I refreshed the benchmark, master would be even faster, so I assumed this was the browser warming up. I raised the number of iterations to try to give a chance to all benchmarks to be "similarly warm" without having to run them several times).

I ran the benchmark in master and the 2 PRs. I ran each example like this:

refresh-tools && flutter clean && flutter run -d web-server --target lib/foundation/decode_and_parse_asset_manifest.dart --web-port 7357 --release

(refresh-tools is a small command that I have to delete the flutter_tools cache, to ensure that changes actually work)

Here's the results after 10k iterations:

master #130419 #131382 (this)
master 130 131
57078ms 58278ms 59956ms

I only ran each microbenchmark once in my gLinux machine, so I take the numbers with a healthy amount of skepticism. Squinting a little bit, we could say that "this" is 2878ms slower than master, so I guess downloading a ~30% larger file and json-base64-decoding it incurs in an (average(, not the best for benchmarks)) ~0.3ms penalty.

It also seems that #130419 is still downloading the AssetManifest.bin on the web, which is hurting it badly in this benchmark, I expected it to wipe the floor with the other two branches (I don't know exactly if I messed up here, but it seems that the global window array is being set, so at least some of the changes are being applied. I can also take a look there and see what's up.)

@jonahwilliams
Copy link
Contributor

FYI @andrewkolos maybe you can help out with the benchmark issue here? Do we need to use a different method to load and parse the manifest?

@yjbanov
Copy link
Contributor

yjbanov commented Jul 27, 2023

Thanks for benchmarking this, @ditman! Looks like there's no material performance difference between these approaches. If so, I'd say let's go with the simplest solution.

@ditman
Copy link
Member Author

ditman commented Jul 27, 2023

@yjbanov Andrew's PR should be much, much faster in this microbenchmark (because it should NOT hit the network at all), I'm shaving that yak now to find why is it downloading the manifest (when it's set in the DOM already)

@ditman
Copy link
Member Author

ditman commented Jul 27, 2023

I pushed a fix to @andrewkolos' PR, and NOW it's chugging!

Screenshot 2023-07-27 at 3 46 13 PM

11ms for 10k iterations of parsing the manifest (now that the bytes are getting inlined, there's not much work to do for the loader, other than juggling the bytes coming from the JS global).

/cc @jonahwilliams @yjbanov.

@jonahwilliams
Copy link
Contributor

What are the numbers here? Sorry its a bit hard to follow the different issues/threads.

@andrewkolos
Copy link
Contributor

Heya, sorry for the silence--I was out at the tail end of last week.

I initially considered generating a separate version of the asset manifest for web, but I wanted to cut out the network request for the asset manifest to speed up (initial) asset loading and avoid having all pending asset loads depending on a single network request). However, if we are willing to delay addressing these properly (i.e. fixing #118115), I don't mind this adopting this solution. The other reason I avoided a solution like this one is that I wanted to avoid having to write/maintain a bunch of logic to construct/consume a JSON file, but your solution of just taking the existing bin data and encoding it as a string is pretty clever and doesn't strike me as too slow or data-consuming.

Barring strong opinions from others, I'd like to adopt this PR and close my original PR (after a few days or so).

@ditman
Copy link
Member Author

ditman commented Jul 31, 2023

Thanks @andrewkolos! I'll take a second look at the tests I broke here and get this one ready to land. I'd like to give this version a shot before we do drastic changes to the build process.

We'll eventually tackle those in #118115, so we'll be sure to include both the assets manifest alongside the fonts' one.

@ditman ditman force-pushed the asset-manifest-json-web-proposal branch from e9c4d5f to 9d0b3eb Compare July 31, 2023 21:10
@ditman
Copy link
Member Author

ditman commented Jul 31, 2023

Agh, I was forgetting to pass --platform=chrome to my flutter test commands, that's why things were working locally but still failing in CI!

@ditman
Copy link
Member Author

ditman commented Aug 1, 2023

I've checked in flutter/packages because I remember pushing a fix wrt the AssetManifest a while ago, however all tests that may use that TestAssetBundle seem to be skipped on the web (code).

For people from the future tracking a flutter/packages failure on the web to this PR, you need to apply a fix similar to this: b3f91d9

@ditman ditman marked this pull request as ready for review August 1, 2023 17:32
@ditman
Copy link
Member Author

ditman commented Aug 1, 2023

@andrewkolos offered to prepare a g3Fix for this so the "Google Testing" check passes and the PR can land. (It may be this PR that one that lands, or some other that @andrewkolos owns so he can do any changes he needs!)

@andrewkolos
Copy link
Contributor

One challenge I failed to foresee with this is the amount of change that might be required in g3. Unlike past asset manifest changes, this adds a file that is conditionally included in the build. This makes updating tests and build rules more difficult. In addition (though not as important), these kind of changes tend to break tests for customers that mock/fake AssetBundle in their tests. One of the reasons I initially liked this PR over my initial PR was it's relative simplicity. However, when considering g3 and testing, it may not be so simple.

It's possible that updating g3 to work with this PR might not be that complicated, but there are unknowns. Given that I've already invested at least 3x as much time as I wanted to on this issue, I'd like to go with the option that will probably have the fewest surprises. As a result, I may revisit my previous PR (#130419).

@ditman
Copy link
Member Author

ditman commented Aug 1, 2023

It's possible that updating g3 to work with this PR might not be that complicated, but there are unknowns.

OK, I guess I'll give that a shot too.

@andrewkolos is right, this is a world of hurt internally, what a shame :/

@andrewkolos
Copy link
Contributor

It's possible that updating g3 to work with this PR might not be that complicated, but there are unknowns.

OK, I guess I'll give that a shot too.

@andrewkolos is right, this is a world of hurt internally, what a shame :/

Do you have opinions against the core idea of #130419? As far as I can tell, @jonahwilliams and @yjbanov are satisfied with the core idea, as long as it uses a public dart API (as opposed to a hidden JS global). I really don't want to foist a bunch of g3 work on you. I'm happy to rework #130419 instead (though I can only hope g3 doesn't use custom code for generating the web entry point 🙃--I never got to find out because FroB bugged out and refused to test the PR).

@ditman ditman force-pushed the asset-manifest-json-web-proposal branch from b3f91d9 to 1109fd5 Compare August 3, 2023 01:02
@ditman
Copy link
Member Author

ditman commented Aug 3, 2023

I have a g3fix ready for this, applying.

@ditman
Copy link
Member Author

ditman commented Aug 3, 2023

I can only hope g3 doesn't use custom code for generating the web entry point 🙃

@andrewkolos sorry, I've just seen this message 😅

In fact, g3 does uses custom code to generate the web entrypoint (see cs//depot/google3/mobile/flutter/build_defs/internal/web_rules.bzl;l=195), so you'd still have to go through the g3fix process to land the other version of the change.

I prefer this PR because it keeps about the same complexity that we currently have in master, fixes the problem that some people have, and gives us some extra time to actually design what's going to be our web inlining strategy. (As Jonah said, it's not the responsibility of your PR to find that solution.)

I guess I'm trying to avoid having one-offs for each file we may want to inline, and find a consolidated solution. What if tomorrow we want to make the FontManifest.json a binary file? (I'd rather it became a .bin.json for initial web solution, than creating another different setter to the engine, etc...)

engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 20, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 21, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 21, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 21, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 21, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 21, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 21, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 21, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 21, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 21, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 21, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 22, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 22, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 22, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 22, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 22, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Sep 22, 2023
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Sep 23, 2023
Manual roll Flutter from 8936504 to f92884c (48 revisions)

Manual roll requested by [email protected]

flutter/flutter@8936504...f92884c

2023-09-21 [email protected] Rename `debugProfilePlatformChannels` to a constant that works in release mode (flutter/flutter#134922)
2023-09-20 [email protected] Mark ReastaurationManager not disposed (flutter/flutter#134832)
2023-09-20 [email protected] cover more tests with leak tracing (flutter/flutter#134834)
2023-09-20 [email protected] Fix leak in hardware_keyboard_test.dart (flutter/flutter#134380)
2023-09-20 [email protected] Fix memory leak in _SelectableTextState (flutter/flutter#135049)
2023-09-20 [email protected] Roll Flutter Engine from 39c0f2ea1f53 to 89d864552acd (4 revisions) (flutter/flutter#135169)
2023-09-20 [email protected] [deps] Update package:web dependency. (flutter/flutter#135174)
2023-09-20 [email protected] finer grained logging of Chromium launch sequence (flutter/flutter#135078)
2023-09-20 [email protected] Upgrade AGP version in tracing_tests (flutter/flutter#134671)
2023-09-20 [email protected] Cover cupertino/form_section_test with leak tracing (flutter/flutter#135158)
2023-09-20 [email protected] Cover more test/widgets tests with leak tracking #7 (flutter/flutter#134943)
2023-09-20 [email protected] Enable strict-inference (flutter/flutter#135043)
2023-09-20 [email protected] Cover more test/widgets tests with leak tracking #10 (flutter/flutter#135143)
2023-09-20 [email protected] cover more tests with leak tracing (flutter/flutter#134833)
2023-09-20 [email protected] codeisn extension safe iOS framework (flutter/flutter#134966)
2023-09-20 [email protected] Roll Flutter Engine from 6f256257b79f to 55314d08d792 (2 revisions) (flutter/flutter#135151)
2023-09-20 [email protected] Remove 'must be non-null' and 'must not be null' comments in widgets library (flutter/flutter#134992)
2023-09-20 [email protected] Roll Flutter Engine from 5f82fc2f6f24 to 6f256257b79f (1 revision) (flutter/flutter#135147)
2023-09-20 [email protected] [Android] Add Java/AGP/Gradle incompatibility warning to `flutter create` (flutter/flutter#131444)
2023-09-20 [email protected] Roll Packages from d4e2454 to 51e74b9 (12 revisions) (flutter/flutter#135145)
2023-09-20 [email protected] Remove 'must not be null' comments from various libraries. (flutter/flutter#134984)
2023-09-20 [email protected] Roll Flutter Engine from 6535421b30d3 to 5f82fc2f6f24 (2 revisions) (flutter/flutter#135142)
2023-09-20 [email protected] Roll Flutter Engine from 67d4aaef3c7b to 6535421b30d3 (1 revision) (flutter/flutter#135139)
2023-09-20 [email protected] Cover more test/widgets tests with leak tracking #8 (flutter/flutter#135045)
2023-09-20 [email protected] Cover more test/widgets tests with leak tracking #9 (flutter/flutter#135054)
2023-09-20 [email protected] Roll Flutter Engine from 83b4df415bf3 to 67d4aaef3c7b (1 revision) (flutter/flutter#135128)
2023-09-20 [email protected] Roll Flutter Engine from df4e6c079682 to 83b4df415bf3 (2 revisions) (flutter/flutter#135102)
2023-09-20 [email protected] Roll Flutter Engine from 9c6b2500282b to df4e6c079682 (1 revision) (flutter/flutter#135101)
2023-09-20 [email protected] Roll Flutter Engine from 24f7ac38dfa2 to 9c6b2500282b (3 revisions) (flutter/flutter#135098)
2023-09-20 [email protected] Roll Flutter Engine from 36379b62bec8 to 24f7ac38dfa2 (2 revisions) (flutter/flutter#135096)
2023-09-20 [email protected] Roll Flutter Engine from 81b93fc4a2cc to 36379b62bec8 (2 revisions) (flutter/flutter#135095)
2023-09-20 [email protected] Roll Flutter Engine from 5a924a9017d7 to 81b93fc4a2cc (2 revisions) (flutter/flutter#135093)
2023-09-20 [email protected] Remove 'must be non-null' and 'must not be null' comments from material. (flutter/flutter#134991)
2023-09-20 [email protected] Unpin url launcher (remake) (flutter/flutter#134958)
2023-09-20 [email protected] Roll Flutter Engine from a7af55c56aa6 to 5a924a9017d7 (10 revisions) (flutter/flutter#135085)
2023-09-20 [email protected] Manual roll Flutter Engine from a7af55c56aa6 to 0d7db40c27fd (7 revisions) (flutter/flutter#135079)
2023-09-20 [email protected] Remove 'must not be null' comments from painting and rendering libraries. (flutter/flutter#134993)
2023-09-20 [email protected] cover more tests with leak tracking (flutter/flutter#134837)
2023-09-20 [email protected] [flutter roll] Revert "Native assets support for Linux" (flutter/flutter#135069)
2023-09-20 [email protected] Manual roll Flutter Engine from 10c480310926 to a7af55c56aa6 (4 revisions) (flutter/flutter#135071)
2023-09-19 [email protected] Retry Linux web tests 1 time on roll presubmit (flutter/flutter#135073)
2023-09-19 [email protected] [web] Encode AssetManifest.bin as JSON and use that on the web. (flutter/flutter#131382)
2023-09-19 [email protected] Specify suggested format in doc comment. (flutter/flutter#134887)
2023-09-19 [email protected] Manual roll Flutter Engine from 28f14e6eec4f to 10c480310926 (6 revisions) (flutter/flutter#135066)
...
Mairramer pushed a commit to Mairramer/flutter that referenced this pull request Oct 10, 2023
…ter#131382)

This PR modifies the web build slightly to create an `AssetManifest.json`, that is a JSON(base64)-encoded version of the `AssetManifest.bin` file.

_(This should enable all browsers to download the file without any interference, and all servers to serve it with the correct headers.)_

It also modifies Flutter's `AssetManifest` class so it loads and uses said file `if (kIsWeb)`.

### Issues

* Fixes flutter#124883

### Tests

* Unit tests added.
* Some tests that run on the Web needed to be informed of the new filename, but their behavior didn't have to change (binary contents are the same across all platforms).
* I've deployed a test app, so users affected by the BIN issue may take a look at the PR in action:
  * https://dit-tests.web.app
auto-submit bot pushed a commit that referenced this pull request Oct 27, 2023
…5954)

Closes #130455.

Updates the name `WebServiceWorker` uses to reference the asset manifest file to the name of the new file generated since   #131382. This will make Flutter web apps correctly prefetch the asset manifest file.
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Nov 15, 2023
@fhuonder
Copy link
Contributor

Hi @ditman

Do you know when this fix will land on a stable release?
We currently have the problem that in some companies the firewalls block the bin-file of our flutter-web-app.

Regards,
Florian

@ditman
Copy link
Member Author

ditman commented Nov 27, 2023

@fhuonder this landed in the 3.16.0 stable release from Nov. 15th, 2023.

(You can figure out in which channel this is available by looking at the "tags" section under the commit description in master, in this case: c7c9d8e it lists 3.16.0 (but not 3.13.0, which was the previous stable))

@fhuonder
Copy link
Contributor

Thank you @ditman 🙏🏼

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App framework flutter/packages/flutter repository. See also f: labels. tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Asset images are not loading (with Internet Download Manager installed on Microsoft Windows)

6 participants