Flutter Web 提供了两种构建模式和两种渲染器。两种构建模式是默认模式WebAssembly 模式,两种渲染器是canvaskitskwasm

Flutter 在构建应用时选择构建模式,并在运行时确定可用的渲染器。

对于默认构建,Flutter 在运行时选择 canvaskit 渲染器。对于 WebAssembly 构建,Flutter 在运行时选择 skwasm 渲染器,如果浏览器不支持 skwasm,则回退到 canvaskit

构建模式

#

默认构建模式

#

当使用不带 --wasm 参数,或者传递 --no-wasm 参数的 flutter runflutter build web 命令时,Flutter 会选择默认模式。

此构建模式仅使用 canvaskit 渲染器。

在 Chrome 中使用默认构建模式运行

flutter run -d chrome

使用默认构建模式构建您的应用以供发布

flutter build web

WebAssembly 构建模式

#

此模式通过向 flutter runflutter build web 命令传递 --wasm 来启用。

此模式使 skwasmcanvaskit 都可用。skwasm 需要 WasmGC,目前并非所有现代浏览器都支持。因此,在运行时,如果支持垃圾回收,Flutter 会选择 skwasm,如果不支持,则回退到 canvaskit。这使得在 WebAssembly 模式下编译的应用仍然可以在所有现代浏览器中运行。

--wasm 标志不支持非 Web 平台。

在 Chrome 中使用 WebAssembly 模式运行

flutter run -d chrome --wasm

使用 WebAssembly 模式构建您的应用以供发布

flutter build web --wasm

渲染器

#

Flutter 有两种渲染器(canvaskitskwasm),它们重新实现了 Flutter 引擎以在浏览器中运行。渲染器将 UI 原始对象(存储为 Scene 对象)转换为像素。

canvaskit

#

canvaskit 渲染器与所有现代浏览器兼容,并且是默认构建模式下使用的渲染器。

它包含一个编译为 WebAssembly 的 Skia 副本,下载大小增加了约 1.5MB。

skwasm

#

skwasm 渲染器是 Skia 的一个更紧凑的版本,它被编译为 WebAssembly 并支持在单独的线程上进行渲染。

此渲染器必须与WebAssembly 构建模式一起使用,该模式将 Dart 代码编译为 WebAssembly。

要利用多线程,Web 服务器必须满足 SharedArrayBuffer 安全要求。在此模式下,Flutter 使用专用的 Web Worker 将部分渲染工作负载卸载到单独的线程,从而利用多 CPU 核心。如果浏览器不满足这些要求,skwasm 渲染器将以单线程配置运行。

此渲染器包含一个更紧凑的 Skia 编译到 WebAssembly 的版本,下载大小增加了约 1.1MB。

运行时选择渲染器

#

默认情况下,在 WebAssembly 模式下构建时,Flutter 会决定何时使用 skwasm,何时回退到 canvaskit。可以通过向加载器传递配置对象来覆盖此设置,如下所示:

  1. 使用 --wasm 标志构建应用,使 skwasmcanvaskit 渲染器都可供应用使用。
  2. 按照 编写自定义 flutter_bootstrap.js 中的说明设置自定义 Web 应用初始化。
  3. 准备一个配置对象,其中 renderer 属性设置为 "canvaskit""skwasm"
  4. 将您准备好的配置对象作为新对象的 config 属性,传递给由早期注入代码提供的 _flutter.loader.load 方法。

示例

html
<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,您的应用及其插件/包必须满足以下要求:

  • 使用新的 JS 互操作 - 代码只能使用新的 JS 互操作库 dart:js_interop。旧样式 dart:jsdart:js_utilpackage:js 不再受支持。
  • 使用新的 Web API - 使用 Web API 的代码必须使用新的 package:web 而不是 dart:html
  • 数字兼容性 - WebAssembly 精确地实现了 Dart 的数字类型 intdouble,与 Dart VM 相同。在 JavaScript 中,这些类型使用 JS Number 类型进行模拟。您的代码可能意外或有意地依赖于 JS 对数字的行为。如果是这种情况,则需要更新此类代码,使其与 Dart VM 的行为保持一致。

使用这些提示来决定使用哪种模式

  • 包支持 - 如果您的应用依赖于尚不支持 WebAssembly 的插件和包,请选择默认模式。
  • 性能 - 如果您的应用代码和包与 WebAssembly 兼容且应用性能很重要,请选择 WebAssembly 模式。与 canvaskit 相比,skwasm 具有明显更快的应用启动时间和帧性能。skwasm 在多线程模式下尤其有效,因此请考虑配置服务器使其满足 SharedArrayBuffer 安全要求