-
Notifications
You must be signed in to change notification settings - Fork 6k
Refactor flutter.js to do dart2wasm bootstrapping and CanvasKit/Skwasm preloading. #49037
Conversation
lib/web_ui/flutter_js/BUILD.gn
Outdated
"// Use of this source code is governed by a BSD-style license that can be", | ||
"// found in the LICENSE file.", | ||
"", | ||
"export const engineRevision = \"$engine_version\";", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This scares me for a couple of reasons:
- The output of web build rules depends on every byte in the engine codebase. For example, changing a
README
file will result in altering the git revision and invalidating the build. - Git revision does not fully describe the engine revision. You can have local source changes while the git revision is the same.
This probably invalidates one of the core principles of a build system, but I'm failing to name one, maybe hermeticity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is an interesting one, I get your concerns. Could we maybe have a GVC and chat about the subtleties here at some point if you have a moment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We had some discussion in a GVC. I think I mostly agree that it would be better to leave the engine revision out of flutter.js
and instead have the tool inject the engine hash as part of the build config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly nitpicks, I think only createWasmInstantiator
needs a little bit more love.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this, this is a fantastic improvement! (All my comments are minor/questions, feel free to disregard!)
"src/service_worker_loader.js", | ||
"src/skwasm_loader.js", | ||
"src/trusted_types.js", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove extra line?
baseUrl = `${baseUrl}/chromium/`; | ||
} | ||
let canvasKitUrl = `${baseUrl}canvaskit.js`; | ||
if (deps.flutterTT.policy) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QQ: how do we decide what goes in deps
vs what is passed as a parameter to the function?
For example, the browserEnvironment
looks like something that could be a dep
too, and not need its own specific positional parameter in the loadCanvasKit
function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it's mostly arbitrary. The browser environment just logically felt like something different than a "dependency" so I have it as a separate thing. Perhaps I don't even need the browserEnvironment
to be passed as a parameter anymore now that it's just a global variable vended by the browser_environment.js
module...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
now that it's just a global variable vended by the browser_environment.js module
I thought the same, but also if you grab it from deps (or the parameter) it's easy(er) to mock for testing maybe?
jsSupportRuntimePath: string; | ||
} | ||
|
||
export type ApplicationBuild = JSApplicationBuild | WasmApplicationBuild; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need this union? Wouldn't it be equivalent that interface ApplicationBuildBase
is called interface ApplicationBuild
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A union like this is super useful in TS. An interface
basically has open polymorphism, but a union has closed polymorphism. This basically means that if you're using the union (ApplicationBuild
), you can actually differentiate based on the compileTarget
field, and the compiler will actually refine the type in the the subsequent branches. This won't happen when using the interface (and in fact, the compileTarget
field doesn't exist on the interface, so you couldn't check for it). Example:
const build: ApplicationBuild = //something;
// build is an ApplicationBuild type
if (build.compileTarget === "dart2wasm") {
// build is actually a WasmApplicationBuild in this branch, so I can access fields specific to WasmApplicationBuild
console.log(build.mainWasmPath);
} else {
// the compiler can even tell that the only remaining possible values are of type JSApplicationBuild
console.log(build.mainJsPath);
}
…sKit/Skwasm preloading. (flutter/engine#49037)
…141228) flutter/engine@941f268...5b9d213 2024-01-10 [email protected] Refactor flutter.js to do dart2wasm bootstrapping and CanvasKit/Skwasm preloading. (flutter/engine#49037) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
FYI @eyebrowsoffire, this patch regressed a couple of size benchmarks: https://flutter-flutter-perf.skia.org/e/?keys=Xe5ab9093da633e5f5a62ea9d8f4fa9f6&selected=commit%3D38703%26name%3D%252Carch%253Dintel%252Cbranch%253Dmaster%252Cconfig%253Ddefault%252Cdevice_type%253Dnone%252Cdevice_version%253Dnone%252Chost_type%253Dlinux%252Csub_result%253Dhello_world_flutter_js_uncompressed_bytes%252Ctest%253Dweb_size__compile_test%252C&xbaroffset=38703 In particular, hello_world_flutter_js_uncompressed_bytes doubled. I'm not intimately familiar with these, so not sure if this is expected behavior or not. |
@bdero Definitely expected. Thanks for the heads up though! |
I'm having a problem after update my flutter version to 3.22, I modify the index.html to new mode of app initialization. My application have some textfields, and after upgrade the number keyboard doesn't work, because the six and four keys moves the cursor to right and left and not show the number on field, how can i resolve this? |
@rafaelbenedetti1 Could you file a separate issue with a minimum reproducible case? |
@eyebrowsoffire where can i create? |
This PR makes some major revisions to our flutter.js bootstrapper.
types.d.ts
file which contains declarations of the types of some of the objects used in the flutter.js APIFlutterLoader.loadEntrypoint
API and added a new function simply calledFlutterLoader.load
, which has a few more capabilities:FlutterLoader.load
can attempt to use. It will use the first one that is compatible with the browser environment and the user's configuration.FlutterLoader.load
also immediately takes a flutter configuration object. If anonEntrypointLoaded
callback is not provided by the user, it just does the expected thing and initializes the engine and immediately starts the app, passing the configuration along as needed.flutter.js
has the engine hash built into it now, which allows it to ascertain the correct CDN URLs for both CanvasKit and Skwasm.