自定义 Web 应用程序初始化
您可以使用 flutter.js
提供的 _flutter.loader
JavaScript API,自定义 Flutter 应用程序在 Web 上的初始化方式。此 API 可用于在 CSS 中显示加载指示器、根据条件阻止应用程序加载,或在显示应用程序之前等待用户按下按钮。
初始化过程分为以下阶段
- 加载入口点脚本
- 获取
main.dart.js
脚本并初始化服务工作者。 - 初始化 Flutter 引擎
- 通过下载必需的资源(例如资产、字体和 CanvasKit)来初始化 Flutter 的 Web 引擎。
- 运行应用程序
- 为您的 Flutter 应用程序准备 DOM 并运行它。
此页面展示了如何在初始化过程的每个阶段自定义行为。
开始
默认情况下,flutter create
命令生成的 index.html
文件包含一个脚本标记,该标记从 flutter.js
文件中调用 loadEntrypoint
<html>
<head>
<!-- ... -->
<script src="flutter.js" defer></script>
</head>
<body>
<script>
window.addEventListener('load', function (ev) {
// Download main.dart.js
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
onEntrypointLoaded: async function(engineInitializer) {
// Initialize the Flutter engine
let appRunner = await engineInitializer.initializeEngine();
// Run the app
await appRunner.runApp();
}
});
});
</script>
</body>
</html>
当 Service Worker 初始化,并且浏览器已下载并运行 main.dart.js
入口点后,loadEntrypoint
函数会调用 onEntrypointLoaded
回调。在开发过程中,Flutter 还会在每次热重启时调用 onEntrypointLoaded
。
onEntrypointLoaded
回调接收一个引擎初始化器对象作为其唯一参数。使用引擎初始化器设置运行时配置,并启动 Flutter Web 引擎。
initializeEngine()
函数返回一个 Promise
,该 Promise 使用应用运行器对象进行解析。应用运行器有一个方法 runApp()
,用于运行 Flutter 应用。
自定义 Web 应用初始化
在本部分中,了解如何自定义应用初始化的每个阶段。
加载入口点
loadEntrypoint
方法接受以下参数
名称 | 说明 | JS 类型 |
---|---|---|
entrypointUrl |
Flutter 应用入口点的 URL。默认为 "main.dart.js" 。 |
字符串 |
onEntrypointLoaded |
引擎准备就绪时调用的函数。接收一个 engineInitializer 对象作为其唯一参数。 |
函数 |
serviceWorker |
flutter_service_worker.js 加载器的配置。(如果未设置,则不会使用 Service Worker。) |
对象 |
serviceWorker
JavaScript 对象接受以下属性
名称 | 说明 | JS 类型 |
---|---|---|
serviceWorkerUrl |
Service Worker JS 文件的 URL。serviceWorkerVersion 会附加到 URL。默认为 "flutter_service_worker.js?v="
|
字符串 |
serviceWorkerVersion |
在index.html 文件中传递构建过程设置的serviceWorkerVersion 变量。 |
字符串 |
timeoutMillis |
Service Worker 加载的超时值。默认为 4000 。 |
数字 |
初始化引擎
从Flutter 3.7.0 开始,你可以使用 initializeEngine
方法通过一个简单的 JavaScript 对象配置 Flutter Web 引擎的几个运行时选项。
你可以添加以下任何可选参数
名称 | 说明 | Dart 类型 |
---|---|---|
assetBase |
应用程序的 assets 目录的基本 URL。当 Flutter 从与实际 Web 应用程序不同的域或子目录加载时添加此项。当你将 Flutter Web 嵌入到另一个应用程序中,或将其资产部署到 CDN 时,你可能需要此项。 |
字符串 |
canvasKitBaseUrl |
下载 canvaskit.wasm 的基本 URL。 |
字符串 |
canvasKitVariant |
要下载的 CanvasKit 变体。你的选项包括 1. auto :下载适用于浏览器的最佳变体。该选项默认为此值。2. full :下载在所有浏览器中都能工作的 CanvasKit 的完整变体。3. chromium :下载使用 Chromium 兼容 API 的较小变体的 CanvasKit。警告:除非你计划仅使用基于 Chromium 的浏览器,否则不要使用 chromium 选项。 |
字符串 |
canvasKitForceCpuOnly |
当 true 时,强制 CanvasKit 中仅使用 CPU 渲染(引擎不会使用 WebGL)。 |
bool |
canvasKitMaximumSurfaces |
CanvasKit 渲染器可以使用的最大叠加曲面数。 | double |
debugShowSemanticNodes |
如果 true ,Flutter 会在屏幕上明显地渲染语义树(用于调试)。 |
bool |
hostElement |
Flutter 将应用程序渲染到的 HTML 元素。未设置时,Flutter Web 将接管整个页面。 | HtmlElement |
renderer |
指定当前 Flutter 应用程序的Web 渲染器,可以是 "canvaskit" 或 "html" 。 |
字符串 |
引擎配置示例
initializeEngine
方法允许你将上面描述的任何配置参数传递给你的 Flutter 应用程序。
考虑以下示例。
你的 Flutter 应用应使用 id="flutter_app"
定位 HTML 元素,并使用 canvaskit
渲染器。生成的 JavaScript 代码类似于以下内容
onEntrypointLoaded: async function(engineInitializer) {
let appRunner = await engineInitializer.initializeEngine({
hostElement: document.querySelector("#flutter_app"),
renderer: "canvaskit"
});
appRunner.runApp();
}
有关每个参数的更详细说明,请参阅 Web 引擎 configuration.dart
文件的“运行时参数”文档部分。
跳过此步骤
你可以调用 autoStart()
来使用其默认配置初始化引擎,然后在初始化完成后立即启动应用,而不是在引擎初始化器上调用 initializeEngine()
(然后在应用程序运行器上调用 runApp()
)。
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
onEntrypointLoaded: async function(engineInitializer) {
await engineInitializer.autoStart();
}
});
示例:显示进度指示器
在初始化过程中为应用程序的用户提供反馈,请使用为每个阶段提供的挂钩来更新 DOM
<html>
<head>
<!-- ... -->
<script src="flutter.js" defer></script>
</head>
<body>
<div id="loading"></div>
<script>
window.addEventListener('load', function(ev) {
var loading = document.querySelector('#loading');
loading.textContent = "Loading entrypoint...";
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
onEntrypointLoaded: async function(engineInitializer) {
loading.textContent = "Initializing engine...";
let appRunner = await engineInitializer.initializeEngine();
loading.textContent = "Running app...";
await appRunner.runApp();
}
});
});
</script>
</body>
</html>
有关使用 CSS 动画的更实际示例,请参阅 Flutter Gallery 的初始化代码。
升级旧项目
如果你的项目是在 Flutter 2.10 或更早版本中创建的,你可以通过运行 flutter create
来使用最新的初始化模板创建一个新的 index.html
文件,如下所示。
首先,从你的 /web
目录中删除文件。
然后,从你的项目目录中运行以下命令
$ flutter create . --platforms=web