Skip to content

Conversation

ditman
Copy link
Member

@ditman ditman commented Mar 16, 2022

This PR changes the initialization of a flutter web app to use the ui.webOnlyWarmupEngine API introduced here:

in order to yield full control to the programmer over the initialization of a Flutter Web app.

Currently, Flutter Web apps start as soon as possible, and take over the whole screen. With this change, the startup of an App can be split in three stages (four, if we count the cleanup stage too):

  • Injecting the main.dart.js and (optionally) the serviceworker
  • Initializing the engine
  • Running the flutter app
  • Cleaning the app (currently not implemented)

To achieve this, some JS-interop and Promise-wrangling is needed. The new workflow is as follows:

  • The user injects flutter.js in their index.html, and once that script is loaded, calls _flutter.loader.loadMainDartJs
  • flutter.js injects main.dart.js, and sets up a _flutter.loader.didLoadMainDartJs callback. (This callback must be in a hardcoded location, so Flutter loaded from a script knows where to call)
    • If the callback is not present (old index.html, not using flutter.js):

      • The engine immediately initializes the app, as it used to do earlier. This ensures backwards compatibility.
    • If the callback is present:

      • The engine calls it with an EngineInitializer object that can be used by the programmer.
        • This resolves the promise returned by loadMainDartJs in step 1.
      • From this moment on, the loading of the application is a sequence of Promise-based objects that let the user walk through the three (four) stages described above:
      loadMainDartJs -> EngineInitializer.initializeEngine -> AppRunner.runApp -> AppCleaner.cleanApp (optional)
      

Demo

The new API above allows users to write their own (informative) splash screens, for example:

  • https://dit-bootstrap-tests.web.app (red circles should turn green as the app loads. The button only becomes enabled once the app is ready to start. The app only starts when the button is pressed).

Backwards compatibility

This is currently backwards compatible with old versions of index.html. If the flutter init script calls ui.webOnlyWarmUpEngine, it checks if the flutter loader callback is setup or not.

Testing

  • Unit tests added to assert the existence and contents of the new flutter.js file.
  • Minor updates to existing unit tests that were asserting the contents of the old wrapper script (auto-generated)
  • general.shard of tests passes.

Waiting to update this branch with the latest from the engine, to detect potential failures in integration tests between the engine and the framework, even though the engine change should be fully backwards-compatible.

Manual testing

Clone this PR into your flutter/engine fork, and build it.

Clone this PR into your flutter/flutter fork, and ensure that your flutter binary is the one coming from your Github checkout.

With the new version of flutter on your box, you'll be able to create a new app normally by using flutter create. That should come with the new flutter.js and index.html templates.

In order for the flutter_tool to rebuild, you'll need to delete its cache; you can do it with:

rm [YOUR_FLUTTER_CLONE]/bin/cache/flutter_tools.*

Once the engine and the tools are rebuilt, you can just do something similar to:

flutter clean && flutter run --local-engine=host_debug_unopt -d chrome --web-port 7357

@flutter-dashboard flutter-dashboard bot added the tool Affects the "flutter" command-line tool. See also t: labels. label Mar 16, 2022
@ditman ditman requested a review from yjbanov March 29, 2022 00:50
@ditman ditman marked this pull request as ready for review March 29, 2022 22:39
@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!).

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

Copy link
Contributor

@yjbanov yjbanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@ditman
Copy link
Member Author

ditman commented Mar 30, 2022

Until the engine PR lands and rolls to flutter (and this branch is updated), these failures will happen:

Building flutter tool...
org-dartlang-app:/web_entrypoint.dart:12:12: Error: Method not found: 'webOnlyWarmupEngine'.
  await ui.webOnlyWarmupEngine(
           ^^^^^^^^^^^^^^^^^^^
Failed to compile application.

Potential other failures may happen even after the update, even though the changes should be fully backwards-compatible.

Comment on lines +138 to +139
final String contents = <String>[
'// @dart=${languageVersion.major}.${languageVersion.minor}',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Export this to a different lib/src/web/web_entrypoint.dart file, so code is shared between the flutter build and run commands.

@ditman
Copy link
Member Author

ditman commented Mar 30, 2022

Applied engine roll manually to see what breaks in this branch.

@ditman
Copy link
Member Author

ditman commented Mar 31, 2022

Removed manual roll, and rebased with proper master.

@fluttergithubbot fluttergithubbot merged commit e52b777 into flutter:master Mar 31, 2022
@ditman ditman deleted the web-js-interop-init branch March 31, 2022 06:23
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 4, 2022
@fangkyi03
Copy link

delete Platform.isAndroid

@ditman
Copy link
Member Author

ditman commented Jul 13, 2023

@fangkyi03 this has been closed for >1 year, please open a new issue explaining in detail what you need :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
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.

[web] Let developers control the bootstrap of a Flutter Web application
4 participants