Web 渲染器
Flutter Web 提供了两种 构建模式 和两种 渲染器。两种构建模式是 默认 和 WebAssembly,两种渲染器分别是 canvaskit 和 skwasm。
Flutter 会在构建应用时选择构建模式,并以此决定运行时 (runtime) 可用的渲染器。
默认 构建:Flutter 会在运行时 (runtime) 选择 canvaskit
渲染器。
WebAssembly 构建:Flutter 会在运行时 (runtime) 选择 skwasm
渲染器,如果浏览器不支持 skwasm
,则会回退到 canvaskit
。
构建模式
#默认构建模式
#在使用 flutter run
或者 flutter build web
命令时,如果不传递 --wasm
或 --no-wasm
,
Flutter 会选择默认构建。
这种构建模式只会使用 canvaskit
渲染器。
使用默认构建模式,在 Chrome 浏览器中运行:
flutter run -d chrome
使用默认构建模式来构建应用,以便进行发布:
flutter build web
WebAssembly 构建模式
#此模式通过在 flutter run
和 flutter build web
命令中传递 --wasm
标志启用。
在此模式下,skwasm
和 canvaskit
都可以使用。
skwasm
依赖 wasm 垃圾回收机制,而这一功能尚未被所有现代浏览器支持。因此,在运行时 (runtime),如果浏览器支持垃圾回收,Flutter 将选用 skwasm
,如果不支持,则会回退到 canvaskit
。这确保了在 WebAssembly 模式下编译的应用程序仍然能够在所有现代浏览器中运行。
--wasm
标志不适用于非 Web 平台。
使用 WebAssembly 模式,在 Chrome 浏览器中运行:
flutter run -d chrome --wasm
使用 WebAssembly 模式构建应用,以便进行发布:
flutter build web --wasm
渲染器
#Flutter 有两种渲染器(canvaskit
和 skwasm
),为了在浏览器中运行,它们重新实现了 Flutter 引擎。渲染器将 UI 元素(存储为 Scene
对象)转换为像素。
canvaskit
#canvaskit
渲染器兼容所有现代浏览器,它是 默认 构建模式中使用的渲染器。
它包含一份编译为 WebAssembly 的 Skia 副本,这会增加大约 1.5MB 的下载大小。
skwasm
#skwasm
渲染器是 Skia 的更精简版本,让编译为 WebAssembly,并支持在独立的线程上渲染。
该渲染器必须与 WebAssembly 构建模式一起使用,这会将 Dart 代码编译为 WebAssembly。
如果要利用多线程的优势,
Web 服务器必须满足 SharedArrayBuffer 安全要求。在此模式下,
Flutter 会使用一个专用的 web worker 将部分渲染工作转移到单独的线程上,从而利用多核 CPU 的优势。如果浏览器不符合这些要求,
skwasm
渲染器将以单线程的配置运行。
该渲染器包含一个编译为 WebAssembly 的更精简的 Skia 版本,这会增加大约 1.1MB 的下载大小。
在运行时 (runtime) 选择渲染器
#默认情况下,在 WebAssembly 模式下构建时,Flutter 会自动决定何时使用 skwasm
,以及何时回退到 canvaskit
。你可以通过传递配置对象给加载器来覆盖这一行为,具体步骤如下:
-
使用
--wasm
标志构建应用程序,以使应用能够使用skwasm
和canvaskit
渲染器。 -
按照 编写自定义
flutter_bootstrap.js
中的描述设置自定义 Web 应用初始化。 -
准备一个配置对象,将其
renderer
属性设置为"canvaskit"
或"skwasm"
。 -
将准备好的 config 对象作为新对象的
config
属性,传递给之前注入代码提供的_flutter.loader.load
方法。
示例:
<body>
<script>
{{flutter_js}}
{{flutter_build_config}}
// TODO: Replace this with your own code to determine which renderer to use.
const useCanvasKit = true;
const config = {
renderer: useCanvasKit ? "canvaskit" : "skwasm",
};
_flutter.loader.load({
config: config,
});
</script>
</body>
在调用 load
方法后,Web 渲染器就无法再次更改。因此,必须在调用 _flutter.loader.load
之前决定使用哪种渲染器。
如何选择合适的构建模式
#要将 Dart 编译为 WebAssembly,所有应用代码以及应用使用的插件和 package 都必须满足以下要求:
-
使用新的 JS 互操作库 (JS Interop) - 代码必须只使用新的 JS 互操作库
dart:js_interop
。旧的dart:js
、dart:js_util
和package:js
已不再支持。 -
使用新的 Web API - 使用 Web API 的代码必须使用新的
package:web
而不是dart:html
。 -
数值类型的兼容性 - WebAssembly 实现了 Dart 的数值类型
int
和double
,其行为与 Dart VM 完全一致。在 JavaScript 中,这些类型是使用 JS 的Number
类型进行模拟的。你的代码可能无意或故意依赖于 JS 中的数值行为。如果是这样,这部分代码需要更新,以确保与 Dart VM 的行为一致。
你可以通过以下建议来决定使用哪种模式:
-
Package 支持 - 如果你的应用依赖于尚未支持 WebAssembly 的插件和 package,那就选择默认模式。
-
高性能 - 如果你的应用代码和 package 与 WebAssembly 兼容,并且应用性能非常重要,那就选择 WebAssembly 模式。
skwasm
相较于canvaskit
在应用启动时间和帧性能方面有明显优势。skwasm
性能优势在多线程模式下尤为显著,因此请考虑配置服务器以满足 SharedArrayBuffer 安全要求。
除非另有说明,本文档之所提及适用于 Flutter 的最新稳定版本,本页面最后更新时间: 2024-12-02。 查看文档源码 或者 为本页面内容提出建议。