跳到主內容

Flutter web 應用初始化

自定義 Flutter 應用在 Web 上的初始化方式。

此頁面詳細介紹了 Flutter web 應用的初始化過程以及如何對其進行自定義。

載入程式

#

flutter build web 命令會在構建輸出目錄 (build/web) 中生成一個名為 flutter_bootstrap.js 的指令碼。此檔案包含初始化和執行 Flutter 應用所需的 JavaScript 程式碼。您可以透過在 Flutter 應用的 web 子目錄中的 index.html 檔案中放置一個 async-script 標籤來使用此指令碼

html
<html>
  <body>
    <script src="flutter_bootstrap.js" async></script>
  </body>
</html>

或者,您可以透過將模板標記 {{flutter_bootstrap_js}} 插入到 index.html 檔案中來內聯 flutter_bootstrap.js 檔案的全部內容

html
<html>
  <body>
    <script>
      {{flutter_bootstrap_js}}
    </script>
  </body>
</html>

在構建步驟期間將 index.html 檔案複製到輸出目錄 (build/web) 時,{{flutter_bootstrap_js}} 標記將被 flutter_bootstrap.js 檔案的內容替換。

自定義初始化

#

預設情況下,flutter build web 會生成一個執行 Flutter 應用簡單初始化的 flutter_bootstrap.js 檔案。但是,在某些情況下,您可能有理由自定義此初始化過程,例如

  • 為您的應用設定自定義 Flutter 配置。
  • 更改 Flutter 服務工作程式的設定。
  • 編寫在啟動過程的不同階段執行的自定義 JavaScript 程式碼。

要編寫自己的自定義引導邏輯,而不是使用構建步驟生成的預設指令碼,您可以將 flutter_bootstrap.js 檔案放在專案的 web 子目錄中,該檔案將被複制並代替構建步驟生成的預設指令碼。此檔案也經過模板處理,您可以插入幾個構建步驟在將 flutter_bootstrap.js 檔案複製到輸出目錄時會替換的特殊標記。下表列出了構建步驟將在 flutter_bootstrap.jsindex.html 檔案中替換的標記

標記替換為
{{flutter_js}} 使 _flutter.loader 物件在 _flutter.loader 全域性變數中可用的 JavaScript 程式碼。(有關更多詳細資訊,請參閱下面的 _flutter.loader.load() API 部分。)
{{flutter_build_config}} 一個 JavaScript 語句,用於設定構建過程生成的元資料,該元資料向 FlutterLoader 提供啟動應用程式所需的資訊。
{{flutter_service_worker_version}} 表示服務工作程式構建版本的唯一數字,可以將其作為服務工作程式配置的一部分傳遞(有關更多資訊,請參閱下面的“常見警告”)。
{{flutter_bootstrap_js}} 如上所述,這將直接將 flutter_bootstrap.js 檔案的內容內聯到 index.html 檔案中。請注意,此標記只能在 index.html 中使用,而不能在 flutter_bootstrap.js 檔案本身中使用。

編寫自定義引導指令碼

#

任何自定義 flutter_bootstrap.js 指令碼都需要三個元件才能成功啟動 Flutter 應用

  • 一個 {{flutter_js}} 標記,以使 _flutter.loader 可用。
  • 一個 {{flutter_build_config}} 標記,它向 FlutterLoader 提供有關構建的資訊,以便啟動您的應用。
  • _flutter.loader.load() 的呼叫,它實際上啟動了該應用。

最基本的 flutter_bootstrap.js 檔案如下所示

js
{{flutter_js}}
{{flutter_build_config}}

_flutter.loader.load();

自定義 Flutter 載入器

#

_flutter.loader.load() JavaScript API 可以使用可選引數呼叫,以自定義初始化行為

名稱描述JS 型別
config 您的應用的 Flutter 配置。 物件
onEntrypointLoaded 當引擎準備好進行初始化時呼叫的函式。它接收一個 engineInitializer 物件作為其唯一引數。 函式

config 引數是一個物件,可以包含以下可選欄位

名稱描述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)。 布林值
canvasKitMaximumSurfaces CanvasKit 渲染器可以使用的最大重疊曲面數。 雙精度浮點數
debugShowSemanticNodes 如果為 true,Flutter 會在螢幕上可見地渲染語義樹(用於除錯)。 布林值
entrypointBaseUrl Flutter 應用的入口點的基本 URL。預設為“/”。 字串
hostElement Flutter 渲染應用的 HTML 元素。如果未設定,Flutter web 將接管整個頁面。 HtmlElement
renderer 指定當前 Flutter 應用的 Web 渲染器,可以是 "canvaskit""skwasm" 字串
forceSingleThreadedSkwasm 強制 Skia WASM 渲染器以單執行緒模式執行,以實現相容性。 布林值

forceSingleThreadedSkwasm

#

一個布林標誌,用於強制 Skia WebAssembly (skwasm) 渲染器以 單執行緒模式 執行。如果

  • 您的環境不支援多執行緒 WASM(例如,SharedArrayBuffer 不可用或缺少必需的安全標頭)。
  • 您希望獲得最大的瀏覽器相容性。
  • 使用 false(預設值)允許在支援時進行多執行緒渲染,從而提高效能。

示例用法

#
js
_flutter.loader.load({
  config: {
    renderer: 'skwasm',
    forceSingleThreadedSkwasm: true,
  },
});

示例:基於 URL 查詢引數自定義 Flutter 配置

#

以下示例顯示了一個自定義 flutter_bootstrap.js,它允許使用者透過在網站的 URL 中提供 renderer 查詢引數(例如 ?renderer=skwasm)來選擇渲染器

js
{{flutter_js}}
{{flutter_build_config}}

const searchParams = new URLSearchParams(window.location.search);
const renderer = searchParams.get('renderer');
const userConfig = renderer ? {'renderer': renderer} : {};
_flutter.loader.load({
  config: userConfig,
});

此指令碼評估頁面的 URLSearchParams,以確定使用者是否傳遞了 renderer 查詢引數,然後更改 Flutter 應用的使用者配置。

onEntrypointLoaded 回撥

#

您還可以將 onEntrypointLoaded 回撥傳遞到 load API,以便在初始化過程的不同階段執行自定義邏輯。初始化過程分為以下階段

載入入口點指令碼

load 函式在初始化服務工作程式並由瀏覽器下載和執行 main.dart.js 入口點後呼叫 onEntrypointLoaded 回撥。Flutter 還在開發期間的每次熱重啟時呼叫 onEntrypointLoaded

初始化 Flutter 引擎

onEntrypointLoaded 回撥接收一個 引擎初始化器 物件作為其唯一引數。使用引擎初始化器的 initializeEngine() 函式設定執行時配置,例如 multiViewEnabled: true,並啟動 Flutter web 引擎。

執行應用

initializeEngine() 函式返回一個 Promise,該 Promise 會解析為 應用執行器 物件。應用執行器具有一個名為 runApp() 的方法,該方法執行 Flutter 應用。

將檢視新增到(或從)應用中

runApp() 方法返回一個 flutter 應用 物件。在多檢視模式下,可以使用 addViewremoveView 方法從宿主應用管理應用檢視。要了解更多資訊,請檢視 嵌入模式

示例:顯示進度指示器

#

為了向您的應用的終端使用者提供初始化過程中的反饋,請使用提供的鉤子來更新 DOM

js
{{flutter_js}}
{{flutter_build_config}}

const loading = document.createElement('div');
document.body.appendChild(loading);
loading.textContent = "Loading Entrypoint...";
_flutter.loader.load({
  onEntrypointLoaded: async function(engineInitializer) {
    loading.textContent = "Initializing engine...";
    const appRunner = await engineInitializer.initializeEngine();

    loading.textContent = "Running app...";
    await appRunner.runApp();
  }
});

常見警告

#

如果您遇到類似以下內容的警告

Warning: In index.html:37: Local variable for "serviceWorkerVersion" is deprecated.
Use "" template token instead.

您可以透過刪除 web/index.html 檔案中的以下行來修復此問題

web/index.html
html
var serviceWorkerVersion = null;