0%

【文章內容使用 Gemini 1.5 Pro 自動產生】

宣布 Flutter 3.24 和 Dart 3.5

今天,我們將揭曉 Flutter 3.24Dart 3.5,以及 I/O 2024 Connect 系列 的最後一站,該系列將在幾個小時內在中國舉行——中國是世界上最活躍的 Flutter 社群之一,這使得這個時刻變得格外特別。

Dash flies in and lands to the left of an outline of 3.24. She presses a button that fills the 3.24 in with Flutter blue.

我們在 5 月份的 Google I/O 上啟動了一系列 令人興奮的更新,包括將 WebAssembly 編譯支援升級到 stable channel,改進 Impeller,以及預覽 Dart macros 的未來。

Flutter 3.24 和 Dart 3.5 發佈版本在我們幫助您製作出色的高效能應用程式(這些應用程式可以透過單個共用程式碼庫到達行動、網頁和桌面上的使用者)的使命之上。它們包括對新的 Flutter GPU API 的早期預覽,對網頁上元素嵌入的改進,以及幾個針對那些想要為 iOS 生態系統構建的開發人員的令人興奮的更新,包括對 Swift Package Manager 的早期支援,以及對 Cupertino Widgets 的功能更新。

讓我們開始吧!

Impeller:為跨平台圖形效能樹立新標竿

從歷史上看,跨平台框架需要在視覺效果上做出妥協,因為它們依賴於底層平台提供的更高級別的抽象。Flutter 採用了不同的方法,它擁有自己的渲染層,可以在每台設備上提供硬體加速的圖形和流暢的效能。我們在 Impeller著色器 方面取得了重大進展,為圖形(如 3D)解鎖了令人興奮的新可能性。

我們很興奮地分享全新的 Flutter GPU API 的早期預覽,這是一個功能強大、低階的圖形 API,直接整合到 Flutter SDK 中。API 允許您定義自訂柵格管道,並將繪製調用直接提交到 GPU,從而可以建立專用的渲染器,例如 2D Canvas 的替代方案、3D 場景圖,甚至用於創造視覺上令人驚豔、高效能和沉浸式體驗的粒子系統,而無需使用通常引擎級別需要的容量。

3D animation of a sci-fi space helmet rendered in flutter_scene.

考慮到 API 的低階性,我們預計對於那些沒有大量圖形開發經驗的開發人員來說,會有一段學習曲線。這就是為什麼我們正在投資渲染套件,例如新的 flutter_scene 套件,它利用 Flutter GPU API 允許匯入動畫 glTF 模型並構造 3D 場景,使您能夠輕鬆地在 Flutter 和 Dart 中建立 3D 應用程式和遊戲,如下所示。

儘管 Flutter GPU API 提供了令人興奮的可能性,但它仍然處於早期預覽階段,我們可能會對 API 進行重大變更。我們建議在使用 Flutter GPU 時針對 Flutter 的主頻道進行開發。在部落格文章 Introducing Flutter GPU & Flutter Scene 中了解更多資訊。

為 iOS 和 macOS 打造 Flutter:讓為 Apple 生態系統交付美麗、快速的應用程式變得更加容易

我們的目標是讓您能夠構建出色的應用程式,這些應用程式感覺起來像原生應用程式,並能完美地執行。這項工作的一部分是優化效能,以及最大限度地提高 Flutter 與底層平台的相容性,包括存取 Apple 生態系統的全部功能。

在此版本中,我們引入了對 Swift Package Manager 的早期支援,解鎖了對蓬勃發展的 Swift 套件生態系統的存取,並使 Flutter 外掛能夠利用大量預先構建的功能來加速開發。一旦 Swift Package Manager (SPM) 被 Plugin 開發人員廣泛採用,它應該會簡化 Flutter 安裝過程本身,並降低新手的入門門檻,特別是那些不熟悉 iOS 生態系統的人。我們鼓勵 Plugin 作者 嘗試將 SPM 支援添加到您的外掛中,並提供您體驗的 回饋

接下來,我們希望讓您始終能夠滿足設計師的要求,並在 iOS 上提供高保真度的體驗。為了實現這一點,我們開始著手現代化和擴展 Cupertino Widget,解決了 Cupertino 中的 15 個問題,並在 Widget 目錄 中加入了 37 個缺少的 Cupertino Widget。

最後,我們為 Flutter macOS 應用程式添加了 platform_viewwebview 支援,允許將原生 macOS UI 組件無縫整合到您的 Flutter 應用程式中,以提供更完整、更完善的使用者體驗。

展望未來,我們很興奮能更多地投資於其他 Cupertino Widget 的保真度,與我們的生態系統一起推出 Swift Package Manager,並提供其他調查,讓整合和與 Apple 平台的互操作變得更加容易。

強調充滿活力的 Flutter 社群的全球影響力

我們還想感謝社群的貢獻,包括您的貢獻!這組版本包含來自 167 多位獨特貢獻者的近 1,500 次提交,其中包括 49 位 全新 貢獻者。我們深受 Flutter 社群持續的高水準活動、承諾和增長所鼓舞,包括積極構建框架的那些人。謝謝您!

我們共同努力的影響力正在世界各地展現出來,創造出數百萬人每天使用的令人難以置信的應用程式和體驗。例如,以下是 案例研究 的搶先看,展示了中國科技公司小米的團隊如何以及為什麼使用 Flutter 為該公司備受歡迎的新型電動汽車 小米 SU7 開發一個配套應用程式。

在世界各地出現的許多其他令人興奮的 Flutter 應用程式範例:

  • SNCF Connect,法國鐵路和歐洲最大的 Flutter 應用程式(擁有超過 150 個螢幕)的擁有者,與奧運會合作為 Flutter 應用程式交付了許多更新,使數百萬遊客能夠在奧運會期間穿梭於法國各地。
  • Wolt,DoorDash 國際的一部分,使用 Flutter 擴展到商家零售市場。
  • 惠而浦,一家擁有全球影響力的《財富》500 強公司,正在使用 Flutter 在巴西探索新的銷售管道。
  • Monta,一家丹麥的電動汽車充電生態系統初創公司,在短短 3 個月內使用 Flutter 將其第一個行動應用程式推向市場,後來又成功地將其 Web 應用程式移植到 Flutter。

總結

以上只是這些版本中 Flutter 和 Dart 的許多新功能和更新中的一小部分,您可以在 Flutter 3.24 技術部落格 文章和 Dart 3.5 部落格文章 中了解更多資訊。

展望未來,我們對 Flutter 的未來充滿期待。我們仍然致力於我們的使命,並且感謝您——無論是貢獻者、社群成員還是 Flutter 開發人員——成為這段非凡旅程的一部分。我們迫不及待想看看您接下來會建立什麼!


宣布 Flutter 3.24 和 Dart 3.5 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

解鎖 Flutter GPU、多視圖嵌入等等

Flutter 3.24 on a blue background

歡迎來到最新的 Flutter 更新!Flutter 3.24 充滿了令人興奮的新功能和增強功能,可以提升您的應用程式開發體驗。此版本重點介紹了 Flutter GPU 的預覽版本,它可以在 Flutter 中直接啟用進階圖形和 3D 場景。Web 應用程式現在可以嵌入多個 Flutter 視圖,增強應用程式的多功能性。最後,我們加入了影片廣告支援,以幫助您最大限度地提高收入。

在過去的幾個月裡,Flutter 社群一直非常活躍,擁有 852 個框架提交和 615 個引擎提交。我們很興奮地歡迎 49 位新貢獻者,他們幫助實現了此版本。您的奉獻和熱情推動著 Flutter 的前進。

因此,深入了解 Flutter 社群帶給這個最新版本的最新功能和增強功能吧!

Flutter 架構

新的 Sliver

此版本加入了新的 Sliver,可以將它們組合在一起以實現動態 app bar 行為:

您可以使用這些新的 Sliver 來製作浮動、保持固定或在使用者捲軸時調整大小的標題。這些新的 Sliver 類似於現有的 SliverPersistentHeaderSliverAppBar Sliver,但具有更簡單的 API,可以組合在一起以實現更大的效果。

這些新的 Sliver 附帶了新的範例程式碼。例如,PinnedHeaderSliver 的 API 文件有一個範例,可以重新建立 iOS 設定應用程式 app bar 的效果:

Cupertino 函式庫中的更新

在此版本中,我們改進了 CupertinoActionSheet 的保真度。在動作表單的按鈕上滑動手指現在可以提供觸覺回饋。按鈕的字體大小和粗細現在與原生對應物相符。

我們還為 CupertinoButton 加入了新的焦點屬性,現在您可以自訂已停用的 CupertinoTextField 的顏色。

Cupertino 函式庫的更新正在進行中,請期待未來版本中的更多更新!

TreeView

two_dimensional_scrollables 套件發佈了 TreeView Widget,以及幾個用於建立高效能捲軸樹的配套類別,這些樹可以在樹增長時向所有方向捲軸。套件中包含的樣本應用程式也已更新,其中包含幾個使用 TableViewTreeView Widget 的全新範例。

TreeSliver 也被加入到框架中,用於在一維捲軸中建立樹。TreeViewTreeSliver API 符合,使您能夠輕鬆地在適合您的使用案例之間切換。

CarouselView

此版本包含了 Material Design carousel Widget:CarouselView。CarouselView 呈現「Uncontained」佈局:一個可捲軸的項目列表,這些項目會捲軸到 container 的邊緣,並且當開頭和末尾項目捲出視圖和捲入視圖時,它們可以動態調整大小。

Flutter CarouselView example

Widget提供更多功能

此版本包含將核心 Widget 邏輯從 Material 函式庫移動到 Widgets 函式庫中以便更廣泛使用,這些邏輯不是設計專用的。這包括:

  • Feedback Widget,它提供輕鬆存取設備上的觸覺和音訊回饋,以點擊回應、長按等手勢。
  • ToggleableStateMixinToggleablePainter,用於建立複選框、開關
    和單選按鈕等切換 Widget 的基本類別。

為 AnimationStatus 增強列舉功能

在社群成員 nate-thegrate 的出色 貢獻 中,增強的列舉功能被加入到 AnimationStatus 中,包括 getter:

  • isDismissed
  • isCompleted
  • isRunning
  • isForwardOrCompleted

其中一些 getter 已經存在於 Animation 子類別中,例如 AnimationControllerCurvedAnimation。現在,所有這些狀態 getter 都可以在 Animation 子類別中使用,除了 AnimationStatus 之外。最後,一個 toggle 方法被加入到 AnimationController 中,用於切換動畫的方向。

SelectionArea 中的更新

Flutter 的 SelectionArea 現在支援使用滑鼠進行三擊和在觸控設備上雙擊的更多原生手勢。預設情況下,SelectionAreaSelectableRegion Widget 使用這些新的手勢。

三擊

  • 三擊 + 拖動:擴展段落塊中的選取範圍。
  • 三擊:選取點擊位置的段落塊。

雙擊

  • 雙擊 + 拖動:擴展文字區塊中的選取範圍(支援原生 Android/Fuchsia/iOS 和 iOS 網頁)。
  • 雙擊:選取點擊位置的文字(支援原生 Android/Fuchsia/iOS 和 Android/Fuchsia 網頁)。

引擎

Impeller

改善效能和保真度

為了在即將到來的穩定版本中移除 iOS 上的 Impeller 選擇不使用設定,團隊一直在努力改進 Impeller 的效能和保真度。例如,針對文字渲染的一系列改進 大幅提高了 emoji 捲軸的效能,消除了捲軸大量 emoji 時的卡頓,這對 Impeller 的文字渲染能力來說是一項極好的壓力測試。

此外,透過 解決許多問題,我們也在此版本中大幅改進了 Impeller 文字渲染的保真度。特別是,文字粗細、間距和字距調整現在都與傳統渲染器的文字保真度相符。

Before (Note gaps instead of proper kerning, and lighter than intended font weight.)
After
Before (Note incorrect spacing, for example in “vergelijken”)
After

Android 預覽

在此版本中,我們將繼續在 Android 上預覽 Impeller。我們延長了預覽期,因為 Impeller 用於 Platform Views 的 API 在 Android 14 中的一個錯誤 導致出現困難。這個錯誤後來被 Android 團隊修補了,但是許多已部署的設備在可預見的將來將運行未修補的 Android 版本。解決這些問題意味著需要額外的 API 遷移,因此需要額外的穩定版本週期。出於謹慎和為了確保 Flutter 應用程式可以在盡可能廣泛的設備上運行,我們將推遲將 Impeller 作為預設渲染器,直到今年晚些時候的穩定版本發佈。

隨著 Android 上的 Impeller 預覽繼續在 3.24 穩定版本週期中進行,我們請求 Flutter 開發人員升級到最新的穩定版本,並在啟用 Impeller 時提交有關任何發現的不足的錯誤。在此階段的回饋對確保 Impeller 在 Android 上取得成功以及我們能夠在今年晚些時候的版本中自信地將其設為預設渲染器至關重要。Android 硬體生態系統比 iOS 生態系統更加多元。因此,關於 Impeller 最有用的回饋應包括有關發生問題的特定設備和 Android 版本的詳細資訊。

改進縮放圖片的預設值

在此版本中,圖片的預設 FilterQuality 已從 FilterQuality.low 變更為 FilterQuality.medium。當一個大型圖片比其目標矩形大很多時(這是一個常見的情況),FilterQuality.low 會導致圖片看起來更加「像素化」,並且渲染速度比 FilterQuality.medium 慢。未來,團隊還將探索更適合各種 FilterQuality 級別的新名稱。

Flutter GPU 預覽

Flutter 推出了對渲染功能的重大更新,即 Flutter GPU,可在主頻道上使用。此低階圖形 API 允許開發人員使用 Dart 程式碼和 GLSL 著色器建立自訂渲染器,而無需任何原生平台程式碼。

Flutter GPU 擴展了您可以在 Flutter 中直接渲染的內容,啟用進階圖形和 3D 場景。它需要 Impeller 渲染後端,目前在 iOS、macOS 和 Android 上支援。儘管處於早期預覽階段,但 Flutter GPU 的目標是最終支援所有 Flutter 平台。

API 允許完全控制渲染傳遞附件、頂點階段和資料上傳到 GPU。這種靈活性對於建立複雜的渲染解決方案至關重要,從 2D 角色動畫到複雜的 3D 場景。

開發人員可以透過切換到 main channel 並將 flutter_gpu 套件加入到他們的專案中來開始使用 Flutter GPU。接下來的幾個月將看到更多功能和穩定性方面的改進,更高階的渲染函式庫(如 flutter_scene)將簡化這些進階功能的使用。

若要深入了解 Flutter GPU,並了解如何在您的專案中利用它,請查看詳細的 Flutter GPU 部落格文章。無論您是建立遊戲還是複雜的圖形,Flutter 的全新 GPU 功能都讓它成為產品的強大選擇。

網頁

多視圖嵌入

Flutter Web 應用程式現在可以利用多視圖嵌入,讓開發人員可以將內容同時渲染到多個 HTML 元素中。此功能稱為「嵌入模式」或「多視圖」,為將 Flutter 視圖整合到現有的 Web 應用程式中提供了靈活性。

在多視圖模式下,Flutter Web 應用程式不會在啟動時立即渲染。相反,它會等到主機應用程式使用 addView 方法加入第一個「視圖」。主機應用程式可以動態加入或移除這些視圖,Flutter 會根據需要調整其 Widget。

若要啟用多視圖模式,請在 flutter_bootstrap.js 檔案中的 initializeEngine 方法中設定 multiViewEnabled: true。然後,可以從 JavaScript 管理視圖,將它們加入到指定的 HTML 元素中,並根據需要移除它們。每次加入和移除視圖都會觸發 Flutter 中的更新,允許動態內容渲染。

此功能對於將 Flutter 整合到需要多個獨立 Flutter 視圖的複雜 Web 應用程式中特別有用。它還支援每個視圖的自訂初始化資料,啟用個人化的設定和互動式體驗。

若要深入了解如何在 Flutter 網頁應用程式中實作多視圖嵌入,請查看 詳細的文件

變現

影片廣告變現支援

我們推出了一個新的 互動式媒體廣告 (IMA) Plugin,以支援 Flutter 行動應用程式中的串流影片廣告變現。新的 IMA Plugin 為 Flutter 應用程式提供了新的廣告變現機會,這些機會建立在現有的 Google 行動廣告 (GMA) Plugin 之上,該 Plugin 主要支援展示廣告格式。

串流影片廣告通常在影片內容播放之前(開頭廣告)、期間(中間廣告)或之後(結尾廣告)顯示給使用者。一些串流影片廣告也可以跳過。

Flutter IMA 的優點:

  • 在 Flutter 應用程式中無縫變現影片播放器內容。例如,當應用程式使用者點擊影片內容上的播放時,您現在可以實作 Flutter IMA Plugin 以首先向使用者顯示一個 15 秒的廣告,然後再開始播放影片內容。
  • 利用原生 IMA SDK 的相同優點,包括存取 Google 優質廣告需求和行業標準合規性(例如 IAB VAST)。

初始發佈版本目前支援 Android 和 iOS 平台上的開頭影片廣告。中間廣告支援將很快提供。我們鼓勵您開始在 Flutter 應用程式影片內容中探索新的 IMA Plugin。如果您在 GitHub 上遇到任何問題或疑慮,請告知我們。

資源:Plugin 指南範例應用程式Git 儲存庫

iOS

Swift Package Manager 初始支援

今天,Flutter 使用 CocoaPods 來管理原生 iOS 或 macOS 相依。

Flutter 3.24 加入了對 Swift Package Manager 的早期支援。這帶來了許多優點,包括:

  1. 存取 Swift 套件生態系統。Flutter Plugin 將能夠利用不斷發展的 Swift 套件 生態系統!
  2. 簡化 Flutter 安裝。Swift Package Manager 與 Xcode 捆綁在一起。未來,您將不再需要安裝 Ruby 和 CocoaPods 來為 Apple 平台使用 Flutter。

我們鼓勵 Plugin 作者 嘗試將 Swift Package Manager 支援加入到您的 Plugin 中,並提供您體驗的回饋。

如果您對 Flutter 對 Swift Package Manager 的支援有任何回饋,請 提交議題

生態系統

Shared Preferences 設定 Plugin 更新

我們已在 shared_preferences Plugin 中加入了兩個新的 API,SharedPreferencesAsync 和 SharedPreferencesWithCache。最重大的變化是 Android 實作使用 Preferences DataStore 而不是 Shared Preferences。

SharedPreferencesAsync 允許使用者直接調用平台以獲取設備上儲存的最新偏好設定,代價是異步和比使用快取版本稍微慢一些。這對於可以由其他系統或隔離區更新的偏好設定很有用,這些偏好設定會使快取過時。

SharedPreferencesWithCache 建立在 SharedPreferencesAsync 之上,允許使用者同步存取偏好設定的本地快取副本。這與舊的 API 相似,但現在可以透過不同的參數多次實例化。

這些新的 API 旨在將來替換目前的 SharedPreferences API。但是,這是生態系統中最常用的 Plugin 之一,我們知道生態系統需要時間才能轉換到新的 API。

Flutter 和 Dart 套件生態系統峰會歐洲 2024

作為 Fluttercon Europe 2024 的一部分,我們舉辦了首屆面對面 Flutter 和 Dart 套件生態系統峰會。這是繼我們於 2023 年 8 月舉辦的第一屆虛擬峰會之後。在此查看討論會的重點摘要。

我們很高興地宣布,下一屆峰會將於 2024 年 9 月 20 日在紐約市舉行的 Fluttercon USA 舉行!如果您是套件作者或貢獻者,並且將參加 Fluttercon USA 2024,請 註冊 以保留您的峰會席位。

峰會匯集了套件作者和維護者,進行了以下主題的 unconference-style 議程:

  • 議程 1 - 原生互操作的過去、現在和未來
  • 議程 2 - 可持續的套件維護模型
  • 議程 3 - 解決套件生態系統碎片化問題

我們相信峰會,特別是在更通用的 Flutter 和 Dart 活動的一部分時,是社群之間公開討論的有價值的平台,用於找出關鍵挑戰和集思廣益解決方案。我們期待與社群合作,在未來舉辦更多此類峰會。

DevTools 和 IDE

此版本包含一些對 Flutter DevTools 工具套件的令人興奮的改進。

如果您曾經想知道您的 Flutter 應用程式是否建立了比預期更多的 Widget,那麼 DevTools 效能 工具中的一個新功能可以幫助您。使用新的 重新建立統計資料 功能,您可以捕獲有關應用程式中或甚至特定 Flutter 畫面中 Widget 建立次數的資訊。

DevTools 效能工具的螢幕截圖,追蹤重新建立統計資料。

我們已為 網路分析工具Flutter Deep Links 工具 等工具加入了潤色和關鍵錯誤修復,並且進行了一些一般性改進,以在您從 IDE 中使用 DevTools 時為您提供更好的體驗。說到 IDE,您知道您可以在 IDE 中直接使用每個 DevTools 工具嗎?

DevTools 螢幕在 VS Code 視窗中打開。

DevTools 螢幕在 Android Studio 工具視窗中打開。

此版本包含對 VS Code 中的 Flutter 側邊欄的改進,讓您更容易存取您正在尋找的工具。升級到最新版本的 VS Code 和 Flutter 和 Dart 擴展,以存取改進的側邊欄。

Flutter 側邊欄是自適應的,可以調整大小以適合您的工作區

此版本還包含對 DevTools Extensions 框架的一些重大改進。您現在可以在除錯 Dart 或 Flutter 測試時使用 DevTools 擴展(由您的套件相依之一提供的工具),或者甚至在您沒有除錯任何內容時,但只是在 IDE 中撰寫程式碼時使用。因此,如果您想在這些使用者旅程中使用工具(或建立工具!),現在已經可以了。

若要進一步了解 Flutter 3.24 中包含的所有更新,請查看 DevTools 的發行備註 2.35.02.36.02.37.2

重大變更和棄用

此版本中的重大變更包括對 Navigator 的頁面 APIPopScope 中的泛型Flutter 網頁的預設渲染器 的變更,以及一些新的棄用。在 重大變更頁面 上查看完整的遷移指南。

與往常一樣,非常感謝社群為 貢獻測試 - 這些測試幫助我們識別出這些重大變更。若要進一步了解,請查看 Flutter 的重大變更政策

結語

Flutter 成功背後的核心是您 - 我們非凡的社群。沒有您无數的貢獻和堅定的熱情,這個版本是不可能實現的。我們衷心感谢您。

若要深入了解此版本中所取得的成果,我們邀請您查看 發行備註變更日誌,以獲取 Flutter 3.24 中加入的內容的完整列表。

Flutter 3.24 與 Dart 3.5 現在已在 stable channel 上提供。開始使用 Flutter 的最新旅程就像運行 flutter upgrade 一樣簡單。我們迫不及待想看看您會建立什麼!


Flutter 3.24 的新功能 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

使用 Flutter、Firebase Genkit 和 Gemini API 為經典文字遊戲添加趣味和實用性

今年的 I/O,Very Good Ventures 與 Google 的 Flutter 和 Firebase 團隊合作,創造了一種獨特的數位體驗,以展示 Gemini API 的強大功能。

填字遊戲的趣味(和挑戰)在於解決線索以完成棋盤。我們今年在 I/O 上討論過的所有內容,自然成為字詞和線索的起點。為了生成遊戲內容,我們向 Gemini Advanced 提供了主題演講的影片,並要求它建立一個與科技相關的熱門字詞和線索列表,使玩遊戲成為了解今年 I/O 公布的所有內容的有趣方式。

請繼續閱讀,了解我們如何使用 Flutter 建立 UI,並查看遊戲的開源程式碼,您可以在 GitHub 上存取。

如何玩

當您登入拼圖時,會提示您選擇您的隊伍。當您正確回答一個線索時,單詞將填入,並且格子的顏色會變為您的隊伍顏色。您的隊伍將為您解決的每個單詞獲得積分,如果您連續解決單詞而不請求提示,則您將獲得額外積分。

需要提示嗎?點擊 提示 按鈕,然後提出不超過十個關於隱藏單詞的是非題。Gemini API 會私下回答您的問題,以便您可以填寫更多單詞,並幫助您的隊伍取得勝利!

提示 功能的設計是一個很好的例子,說明不同的技術如何協同工作來解決問題。提示由 Firebase Genkit 提供支援,Genkit 是一個在 I/O 上宣布的用於 AI 開發的新框架,並且被部署為 Firebase 函式。

對 API 的網路請求包括線索的答案,因此為了將回應隱藏在訊息資料中,我們使用 Dart Frog 套件 建立了一個簡單的 Dart 後端,以使體驗更加健壯。Frog 後端呼叫 Genkit 以獲得提示,並從資料庫中擷取答案。這樣,玩家就不能簡單地檢查網路呼叫來找出遊戲的答案。

您可以在 Firebase 深入探討部落格 中閱讀更多關於 Genkit 流程的建構方式。

使用 Flutter 渲染高效能的填字遊戲棋盤

棋盤是遊戲的核心部分之一。我們優化了玩家在拼圖上的移動,以確保良好的效能,並為玩家提供最佳的使用者體驗。

我們考慮了兩種建立棋盤的選項:直接使用 Flutter 或使用 Flame 遊戲引擎。Flame 對此遊戲最引人注目的功能是其攝影機 API,它允許吉祥物輕鬆移動並支援縮放控制。但是,由於這幾乎是我們將使用的 Flame 的唯一功能,因此我們最終決定,對此場景而言,使用像 Flame 這樣的完整遊戲引擎有點過度。

尋找替代解決方案,我們探索了 InteractiveViewer Widget,它允許在自訂大小的畫布中渲染單詞,並使用矩陣轉換自由地移動吉祥物。InteractiveViewer 對我們的需求而言是一個更簡單的解決方案,具有較少的相依性和負載,這讓我們能夠更好地展示 Flutter 的靈活性與效能。

InteractiveViewer 的功能和靈活性

InteractiveViewer 內建了縮放手勢,但我們想要為桌面體驗添加更多直觀的按鈕。利用矩陣轉換,我們透過首先計算縮放比例的變化,並使用中心作為常數參考點來更新新的視窗,從而實作了縮放控制:

獲得新的暫時視窗後,我們必須確保它適合棋盤的邊界。我們必須允許兩種情況:當視窗比棋盤大時,或者當視窗的位置超出邊界時。我們透過調整縮放級別或視窗的位置來更新縮放比例變化的程度和視窗的轉換,以確保它適合邊界,如下面的程式碼所示:

最後,計算轉換並將其應用到 InteractiveViewer 控制項:

透過這段程式碼,我們擴展了 InteractiveViewer 的縮放控制,並根據我們的需求轉換了視窗。

使用 Flutter 中的 WebAssembly 提升效能

Flutter Web 應用程式的 WebAssembly 支援是今年 I/O 對 Flutter 社群的重要宣布之一。隨著全球玩家同時玩遊戲,效能是一個關鍵因素。我們利用了 WebAssembly (Wasm),它建構在 Flutter 中,以減少效能瓶頸並維持流暢的畫面更新率,特別是在遊戲中的角色和棋盤動畫方面。

Dart 後端和 Cloud Run:後端和前端之間的無縫程式碼共享

為了確保所有使用者都能享受流暢的遊戲體驗,我們的 Dart 後端使用 Dart Frog 套件 建構,並託管在 Google Cloud Run 上,以利用自動調整功能。這有助於維持最佳效能,無論活躍玩家數如何,因為遊戲會進行多次呼叫,例如每次建立使用者時,或者當玩家提交單詞或請求提示時。

使用後端來確認每個線索的答案,還可以讓我們保護填字遊戲,防止作弊。具體而言,應用程式使用 Flutter Firestore SDK 讀取資訊,但資料庫 允許 Dart 後端進行更改。這還有助於加快開發速度,因為我們可以在前端和後端使用相同的語言(Dart)。

例如,我們可以在 Player 資料模型中看到這種模式,它使用 Dart Frog API 建立一個玩家。

應用程式直接存取玩家排行榜,重複使用相同的模型,避免重複和不同步:

開始玩:解開 I/O 填字遊戲!

在您自己的所有橫向和縱向的輝煌中開始玩 填字遊戲。對於那些想要深入了解細節的人,請查看它的 開源程式碼開發者學習路徑,以展示我們如何建立它。觀看 Google I/O 回顧,以了解有關今年宣布的所有內容的更多資訊!


我們是如何建構它的:使用 AI 製作 I/O 填字遊戲 最初發佈在 Medium 上的 Flutter,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

回顧 Google I/O 2024 中的所有重大產品更新、新資源和成功案例

很難相信 Google I/O 2024 已經過去兩週了。我們對 Flutter 社群的支持表示衷心的感謝 - 這種能量令人振奮!

Flutter logo illustration

我們在幾個部落格、影片和活動中分享了許多產品更新、資源、開發人員故事、技術會議和工作坊 - 我們知道要跟蹤所有這些內容可能很困難。

在下面,您將找到我們在 Google I/O 2024 中分享的所有內容的概述,以及關於您可以在夏季的柏林、班加羅爾、北京的 I/O Connect 和 I/O Extended 活動中與我們和其他 Flutter 社群成員聯繫的活動地點和日期的更新。

部落格文章

我們在 Dart 和 Medium 部落格中發布了 四篇新的部落格文章

我們還與 Android 團隊合作撰寫了一篇部落格文章,提供有關 如何為您的專案選擇正確的框架 的一些指南:Flutter、Jetpack Compose 和 Kotlin 多平台:

Google I/O 演講、Codelabs 和工作坊

主要的 Google I/O 活動特色是關於 Dart 和 Flutter 的一系列精彩演講。我們建議從 Flutter 的新功能 主旨演講 開始,然後繼續我們的 五個技術會議,這些會議涵蓋了 CameraX、自適應 UI、AI 代理、Gemini 和應用程式深層連結等主題。

我們還有 三個新的 Codelabs,全部集中在使用 Flutter 建立 休閒遊戲 上。它們可以幫助您開始使用 2D 物理以及添加聲音和音樂。若要了解更多詳細資訊,請查看新的 2D 物理遊戲工作坊

新的 Flutter 展示故事

Flutter 展示 展示了一系列 Flutter 應用程式,這些應用程式展示了您可以使用 Flutter 在行動、網頁和桌面端創建引人入勝的使用者體驗。我們為 Google I/O 2024 添加了 四個新的展示故事

  • 環球影城環球影城使用 Flutter 打造下一代體驗
  • SupercellFlutter 幫助 Supercell 將 Supercell ID 核心程式碼大小縮減 45%
  • EtermaxEtermax 透過 Flutter 提高開發人員效率
  • 維珍理財維珍理財透過 Flutter 整合應用程式開發

I/O Connect 活動

Google I/O 並未結束於美國加州山景城的 主要活動。在全球各地有許多 Google I/O 社群活動,以及在三個地點規劃的 Google I/O Connect 活動:

  • 2024 年 6 月 27 日,德國柏林的 I/O Connect
  • 2024 年 7 月 17 日,印度班加羅爾的 I/O Connect
  • 2024 年 8 月 7-8 日,中國北京的 I/O Connect

Dart 和 Flutter 團隊將參加所有三個 I/O Connect 活動,我們希望與你們中的許多人聯繫!如果您想參加活動,請務必 註冊。我們期待與您聯繫!


來自繁忙的 Google I/O 2024 的所有 Flutter 新聞 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

undefined

【文章內容使用 Gemini 1.5 Pro 自動產生】

宣布全球遊戲挑戰賽的獲獎者

我們邀請 Flutter 和 Global Citizen 社群共同打造以幫助地球為目標的史詩級 Flutter 遊戲。來自超過 50 個國家的數千名熱情開發人員提交了數百個創新的遊戲專案。

每個專案都旨在賦予玩家知識和行動,以保護我們的星球。從資源節約到抗擊污染,這些遊戲提升了我們對迫切環境問題的整體意識,同時也真正好玩!我們深受參賽作品中令人難以置信的想法和熱情的啟發。

為我們的十強作品最後一次隆重揭曉

在 103 天的時間裡,這些專案團隊不斷地構思、開發、尋求意見和改進他們的專案。結果——誕生了令人興奮的遊戲,鼓勵我們都更深入地思考我們如何可以更可持續地生活。以下是它們,按字母順序排列!

Better World

各種環境主題,豐富多彩的視覺效果和音樂,以及與組織合作促進積極行動的想法。

Craftown

將經典的即時策略和資源管理遊戲玩法獨特地融合在一起,重點關注可持續性主題。

EcoShift Chronicles

以迷人的視覺效果和聲音設計鼓勵積極行動,讓玩家面對相關的選擇及其環境後果。

Gomiland

視覺上引人入勝、教育性、垃圾管理遊戲,靈感來自日本文化。

Last Bottle

迷人的設計和可收藏的元素,有效地傳達了它關於回收限制和批判性思考環境問題的核心訊息。

MGame - A waste management game

雄心勃勃的模擬遊戲,以引人入勝的方式呈現複雜的垃圾管理系統,讓人想起經典的城市建造遊戲。

Ocean Rangers

引人入勝的敘事、迷人的角色和策略性遊戲玩法元素,以獨特的視角呈現環境主題的熟悉類型。

PlasticPunk

城市建造風格的遊戲,以引人入勝的遊戲玩法和迷人的視覺效果,呈現出複雜的環境挑戰。

Waste Wise

垃圾分類遊戲,具有直觀的遊戲玩法,並有效地向玩家傳授正確的垃圾處理知識。

Whaley’s Bins Waste Sorting

垃圾分類遊戲,以創造性的方式進行回收教育,採用獨特的像素藝術視覺效果。

我們期待在紐約市與這些團隊共度一天,在 Google 辦公室舉辦研討會等等,並與 6 萬名 Global Citizen 在 2024 年 Global Citizen Festival 上慶祝!

但這些只是 30 多個在 Global Gamers Challenge 中獲得獎項的團隊中的 10 個,包括 Top 20 中的其他成員,您將在榮譽提名列表中看到它們。前往 flutter.dev/global-gamers/#winners 查看所有團隊!

恭喜所有獲獎者!

這還沒有結束

作者:Lisa Pak,Playing 4 the Planet Alliance 運營主管

全球遊戲挑戰賽可能即將結束,但可持續遊戲運動不會就此結束。在此挑戰賽期間開發的遊戲以及類似的挑戰(如 Global Game Jam)有可能接觸到數百萬玩家,在全球範圍內產生積極的環境變革漣漪效應。

若要與這個蓬勃發展的運動保持聯繫:

  • 加入社群:考慮加入專注於環保遊戲設計的線上社群和論壇。這些空間為分享您的作品並與其他開發人員交換想法提供了寶貴的機會。
  • 繼續玩可持續遊戲:關注 熱門遊戲,其中包含以時間限制的事件、挑戰和新關卡形式呈現的綠色啟用,讓玩家參與這個重要議題。我們的目標是接觸到盡可能多的人群,而這些遊戲可能是很好的靈感來源。
  • 讓您的聲音被聽到:撰寫您在可持續遊戲開發方面的經驗,指導有抱負的開發人員,或自行組織倡議。在分享您的知識和專業知識(無論是技術還是環境)時,您不僅支持社群的成長,而且也鼓勵其他人創造對地球產生積極影響的遊戲。

繼續打造

作者:Clayton Whittle,氣候 SIG 聯席主席

遊戲中的可持續性包括促進運動本身,將氣候和可持續性問題優先考慮到您團隊的遊戲設計實務中,並作為可持續遊戲產業的代言人堅持下去。

綠色遊戲設計是一個不斷發展的領域,在創造出產生切實可衡量影響的遊戲方面,不斷發展出更精密的實務。雖然沒有通用的綠色遊戲設計規則,但遵守標準指南可以顯著有利於任何遊戲設計團隊。

  • 了解您的受眾:有效的可持續遊戲始於了解您的受眾的需求和能力。由於可持續遊戲旨在以某種方式轉變玩家,因此了解受眾對於指導這種轉變至關重要。如果不了解受眾最初的立場,就難以引導他們到達期望的終點。
  • 具体化:集中您的訊息以提高其有效性。試圖用一款遊戲改變玩家的整個世界觀是不切實際的。相反,找出有意義的改變領域。
  • 推廣有效的行動:為玩家提供可操作的知識。向他們傳授可以採取的具有影響力的行動,以做出改變。如果玩家看到他們的行動如何在大規模上影響生態系統或社會,他們更有可能參與其中。
  • 小心 漂綠:避免表面上的可持續性努力。漂綠是指那些沒有真正整合可持續性問題的表面上的可持續性元素。雖然添加綠色藝術作品或將角色命名為「回收隊長」似乎很有吸引力,但如果遊戲玩法或敘事缺乏有意義的可持續性行動,玩家就能看穿這些表面上的聯繫。

請記住,開發具有影響力的綠色遊戲有无数种方式。您的想法和設計可能會超出這些指導方針,進入未知領域。適合您團隊的方法取決於您的使命和受眾。但是,將這些原則納入您的設計討論中有助於確保您的團隊始終专注于其影響使命。

Flutter 如何幫助您

以下是一些 Flutter 可以幫助您減少對遊戲運行位置的擔憂,並將更多時間花在為您的使命和受眾設計具有影響力的体验的方式。

  • Flutter 效率高: Flutter 的單一程式碼庫開發意味著您只需要撰寫您的遊戲一次,就可以部署到所有平台。像「狀態熱重載」等功能可以幫助您快速迭代,加速您的開發流程。
  • Flutter 容易學習:即使您不是專業的遊戲開發人員,從 Flutter 入门也比使用傳統的遊戲開發工具更容易。我們還提供了一些資源,例如 Flutter 休閒遊戲工具組 中的遊戲模板,可以為您提供一個起點,幫助您提升您的遊戲開發技能。

感謝所有參與了我們旅程的人!我們迫不及待地想看看您接下來會打造什麼!


宣布全球遊戲挑戰賽的獲獎者 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

http://creativecommons.org/licenses/by/4.0/

【文章內容使用 Gemini 2.0 自動翻譯產生】

宣佈 Dart 3.4

Dart 3.4 於今天發佈!此版本展示了 Dart 和 Flutter 在 Flutter 3.22 / Dart 3.4 / IO24 文章中的共同努力,因此請務必在那裡獲得完整資訊。這篇文章介紹了我們對 WebAssembly 的支援,然後詳細介紹了今年 Dart 語言的主要路線圖項目之一:巨集

WebAssembly 更新

今天,我們很高興地宣布,隨著最新的 Flutter 3.22 穩定版發佈,Flutter Web 應用程式 現已完全支援 WebAssembly (Wasm)!

這是 Dart 和 Flutter 多年來的投資。如果您一直在關注這些發展,您已經看到了我們的逐步發展:

  • 標準化 WasmGC 提案,
  • 加入一個全新的 Dart 編譯器後端來產生 WasmGC 程式碼,以及
  • 改進 我們的 Web 和 JavaScript 互通產品,以最好地支援 Wasm。

我們將繼續投資 WebAssembly。我們的下一步工作將是在純 Dart 應用程式中啟用對 Wasm 的全面支援,並完成一些缺失的功能(例如延遲載入)。Dart 中 Wasm 編譯的端到端工具仍在開發中,但您現在可以透過一些臨時步驟在穩定版中 試用預覽版。之後,我們還希望在 JS 環境之外的 Dart 中支援 Wasm(例如 wasmtime 和 wasmer 等標準 Wasm runtime),如 dart-lang/sdk/issues/53884 中所述。

Dart 巨集:提升開發抽象層級

我們投入了多年時間來設計 Dart 巨集系統。為了改善 Dart 的開發體驗,巨集提供了一個元程式設計解決方案,例如程式碼產生。此解決方案內建於 Dart 語言中,可為開發人員提供最大的效能、效率和生產力。現在,我們準備好提供此體驗的預覽版!

長期以來,Dart 開發人員的一個痛點是序列化和反序列化 JSON 資料的瑣碎但繁瑣的模式。製作一個可重複使用、功能足夠強大的解決方案在 Dart 中是一項挑戰,因為由於效能原因,它不支援 runtime reflection。作為替代方案,我們一直依賴於程式碼產生解決方案,例如 JsonSerializable。這些解決方案依賴於在程式碼本身之前運行的外部工具,使開發人員體驗變得複雜。

今天,我們宣布推出一個全新的 JSON 序列化和反序列化方法的預覽版:JsonCodable 巨集。

巨集是一種程式碼,它透過在編譯時檢視其他程式碼來產生更多程式碼。例如,以下是一個應用新 JsonCodable 巨集的 Dart 類別 Vehicle

1
2
3
4
5
6
7
8
9
10
11
@JsonCodable()
class Vehicle {
final String description;
final int wheels;
Vehicle(this.description, this.wheels);
}

void main() {
final jsonString = Vehicle('bicycle', 2).toJson();
print('Vehicle serialized: $jsonString');
}

那麼,它是如何工作的呢?toJson() 方法(以及配套的 fromJson() 建構函式)從哪裡來的?這是我們新的巨集系統的實驗性實作,旨在簡化開發人員體驗。當 Dart 編譯器看到 @JsonCodable() 注釋時,它會立即找到 JsonCodable 巨集的定義並開始執行它。這會導致巨集:

  1. 建立一個新的“擴充類別”;這是一種新的語言結構,可以將新的宣告加入到現有的類別中。
  2. 讀取開發人員對 Vehicle 類別的定義,以確定它有兩個欄位:descriptionwheels
  3. 將新的 toJson 方法簽章加入到擴充類別中。
  4. 填寫 toJson 方法的主體,以處理 descriptionwheels 欄位的序列化。

所有這些都立即發生。整合的體驗支援我們現有的開發人員工作流程,例如熱重新載入,如下面的螢幕錄影所示:

螢幕錄影顯示了使用巨集的體驗:最初沒有 toJson 程式碼完成,但在將 @JsonCodable 加入到類別後,toJson 程式碼完成會立即顯示。

長期巨集目標

最終目標是讓社群能夠建立自己的巨集。這提高了 Dart 程式設計的抽象層級。以資料類別為例,這是 得票最高 的 Dart 語言功能。我們研究了在 Dart 中加入對資料類別的內建支援,但了解到對於這樣的結構應該支援什麼以設定我們自己的標準,意見差異很大。欄位應該是不可變的嗎?它應該支援 equals 嗎?hashCode 呢?也許還有 toString?我們的結論是,支援巨集系統將是更好的方法。社群可以建立自己的抽象類型,允許更多可擴展的實驗和多樣性。

設計和實作這樣一個強大的巨集系統是一項艱鉅的任務。我們決定以一種不會對核心 Dart 開發人員使用案例(例如程式碼輔助和完成、程式碼分析和熱重新載入)產生負面效能影響的方式來完成它。考慮到這一點,我們正在採取分階段的方法:

  • 在今天的版本中,我們將提供單個巨集 JsonCodable 的預覽版,以便使用者可以開始熟悉使用巨集的開發人員體驗。
  • 如果此巨集的推出順利,那麼我們希望在以後的版本中將 JSON 巨集升級到穩定版。
  • 同時,我們正在努力完成底層巨集系統的設計和實作。一旦我們對其效能和穩定性充滿信心,最終目標將是讓 Dart 開發人員社群能夠定義自己的巨集。

完成這些階段還有很多工作要做。同時,您可以閱讀文件以進一步了解 Dart 巨集系統,並立即試用 JsonCodable 巨集 的預覽版。

其他改進

與往常一樣,此版本包含所有持續的開發,這些開發旨在提供最佳版本的 Dart。在此版本中,我們進行了以下改進:

  • 解決了超過 50% 的分析器程式碼完成錯誤。(請繼續提交 錯誤報告!)
  • 改進了條件表達式、if-null 表達式和 switch 表達式的類型分析與語言規範的一致性(變更日誌)。
  • dart:cli 函式庫中移除了不完整且不一致的工具,以償還 Dart VM 中的技術債務。
  • 解決了一些不足之處,以改進新的 dart:js_interop 函式庫。

查看完整的 變更日誌!別忘了閱讀此版本的 Dart 和 Flutter 聯合部落格文章,以了解我們共同努力的完整故事!


宣佈 Dart 3.4 最初發佈於 Medium 上的 Dart,人們在那裡透過醒目顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

宣布 Flutter 3.22:WebAssembly、圖形渲染增強功能和更多 AI 整合選項

歡迎回來,一起迎接另一個令人興奮的 Flutter 穩定版本!這次,我們很高興推出 Flutter 3.22。我們將 WebAssembly 帶到穩定通道,為 Android 上的 Impeller 提供功能齊全的 Vulkan 後端,有望帶來更流暢的圖形和大幅提升效能。我們還推出了精簡的工作流程,其中包含新的 Widget 狀態屬性、動態視圖大小調整和改進的表單驗證功能。但這還不是全部——您將發現風味條件的資產捆綁、Firebase 上 Vertex AI 的預覽版本(使用 Dart),以及更新的 DevTools,讓您的生活更輕鬆。

自上次更新以來,僅僅幾個月,我們就從 Flutter 社群合併了令人印象深刻的 1595 個拉取請求,其中有 37 位新社群成員首次為 Flutter 貢獻!

因此,深入了解 Flutter 社群帶給這個最新版本的最新功能和增強功能吧!

WebAssembly

隨著 Flutter 3.22 的發佈,Wasm 現在可以在穩定通道上使用,提供顯著的效能提升。在我們在 M1 MacBook 上使用 Chrome 進行的內部基準測試中,Wonderous 應用程式的畫面渲染時間平均提高了 2 倍,在最壞的情況下提高了 3 倍。

這些增強功能對於具有動畫和豐富轉場的應用程式至關重要,在這些應用程式中,保持流暢的畫面速率至關重要。Wasm 透過減少效能瓶頸來幫助實現這一點,從而帶來更流暢的動畫和轉場。若要開始在您的 Flutter 網頁應用程式中使用 Wasm,請查看我們的 Dart Wasm 文件Flutter Wasm 文件。如需完整的公告,請訪問 Google I/O 部落格文章中的 Flutter

引擎

Flutter 3.22 為 Impeller 引入了重大更新,Impeller 是驅動 Flutter 應用程式的渲染引擎。主要亮點包括完成 Android 上的 Vulkan 後端,以實現更流暢的圖形和改進的效能,為模糊效果和複雜路徑渲染進行持續優化,以及一個新的實驗性 API,用於使用 Impeller 進行測試。根據我們的路線圖,我們致力於提升 Impeller 的品質和效能,包括完成 iOS 到 Impeller 的遷移和擴展 Android 支援。

Impeller

Android 上的 Vulkan 後端功能完整

在此版本中,Impeller 的 Android Vulkan 後端已具備完整的功能。特別是在過去的幾個月裡,團隊一直在努力完成 快速進階混合 的實作,支援使用 FragmentProgram API 的自訂片段著色器,PlatformView 支援(儘管它需要 少量 API 遷移),以及完全實作 所有模糊樣式

Android 預覽

在 3.19 穩定版本中,在發佈 Impeller 的 OpenGL 後端的改進之後,我們邀請使用者在支援和不支援 Vulkan 的 Android 設備上試用 Impeller。在過去的幾個月裡,在評估 OpenGL 後端的效能並估計 Vulkan 後端的剩餘工作量之後,我們決定將精力集中在首先讓 Vulkan 後端做好生產準備。

Impeller 解決了著色器編譯卡頓的問題。此外,在我們的基準測試中,它在平均值、第 90 個百分位數和第 99 個百分位數的畫面時間方面優於傳統渲染器。因此,我們認為 Vulkan 後端在 Android 上的效能是可以接受的。在此版本(3.22)中,選擇加入 Impeller 的應用程式將在有 Vulkan 支援的地方使用 Vulkan 後端。在將來的版本中,這將成為預設值。當選擇加入 Impeller 的應用程式在不支援 Vulkan 的設備上運行時,Flutter 將會自動無縫切換為使用 OpenGL ES 和 Skia。您無需採取任何措施。在未來,當我們認為 OpenGL ES Impeller 後端已做好生產準備時,這種回退也會使用 Impeller。

隨著 Android 上的 Impeller 預覽繼續在 3.22 穩定版本週期中進行,我們請求 Flutter 開發人員升級到最新的穩定版本,並在 啟用 Impeller 時提交有關任何發現的不足的錯誤。在此階段的回饋對確保 Impeller 在 Android 上取得成功以及我們能夠在今年晚些時候的版本中自信地將其設為預設渲染器至關重要。Android 硬體生態系統非常多元。因此,關於 Impeller 最有用的回饋應包括有關發生問題的特定設備和 Android 版本的詳細資訊。

模糊效能改進

模糊已在 iOS 和 Android 上的 Impeller 中 重新實作。特別是,這種新方法類似於 Skia 的方法,在 基準測試 中將模糊的 CPU 和 GPU 時間減少了近一半。

下圖顯示了在 iPhone 11 設備上進行的病態基準測試中的最壞情況、第 99 個百分位數、第 90 個百分位數和平均畫面柵格化時間以及 GPU 畫面時間(以毫秒為單位),旨在突出顯示模糊效能。在重寫 Impeller 的模糊之後,背景濾鏡模糊的 CPU 和 GPU 成本都幾乎減少了一半。這種改進的規模也適用於非病態情況,正如典型應用程式中所出現的那樣。

在 iPhone 11 設備上進行的病態基準測試中的第 99 個百分位數、第 90 個百分位數和平均畫面柵格化時間以及 GPU 畫面時間(以毫秒為單位),旨在突出顯示模糊效能

Stencil-then-Cover

iOS 和 Android 上的 Impeller 都已 轉移到新的渲染策略,該策略基於 OpenGL Redbook 中“使用模板緩衝區繪製填充的凹多邊形”章節中描述的 Stencil-then-Cover 方法。團隊成員在 GitHub 問題 #123671 中討論了這種技術在 Flutter 中的應用。

這種方法解決了柵格執行緒在 CPU 上為複雜路徑(例如,SVG 和 Lottie 動畫)計算細分時花費過多時間的問題。更改之後,包含複雜路徑的畫面的總畫面時間(CPU 上的 UI 執行緒 + CPU 上的柵格執行緒 + GPU 工作)要低得多。使用者會注意到 Lottie 動畫和其他複雜路徑渲染得更加流暢,CPU 利用率更低,而 GPU 利用率略微更高。

(左) Lottie 動畫。以前,Impeller 在最近的 iPhone 上需要 64ms/畫面 的柵格執行緒 CPU 時間才能渲染它。(右) 在我們實施 Stencil-then-Cover 優化之後,在相同設備上渲染的相同動畫。柵格時間幾乎快了 10 倍。

雖然對這些改進感到滿意,但我們還有更多工作要做。除了其他機會之外,我們意識到折線生成在 CPU 配置檔案中仍然很突出,我們打算調查將此工作也轉移到 GPU 上。

新的 API

雖然仍處於實驗階段,但 flutter test 現在接受 --enable-impeller 標誌,它使用 Vulkan 後端來執行 Impeller。

架構

Widget 狀態屬性

MaterialState 已被移動到 Material 函式庫之外,並被重新命名為 WidgetState,以便於 Cupertino、基本 Flutter 框架和套件作者使用。如需有關遷移到新的 WidgetState 的更多資訊,請查看 遷移指南

動態視圖大小調整

對動態視圖大小調整的 增強功能 有利於構建響應式佈局的開發人員,確保在各種設備螢幕上具有更好的 UI 自適應性。

改進的表單驗證

感謝 Flutter 社群成員 SharbelOkzan貢獻,Flutter 3.22 帶來了更靈活的表單驗證方法,使開發人員能夠建立更健壯的使用者輸入處理,從而提升可用性和安全性。

2D API 中的協變

減少在 2D 圖形 API 中進行類型轉換的需要,簡化了開發工作流程並提高了效能,這對於遊戲和複雜動畫非常重要。

風味條件的資產捆綁

使用 風味 功能的開發人員現在可以將個別資產配置為僅在為特定風味構建時進行捆綁。如需更多資訊,請查看 根據風味有條件地捆綁資產

使用 Dart 套件變換資產

使用者現在可以將 Dart 套件配置為在捆綁時變換應用程式的資產。如需更多資訊,請查看 在構建時變換資產

Android

深度連結

深度連結可以顯著提高 Flutter 應用程式中的使用者體驗,充當將使用者無縫引導到應用程式中特定內容的捷徑,從而提升參與度和推動銷售。雖然 iOS 的通用連結和 Android 的應用程式連結因其安全性及其使用者友好的特性而受到高度推薦,但設定它們可能有點棘手。

在上次 Flutter 穩定版本中,我們在 DevTools 中引入了一個深度連結驗證工具,該工具支援為 Android 應用程式檢查網頁配置。在此版本中,我們添加了一組新的功能來幫助驗證 Android 清單檔案中的設定。

如需有關使用此工具的更多資訊,請查看 驗證深度連結

預測返回手勢

Flutter 現在為 Android 的即將推出的預測返回功能提供了更多支援,使用者可以在返回手勢期間預覽上一個路由,甚至預覽上一個應用程式。這仍然是 Android 設備上的功能標誌,但您可以在 GitHub 上找到有關如何自行嘗試它的詳細資訊。

Flutter 工具強制執行 Gradle、AGP、Java 和 Kotlin 上的版本要求

在此版本中,Flutter 工具強制執行有關它支援的 Gradle、Android Gradle Plugin (AGP)、Java 和 Kotlin 版本的策略。最初,該工具只提供警告。

目前,支援的版本範圍如下:

  • Gradle - 完全支援 7.0.2 到最新版本,否則警告
  • AGP - 完全支援 7.0.0 到最新版本,否則警告
  • Java - 完全支援 Java 11 到最新版本,否則警告
  • Kotlin - 完全支援 1.5.0 到最新版本,否則警告

在下次主要版本更新中,這些警告將變為錯誤,可以使用 --android-skip-build-dependency-validation 標誌覆蓋。更一般而言,該工具會在完全放棄對這些相依項目的給定版本的支援(生成錯誤)之前,至少提供一個版本的警告。

這項策略在 相關的設計規範 中有討論。歡迎隨時發表意見和回饋。

支援在 Android 上的 Gradle 組建指令碼中使用 Gradle Kotlin DSL

Gradle Kotlin DSL 現在在 Flutter 中得到支援,為傳統的 Gradle Groovy DSL 提供了一個替代方案。這種支援允許提供更好的程式碼編輯體驗,其中包含自動完成、快速存取文件、原始碼導航以及上下文感知重構。

此初始支援由 GitHub 使用者 bartekpacia 貢獻。開發人員現在可以选择使用 Kotlin 重寫他們的 Gradle 組建指令碼,以利用這些優點,儘管 Flutter 工具目前還不允許在使用 flutter create 時選擇 Kotlin 而不是 Groovy。

如需更多詳細資訊,請查看 bartekpaciaPR 140744

平台視圖改進

給所有 Flutter 應用程式開發人員的提醒!如果您使用 Flutter 構建依賴原生 Android 組件(如地圖、網頁視圖或某些 UI 元素)的應用程式,我們有一些重要資訊。

由於 Android 14 中的一個錯誤,使用舊版 Flutter 構建的應用程式可能無法在運行此新 Android 版本的設備上正常工作。

Flutter 3.22 修複了這個問題,並改進了 Android 應用程式中這些原生組件的整體效能。因此,為了確保您的應用程式在所有 Android 設備上順暢運行,請確保使用 Flutter 3.22 重新構建和發佈您的應用程式。

此更新還包括幕後改進,以使 Android 上的平台視圖更加可靠和高效。

KitKat 支援結束

Flutter 的最低支援 Android 版本現在是 Lollipop (API 21)。從 Flutter 的 3.22 穩定版本開始,Flutter 將不再在運行 Android KitKat (API 19) 的設備上工作。如需更多詳細資訊,請查看我們的 棄用指南

iOS

平台視圖效能

我們理解 iOS 上的平台視圖效能一直是許多 Flutter 開發人員的痛點。這在使用平台視圖時,特別是在捲軸視圖中很明顯。

最近的更新直接解決了這些問題,在嵌入文章中的多個內聯廣告等場景中取得了顯著的改進。以下是一些 基準測試 中的一些關鍵改進:

  • 降低 GPU 使用率: GPU 使用率降低了 50%,從而減少了功耗,並可能帶來更流暢的使用者體驗。
  • 改進畫面渲染: 平均畫面渲染時間減少了 1.66ms(33%)。
  • 最小化卡頓: 最壞情況下的畫面渲染時間減少了 3.8ms(21%)。

如果您以前在捲軸視圖中使用多個平台視圖(如廣告、地圖等)時遇到效能挑戰,這些優化可能有助於提供更流暢、響應更靈敏的捲軸體驗。請試用一下,並告訴我們您的想法。

生態系統

Vertex AI for Firebase Dart SDK 預覽版本發佈

Vertex AI for Firebase 產品已發佈到公開預覽版,其中包含 Dart SDK。這使您可以使用 Gemini API 為您的 Dart 或 Flutter 應用程式構建生成式 AI 功能,並考慮到生產、效能和企業規模。該 SDK 集成了 Firebase 應用程式檢查,這可以保護您的 API 調用,並保護您的後端基礎設施免受嚴重的威脅,例如計費欺詐、釣魚和應用程式偽裝。跳入 Dart 入門,並使用促銷代碼免費開始使用。

Google AI Dart SDK 仍然可用,建議僅用於原型設計。Google AI 具有免費使用權限(在限制範圍內,以及在有提供的地方),並提供按使用付費定價。如果您一直在使用 Google AI Dart SDK 進行原型設計,並且已準備好遷移到 Firebase 上的 Vertex AI,請查看 遷移指南

DevTools 更新

我們繼續改進 DevTools,這是 Dart 和 Flutter 的效能和除錯工具套件。此版本包含效能改進、通用潤色以及新的功能,例如在時間軸中包含 CPU 樣本、進階過濾以及支援匯入和匯出記憶體快照。

其他值得注意的改進與 devtools_extensions 和 devtools_app_shared 套件一起發佈,這些套件支援 DevTools 擴展作者。我們添加了對將擴展連接到新的 Dart Tooling Daemon (DTD) 的支援,這使 DevTools 擴展可以存取由其他 DTD 客戶端(例如 IDE)註冊的公開方法,以及允許存取用於與開發專案進行互動的最小檔案系統 API。

若要進一步了解 Flutter 3.22 中包含的所有更新,請查看 DevTools 的發行備註 2.32.02.33.02.34.1

Flutter 的 Google 行動廣告 SDK

對於那些使用廣告為 Flutter 應用程式獲利的人來說,我們有一些好消息:Flutter 的 Google 行動廣告剛剛發佈了 5.0.1 版本的重大更新!

增強對使用者訊息平台 (UMP) SDK 的支援: 此更新添加了對 Android UMP SDK 版本 2.2.0 和 iOS UMP SDK 版本 2.4.0 中的最新 API 的支援。UMP SDK 對遵守隱私法規至關重要,讓您更容易獲得使用者對個人化廣告的同意。此新版本引入了幾個新的 API,以簡化同意收集過程。

擴展的中介合作夥伴: 我們透過提供與熱門廣告合作夥伴的整合,擴展了您的廣告變現範圍,這些合作夥伴包括 UnityMetaAppLovinIron SourceMintegralPangleDT ExchangeInMobi 以及 Liftoff。您現在可以使用擴展的中介選項和簡化的實作,最大限度地提高應用程式的收入。

我們鼓勵您在 Flutter 應用程式中試用這些新功能,並告訴我們您希望我們支援哪些其他中介合作夥伴。您的回饋對我們持續改進 Flutter 的 Google 行動廣告 SDK 至關重要。

重大變更和棄用

移除 v1 Android 嵌入

版本一 Android 嵌入的刪除正在進行中。這可能對大多數應用程式沒有影響,因為

  1. 版本二已成為預設版本多年。
  2. Flutter 工具會阻止構建版本一應用程式,除非使用 --ignore-deprecation 標誌特別覆蓋。

此版本完全中斷了 Flutter 工具對 v1 應用程式的支援。不再可以用此方法覆蓋。

插件作者,請注意: 當 v1 android 嵌入最初被棄用時,為插件作者撰寫了一個遷移文檔:https://docs.flutter.dev/release/breaking-changes/plugin-api-migration。作為此遷移的一部分,建議插件作者透過在其 Plugin.java 中包含具有以下簽章的方法,來保持對使用 v1 嵌入的應用程式的支援:

1
public static void registerWith(@NonNull io.flutter.plugin.common.PluginRegistry.Registrar registrar) 

我們計劃在下一個版本中完全刪除 v1 Android 嵌入,屆時包含具有此簽章的方法的插件將無法編譯(因為它會引用 v1 android 嵌入中的類型)。

它目前沒有任何作用,因為此版本中斷了使用 v1 嵌入的應用程式。我們建議插件作者儘快發佈已移除 v1 程式碼的插件更新版本,以避免在將來的 Flutter 版本中出現中斷。例如,請查看 PR 6494,該 PR 移除 Flutter 團隊維護的插件。

在 3.22 中移除的棄用

此版本中的 重大變更 包括在 v3.19 發佈後過期的棄用 API。若要查看所有受影響的 API,以及其他內容和遷移指南,請查看 此版本的棄用指南。這些 API 中的許多都由 Flutter fix 支援,包括 IDE 中的快速修復。可以使用 dart fix 命令列工具評估和應用批量修復。

與往常一樣,非常感謝社群為 貢獻測試 - 這些測試幫助我們識別出這些重大變更。若要進一步了解,請查看 Flutter 的重大變更政策

結語

Flutter 成功背後的核心是您 - 我們非凡的社群。沒有您無數的貢獻和堅定的熱情,這個版本是不可能實現的。我們衷心感謝您。

準備探索 Flutter 3.22 嗎?深入了解完整的發行備註和變更日誌,啟動您的終端機,然後運行 flutter upgrade。我們迫不及待想看看您會建立什麼!


Flutter 3.22 的新功能 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

在 Google I/O 2024 上推出 Flutter 3.22 和 Dart 3.4

過去幾個月,Dart 和 Flutter 的空中交通管制特別繁忙,但我們很高興宣布 Flutter 3.22 和 Dart 3.4 已於今天順利推出,並可供使用,恰逢今年的 Google I/O

我們始終致力於提供強大的語言和框架配對,讓您能夠從單個共用程式碼庫構建精美、豐富且快速的應用程式,以便您可以將應用程式交付給行動、網頁和桌面上的使用者,而無需分散您的產品路線圖。

Flutter 3.22 和 Dart 3.4 提供了效能改進和平台特定的細化,使我們更接近這個願景。我們特別興奮地分享我們在 Wasm 方面的旅程,但您還會發現更多內容,包括改進的 Impeller 渲染引擎、iOS 上更流暢的視覺效果和更低的 CPU 使用率、使用 Android 的預測性返回手勢增強的平台導航、使用 Google Mobile Ads SDK 擴展的變現選項,以及 DevTools 中一個全新的強大深度鏈接驗證器。Dart 開發人員將享受使用 IDE 中的 dart fix 簡化 API 遷移以及用於進階分析的新 DevTools 功能。此外,您現在可以預覽用於 Firebase Dart SDK 的 Vertex AI,將 AI 驅動的功能與強大的安全措施相結合。

今天,我們還將重點介紹頂尖公司如何使用 Flutter 來提高生產力並構建高效能的體驗。我們將重點介紹一些特別令人興奮的功能,這些功能讓我們更接近我們的目標,即在所有平台上提供類似原生的效能,並包括我們對生產力、開發人員體驗和遊戲的投資的最新更新。

如果您想詳細了解版本中包含的所有內容,請查看專門的 FlutterDart 文章。是時候放手一搏了!

Flutter 在行動中

Flutter 開發人員正在忙碌地將大型新應用程式發佈到應用程式商店。讓我們看看其中幾個。

幫助大型企業級應用程式在行動端和網頁端交付

  • 在英國,金融機構 維珍金融 在其行動銀行和信用卡應用程式套件中使用 Flutter,以統一應用程式開發流程,加快變更速度,並提供行業領先的使用者體驗。
  • 美國保險公司 GEICO 最近 分享了 Flutter 如何幫助他們改進 iOS、Android 和網頁上的品牌使用者體驗,減小程式碼庫的大小,並提高開發效率,所有這些都在規模上實現。
  • 環球影城目的地與體驗 發佈了他們好萊塢、大阪和奧蘭多公園的新 Flutter 行動應用程式。觀看下面的影片,了解他們為什麼選擇 Flutter 以及 Flutter 的表現如何。

超越行動端和網頁端

  • Canonical 團隊一直在與 Flutter 合作自 2021 年起 為 Ubuntu 提供 Flutter 生態系統 的支援。在過去的一年中,Canonical 團隊使用 Flutter 從頭開始重建了 Ubuntu 安裝程式。
  • LG 選擇 Flutter 來增強他們的智慧電視作業系統 webOS。Flutter 的效能、生產力和強大的生態系統讓 LG 可以快速開發和部署 webOS 系統應用程式,這些應用程式可以順暢運行。到 2025 年,Flutter 將為全球數千萬台 LG 電視提供系統應用程式。

這些成功案例鼓舞著我們,我們致力於讓 Flutter 變得更好。讓我們深入了解最新的產品更新,展示我們正在做些什麼來讓您能夠構建更加驚豔的應用程式、遊戲和體驗。

WebAssembly:在網頁上追逐原生效能

今天,我們宣布在我們的穩定版本中支援將 Flutter 網頁應用程式 編譯 為 WebAssembly (Wasm)。這是一種用於網頁瀏覽器的令人興奮的新指令格式,它提供了一種可移植的、平台中立的二進制程式碼格式。

我們對 Wasm 的支援是一項深入的、多年來的投資。首先,我們與 Chrome 團隊合作,在 WebAssembly 中為像 Dart 這樣的高級管理語言定義支援,這些語言通常使用垃圾回收。這導致了 WasmGC 提案,該提案現在已成為一個完整的標準,並在 Chrome(Chromium 119 及更高版本)和 Firefox(120 及更高版本)中提供了運行時實施,預計其他瀏覽器供應商將會效仿。接下來,我們添加了一個全新的 Dart 編譯器後端以生成 WasmGC 程式碼,而 Dart 和 Flutter 團隊合作執行編譯後的應用程式程式碼和 Flutter 渲染引擎作為 Wasm 模組,並提供有效的 Wasm 到 Wasm 的互操作性。

那麼最終結果是什麼?我們看到了效能的大幅提高,接近我們在運行機器程式碼的行動和桌面設備上的效能。在我們的內部基準測試中(在 M1 MacBook 上使用 Chrome),Wonderous 的畫面渲染時間在一般情況下提高了 2 倍,在 99% 的最差情況效能下提高了 3 倍。改進的渲染效能對於具有動畫和豐富轉場的需要大量資源的應用程式至關重要,在這些應用程式中,超出畫面預算(分配給渲染下一畫面的時間)會導致非常明顯的卡頓。Wasm 可能會消除這種卡頓,如下圖所示,Wonderous 應用程式使用傳統的 JS 編譯和 Wasm 編譯進行比較。

比較Wonderous 範例應用程式中 Javascript 和 Wasm 的渲染速度。

Flutter 網頁應用程式的 Wasm 編譯今天在穩定版本中可用。若要開始使用,請查看我們的 Dart Wasm 文檔Flutter Wasm 文檔

Dart macros:提高開發抽象級別

我們致力於提供一流的開發人員體驗。這意味著要解決 Dart 開發人員長期存在的痛點,例如序列化 JSON 資料。

這是一種普遍的模式,既簡單又乏味。目前的解決方案意味著要麼手動地完成編碼和解碼樣板,要麼在程式碼生成解決方案(例如 JsonSerializable 套件)的形式中添加額外的工具。

今天,我們宣布了一個用於 JSON 的更好選項的預覽版本:JsonCodable macro。

macros 是創建更多程式碼的程式碼。它們就像程式碼生成,只是 macro 系統 內建於 Dart 中 並在您編輯和運行程式碼時 實時發生。這是一種整合的體驗,沒有延遲,完全支援我們現有的開發工作流程,例如熱重載,如這個螢幕截圖所示:

螢幕截圖展示了使用 macro 的體驗:最初沒有 `toJson` 程式碼完成,但在為類別添加 `@JsonCodable` 之後,`toJson` 程式碼完成立即顯示。

我們很興奮地看到 macros 為我們的開發人員解決各種問題。例如,資料類別,是 票數最高的 Dart 語言功能。除了特定應用之外,我們的最終目標是在 Dart 中擁有一個 macro 系統,允許使用者創建自己的 macros 並提高 Dart 程式設計的抽象級別。

設計和實作這樣一個強大的 macro 系統是一項巨大的任務,因此目前沒有設定穩定版本的時間 - 有關更多詳細資訊,請查看 Dart 3.4 文章。同時,今天就嘗試一下 JsonCodable macro 的預覽版本。有關更多資訊,請查看 macros 文檔

Flutter 遊戲開發的新資源

我們在遊戲方面的早期投資取得了令人鼓舞的成果,包括來自行業領導者(如 EtermaxSupercell)的成功案例,他們都在利用 Flutter 的功能和靈活性來有效地提供愉悅的使用者體驗並擴展其覆蓋範圍。

今天,我們很興奮地使用這些 Flutter 遊戲開發人員的新資源來延續這種勢頭:

賦能可持續的遊戲開發

在 2024 年 1 月,在受到他們使用 Flutter 的 故事 的啟發下,我們與全球公民合作,挑戰我們的社群使用 Flutter 設計、構建和發佈可持續性遊戲。這些遊戲旨在激勵和賦能玩家,讓他們為環境採取一些微不足道但有意義的行動。今天,我們宣布 10 位獲獎者

恭喜所有獲獎者!

更多探索

今天我們只有時間重點介紹這些內容,但還有許多其他我們沒有涉及的令人興奮的改進。以下是一些需要注意的其他事項:

  • 您可以 預覽用於 Firebase Dart SDK 的 Vertex AI,在 Dart 或 Flutter 應用程式中使用 Gemini API 來實現 AI 驅動的功能。SDK 與 Firebase 應用程式檢查相結合,保護您的 API 調用,並保護您的後端基礎架構免受嚴重的威脅,例如計費欺詐、釣魚和應用程式偽造。有關詳細資訊,請查看我們的 AI 頁面
  • Impeller,我們的 下一代渲染引擎,現在在 Android 上功能齊全。
  • Android 的預測性返回手勢 現在支援在 Flutter 應用程式中導航時,以及導航到其他應用程式或主畫面時。
  • iOS 上的 平台視圖 已進行效能優化,將 CPU 使用率降低了高達 50%。
  • Google Mobile Ads SDK 已擴展以支援更多廣告合作夥伴和調解選項。
  • DevTools 有一個新的 深度鏈接驗證器,它可以幫助您識別和解決 Android 深度鏈接配置中的錯誤,以便您可以更輕鬆地將網頁體驗與 Flutter 應用程式連接起來。
  • dart fix,我們的 API 遷移工具,現在可以直接從 IDE 中調用。
  • DevTools 現在支援時間線上進階篩選和 CPU 樣本。

前往 Flutter 技術文章Dart 3.4 文章 獲取有關這些內容以及更多內容的更多詳細資訊。

與往常一樣,我們非常感謝您的持續支援、熱情、熱忱和回饋。沒有您,這個專案是不可能實現的,我們迫不及待地想看看您將如何繼續推動 Flutter 向前發展。

Flutter 完畢。我們希望很快再見到您!


在 Google I/O 2024 上推出 Flutter 3.22 和 Dart 3.4 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

使用 Flutter 開發跨平台應用程式 - Google Classroom 如何讓教師和學生步調一致

Google Classroom 應用程式最初於 2014 年推出,如今全球有 1.5 億教師和學生使用它來組織作業、成績和課堂通訊。該應用程式可在 Android 和 iOS 上使用,開發工作始於當年早些時候,並經歷了兩個行動平台的巨變時代。事實證明,管理這些分歧的變化帶來了挑戰。

儘管努力同步,但在 2021 年,也就是 7 年後,Classroom 應用程式的 Android 和 iOS 程式碼庫在功能、UI 和實作方面逐漸出現分歧。從最明顯的地方,例如屏幕對相同 UI 採取不同方法,到不太明顯的地方,例如驗證和應用程式啟動邏輯的差異;Classroom 逐漸變成一個難以維護和改進的應用程式,兩個程式碼庫給一個小型開發人員團隊帶來了沉重的負擔。

有許多選項可供選擇,從堅持現狀,到增加更多開發人員,再到使用跨平台框架完全重寫兩個程式碼庫。該團隊致力於改進,這排除了堅持現狀的選項,然後評估穩定兩個現有程式碼庫需要做些什麼,這排除了僅添加更多開發人員的方案。最終,團隊選擇了第三個方案:使用單一來源、跨平台的解決方案重新構想 Classroom,而這個方案最終是 Flutter。

Flutter 如何簡化 Classroom 應用程式

不一致的 UI

Classroom 最明顯的問題 - UI 變異 - 強迫教師熟悉 Android 和 iOS 的 UI。畢竟,很容易想像學生會問關於作業屏幕和說明的問題,而一個平台上的說明在另一個平台上對於學生來說可能毫無意義。

傳統方法是由不同的團隊開發的獨立的客戶端應用程式,這些應用程式會隨著時間推移而出現分歧。只有對每個功能進行一致而艱苦的同步工作才能阻止這種情況。相比之下,Flutter 的本質顛覆了這種預設結果。使用 Flutter,UI 預設情況下是相同的 [1],直到主動工作(通常為了適應性)迫使它們為了使用者利益而出現分歧。

[1] 在 Classroom 的 Flutter 客戶端中,保留了一些細微的故意差異,例如系統欄和底部控制項。Flutter 保留了這些平台特有的細節,同時將屏幕中央 90% 的區域留給單個 UI 實作來填充。

混亂的業務邏輯

Classroom 的 Android 和 iOS 客戶端之間存在著差異,這不僅僅是 UI 的問題。受伺服器端解決方案的影響,該方案將一些複雜的業務邏輯轉移到客戶端,舊版的 Classroom 應用程式還處理核心實作方面的差異。除了造成偶爾的平台特定錯誤(這可能會讓工程師難以重現!)之外,這還給任何評估兩種實作正確性的人都帶來了相當大的認知負擔。

使用 Flutter 重寫 Classroom 解決了一系列錯誤,包括先前報告的和未報告的錯誤,這純粹是 Flutter 如何處理原生平台互動的結果。

在原始程式碼中,多年的持續開發偶爾會模糊 UI、業務和平台特定邏輯之間的界限。這意味著使用者的錯誤報告幾乎總是需要付出巨大的努力才能隔離,因為整個呼叫堆疊都可能存在問題。是否由於檔案系統讀取錯誤、業務邏輯通信錯誤,或者由於 UI 接收了檔案但隨後遺失了檔案而導致請求的檔案無法載入?唯一的解決方法是 調查所有內容

當然,Flutter 開發人員可以像其他人一樣混淆這些界限並混合邏輯,但 Classroom 工程團隊發現,遵循框架最佳實務使這種嘗試變得十分明顯。Flutter 的聲明式 UI 系統強烈建議不要將業務邏輯意外放置在 UI Widget 中,而新的 MVVM 架構甚至有助於在位於 Flutter Widget 背後的龐大程式碼庫中強制執行明確的責任層級。

Flutter 應用程式仍然會定期與底層平台進行通信 - 畢竟,上傳和查看作業的使用者旅程離不開檔案系統 - 但 Flutter 將平台特定邏輯隔離到專用 Plugin 的模式再次阻止了例行磁碟 I/O 偷偷溜進不應該出現的地方。以下範例展示了 Flutter 應用程式在不混淆整個呼叫堆疊的情況下存取檔案系統的一種實際方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import "dart:io";
import "package:path/path.dart" as path;
import "package:path_provider/path_provider.dart" as path_provider;

// 載入學生為特定作業儲存的作業。
// 回傳值的 exists() 函式會在學生將作業交給狗狗吃掉的情況下返回 False。
Future<File> getHomework(Assignment assignment) async {
// 使用 `path_provider` 套件將平台特定的檔案系統怪癖抽象化
final Directory homeworkDirectory =
await path_provider.getApplicationSupportDirectory();

// 提取學生上傳的作業
return File(
path.join([homeworkDirectory.absolute.path, assignment.name]),
);
}

這個範例很簡單,Classroom 工程團隊最終開發了他們自己的幾個 Plugin,以包含更複雜的與主機平台的互動。有趣的是,這麼做讓他們的原生程式碼 更容易除錯,比他們最初的原生應用程式更容易。這是怎麼做到的呢?在 Flutter Plugin 中遵循「不要重複自己 (DRY)」原則意味著將儘可能多的業務邏輯提升到 Dart 程式碼中,只為原生互動保留最簡單的進出方法呼叫。這會強制在領域邏輯和平台邏輯之間建立堅如磐石的分隔;這意味著 Classroom 的 Android 或 iOS 程式碼中的任何錯誤都可能出現在隔離的單一責任函式中,這些函式很容易進行推理。

效能消耗

當使用者旅程失敗時,就會提交一個具體的錯誤,所有人都同意需要解決。但對於更微妙的問題,例如應用程式啟動時間隨著時間推移越來越慢,自應用程式推出以來每年都在惡化,該怎麼辦?再加上對保持多個客戶端同步的擔憂,突然之間,對應用程式啟動流程的緩慢進行故障排除感覺就像一項無望的任務。

在這裡,Flutter 通過自身速度足够快,不至於加剧问题,更重要的是,它提供了從頭開始的機會。Classroom 團隊知道他們是在建立新的東西,而不是繞過多年開發積累的骨架,他們通過移除冗餘的 API 呼叫,並行化其他獨立的 API 呼叫,以及在所有內容解析完成時顯示閃爍效果和其他 UI 預覽,使他們的授權和啟動流程更加清晰明了。结果是應用程式启动时间惊人地 *减少了 80%*!

注釋功能

Classroom 的大部分功能可以看作是一個相當例行的應用程式,它將使用者圍繞共享內容(如作業和上傳的作業)聚集在一起。但有一個功能顯得 非常棘手。Classroom 的主要功能之一是檔案共享,教師和學生都可以創建、查看和編輯檔案,包括自由形式的注釋,就像在真紙上用筆或記號筆繪畫一樣。這個注釋共享功能已經存在於 Classroom 的原生 Android 和 iOS 客戶端中,因此將其移植到 Flutter 的任何摩擦都會成為阻礙。

Classroom 團隊能夠將這個注釋功能重新打包到一個 Plugin 中,該 Plugin 將平台特定實作委派給單獨的函式庫。對於檔案注釋,這些函式庫成為了 Google One、Google Keep 和舊版 Classroom 應用程式中已經使用的預先存在的原生函式庫的薄薄包裝。在內部,Android 和 iOS 對檔案共享有不同的實作要求。在 iOS 上,Classroom 應用程式通過原生視圖存取檔案,但在 Android 上,它會直接打開 Google Keep 應用程式。但是,良好的 Plugin 設計原則能夠將這些實作細節隔離,同時仍然為應用程式中的其他部分提供一個乾淨的、單一的 Dart API 來進行導航。最終,Classroom 中「最棘手」的功能之一已成功移植到 Flutter。

以下是 Classroom 在 Android 上的注釋功能的可視化,概述了原生和 Flutter UI 組件的混合。

四個並排的行動裝置屏幕,共同展示了選擇和注釋檔案的使用者流程

更籠統地說,典型的 Flutter Plugin 設計看起來像下面這樣,其中一個單一的、簡化的介面載入平台特定的函式庫,這些函式庫反過來又使用 FFI 或 JNI 與底層平台進行通信。這允許 Flutter 應用程式與所有構建目標的平台特定原生 API 互動,而不會將這些考慮因素洩露到 Dart 程式碼中。

Flutter Plugin 設計圖

回顧

開發速度

Classroom 團隊花費了兩年的時間來使用一個團隊重寫他們的應用程式,這個團隊從 1 名工程師(用於最初的原型設計階段)到開發高峰期的 10 名全職工程師不等。這不是一筆小投入,但團隊基於更快開發和維護的承諾做出了這個決定。Classroom 於 2023 年 6 月在 iOS 上推出了他們的 Flutter 重寫版本,並於 2024 年 1 月在 Android 上推出該專案。此後,用於新功能的平均工程師時間減少了三分之二,這意味著開發速度提高了三倍!在等了兩年之後,利益相關者對期待已久的 ✨更快功能開發✨ 感到非常高興。

Classroom 團隊決定重寫的部分原因是,他們知道他們的專案永遠不會「完成」,新的功能很可能會在很長一段時間內不斷添加。這為一個有說服力的案例提供了支持,即重寫,即使是一項昂貴的重寫,最終也會得到回報。Classroom 團隊計算他們使用 Flutter 重寫應用程式後何時才能實現投資回報的公式是:

估算使用 Flutter 重寫應用程式後,提高的速度何時會超過重寫時間的公式。公式為重寫時間除以使用 Flutter 編寫功能所需時間的減少量,等於達到盈虧平衡點的發佈後功能數量。

在 iOS 推出 9 個月後,Classroom 估計已經通過 Flutter 提供的開發速度提高三倍,從而收回了最初投資的 40%。

開發人員體驗

除了利益相關者之外,唯一比開發速度提高更讓 開發人員自己 高興的是 - 開發人員自己。對於 Classroom 團隊來說,他們 3 倍的速度增長來自於僅需編寫一次每個功能(或者至少 1.5 次,在具有大量原生組件的情況下),消除了協調兩個團隊的成本,而這兩個團隊的時間表通常相差數月,當然還有熱重載。熱重載本身及其大約 99% 的重建時間減少,讓 Classroom 團隊的士氣比他們使用兩個原生客戶端時更高。最終,Classroom 團隊發現,在他們轉向 Flutter 之後,很容易吸引和留住工程師。

此外,Classroom 團隊發現,平均來說,新的功能需要減少至少 50% 的程式碼行數才能實現。實際上,減少量可能要高得多,因為他們在重寫過程中建立的每個功能在兩個原生客戶端中都沒有真正實現!換句話說,50% 的程式碼行數實現了所有舊的功能,還覆蓋了 大量 功能缺口(包括 iOS 上的離線支援)。

總結

在開始重寫大約兩年後,Classroom 團隊將他們的應用程式發佈到 Android 和 iOS,並添加了足夠的額外功能,以償還他們前期投資的 40%。他們的全新應用程式啟動速度是舊版本啟動速度的 五倍,為開發人員和最終使用者節省了時間和挫折。展望未來,新的功能平均開發成本是舊狀況的 三分之一,可以在兩個平台上同時發佈,並且 更容易 除錯和維護。最終,在 Classroom 切換到 Flutter 以重新投資他們的 未來 後,使用者、開發人員和利益相關者的士氣達到了前所未有的高度。


使用 Flutter 開發跨平台應用程式 - Google Classroom 如何讓教師和學生步調一致 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

優化 Flutter Web 載入速度的最佳實務

身為一名與 Google Flutter 團隊合作,並在私人時間進行個人專案的 Flutter 開發人員,我遇到並理解了關於 Flutter Web 應用程式載入速度的擔憂。優化載入速度對於提升效能和提供良好的使用者體驗至關重要,尤其是在 Flutter 開發人員擴展到 Web 開發時。本指南提供可執行的策略和最佳實務,以加速 Flutter Web 應用程式的效能。

渲染

CanvasKit 是 Flutter Web 應用程式的預設 渲染器,它透過利用 WebGL 在平台間提供高效能和像素完美的一致性。這種功能對於需要豐富動畫和高保真度的複雜圖形應用程式特別有用。然而,CanvasKit 的內建檔案大小(約 1.5 MB)可能是一個缺點,特別是在初始載入時間至關重要的應用程式中。

儘管 flutter.js 載入 API 可並行下載 CanvasKit 和 main.dart.js,但所有 Flutter Widget 都必須等到它們完全載入到瀏覽器中,這可能會在應用程式變得互動之前導致明顯的延遲。為了減輕這些問題並優化載入體驗,開發人員可以選擇 Wasm 渲染模式。

由於 Flutter Web 中的 WebAssembly 支援 被視為實驗性並且可能會發生變化,因此這些步驟適用於願意嘗試尖端功能的開發人員。功能和指令可能會演變,因此請務必參閱最新的 Flutter 文件以瞭解目前的實務。

相容性

當使用 Wasm 進行構建時,dart:html 套件不受支援。此限制意味著您必須仔細考慮您的應用程式相依的 API。或者,web 套件dart2wasmdart2js 支援。

效能

Wasm 不僅與 CanvasKit 相比減少了應用程式大小,而且與 JavaScript 相比,啟動速度也更快。

延遲載入

Dart 的 延遲載入函式庫 允許您分割程式碼,並且只在需要時載入部分程式碼,從而減少初始載入時間。以下部分將討論如何使用延遲載入。

宣告延遲載入

在 Dart 檔案的頂部,宣告您要延遲載入的載入。在載入陳述式中,指定 deferred,後面接著識別符號。當您需要使用函式庫時,請使用延遲載入的 loadLibrary() 方法非同步載入它:

1
2
3
4
5
6
import 'package:myapp/hello.dart' deferred as hello;

Future<void> loadHelloLibrary() async {
await hello.loadLibrary();
hello.sayHi();
}

呼叫載入函數

在您的 Flutter 應用程式中,根據需要呼叫此函數,例如,作為對使用者互動的回應。以下範例在使用者按下 Widget 時載入所需的函式庫:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import 'package:flutter/material.dart';

void main() {
runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {
loadHelloLibrary();
},
child: Text('Load Feature'),
),
),
);
}
}

未等待的函數呼叫

為了減少顯示應用程式初始 Widget 所花費的時間,請嘗試在呼叫 runApp 之前不要等待代價高昂的 Future。可以將一些 Future 設為未等待,以便它們在完成後更新 UI。unawaited 函數 允許應用程式程式設計師明確告知「未等待的 Future」提示,這些 Future 不會等待。此改進透過讓應用程式感覺更具回應性,在應用程式啟動和頁面載入期間都增強了使用者體驗。但是,必須小心管理這些函數,以避免與應用程式狀態一致性和資源管理相關的問題。

1
2
3
4
5
6
7
8
9
10
import 'dart:async';
import 'package:flutter/material.dart';

void main() {
unawaited(downloadVideos().then((videos) {
playlist.add(videos);
}));

runApp(const MyApp());
}

媒體檔案

以最佳解析度顯示資產

Flutter 會自動根據設備的像素密度 以適當的解析度載入資產。這可確保在不同螢幕尺寸上顯示最佳視覺效果。雖然優化資產以進行有效傳遞很重要,但請優先考慮在探索替代圖片格式之前提供所需精確解析度的資產,就像我們在下一節中將討論的那樣。

更好的圖片壓縮

PNG 和 JPG 是網站上使用最普遍的圖片格式。這些格式以其廣泛的支援和相容性而聞名。然而,新一代格式(如 WebPAVIF)在減少檔案大小方面取得了重大進展,而不會顯著降低圖片品質。例如,原始大小為 319 KB 的 PNG 圖片可以用 WebP 格式壓縮到僅 38 KB,或者更令人印象深刻的是,可以用 AVIF 格式壓縮到 10 KB。這些檔案大小的縮減是透過肉眼幾乎無法察覺的品質損失來實現的,這證明了這些格式在保持視覺保真度的同時,提升網站載入速度的潛力。

PNG 319 KB / WebP 38 KB / AVIF 10 KB

然而,重要的是要注意,並非所有瀏覽器都支援 WebPAVIF 圖片。在將這些格式整合到您的網站之前,請驗證它們與您的觀眾最常使用的瀏覽器的相容性。這將幫助您確定這些新一代圖片格式是否符合您的網站要求和觀眾需求。

快取

記憶體、磁碟、Service Worker 快取

利用記憶體快取、磁碟快取和 Service Worker 的功能可以顯著減少初始頁面載入後的載入時間。這是因為這些快取機制需要檔案先載入一次,然後才能快取它們。記憶體快取儲存在 RAM 中,提供快速的存取速度,但易失性。另一方面,磁碟快取雖然速度較慢,但提供持久性。Service Worker 作為可程式化的網路代理,可以跨記憶體和磁碟實現複雜的快取策略。

瀏覽器或作業系統通常會自動管理記憶體和磁碟快取,除非有特定的要求需要以程式方式操作它們,否則不需要手動干預。雖然 Flutter 在一定程度上管理 Service Worker,但開發人員可以靈活地在 Flutter 之外實作自訂 Service Worker,以增強對快取和網路互動的控制。

Wasm

瀏覽器會快取 Wasm 檔案(如 CanvasKit,以及很快的 dart2wasm 輸出),以及它們的編譯原生程式碼。這意味著快取的 Wasm 模組載入速度與原生二進制檔案一樣快,與 JavaScript 不同,JavaScript 需要重新解析、重新編譯和重新 JIT(Just-In-Time)處理。

雖然 Flutter 的 Wasm 構建選項尚未完全穩定,但當 dart2wasm 穩定後,採用現代 JS-interop 實務會使您受益。例如,避免使用 dart:htmldart:js 等傳統函式庫,並優先考慮 package:webdart:js_interop。此外,請考慮檢查您正在使用的其他套件是否與 Wasm 相容。

預載入

HTML <head> 標籤、HTTP 響應標頭

預載入資產(如圖片、字體和 JavaScript 檔案)可以顯著提高網頁載入速度。透過在 HTML <head> 標籤中預載入或使用 HTTP 響應標頭,您可以指示瀏覽器在需要用於渲染之前下載這些資源。這樣可以消除延遲,並確保更順暢的使用者體驗。若要預載入資產,請在 <head> 部分添加 <link> 標籤,並將 rel 屬性設定為 preload。僅預載入立即使用的資產,最優化的是應用程式的第一個螢幕,否則瀏覽器會將預載入視為浪費頻寬。

HTML <head> 標籤

1
2
3
4
5
6
7
8
<head>
<link rel="preload" href="assets/logo.webp" as="image" type="image/webp" />
</head>
<body>
<picture>
<source src="assets/logo.webp" type="image/webp" />
</picture>
</body>

Firebase 托管的 HTTP 響應標頭

以下程式碼塊是一個 firebase.json 範例,其中包含一個鍵/值組合,展示如何為資產預載入添加 HTTP 標頭。

1
2
3
4
5
6
"headers": [
{
"key": "Link",
"value": "<assets/logo.webp>; rel=preload; as=image"
}
]

登陸頁面

Flutter 使您能夠使用純粹的 HTML/CSS 為您的應用程式構建完全互動式的登陸頁面。當使用者與您的登陸頁面互動時,flutter.js 會預載入您的 Flutter 應用程式 - 確保使用者導航到 Flutter 應用程式時立即啟動。這對於具有 播放 按鈕的遊戲和需要登入的應用程式特別有用。

載入/啟動畫面

雖然我們一直關注應用程式載入速度的技術優化,但感知載入速度更為關鍵。您的目標應該是讓您的應用程式 感覺很快

載入/啟動畫面在增強這種感知方面非常有效。透過提供視覺活動,它們向使用者保證應用程式正在迅速啟動。相反,空白螢幕會引起不確定性,可能會導致沮喪和頁面重新整理。

為了實現最快的回應能力,請使用純粹的 CSS/HTML 在您的 index.html 檔案中直接實作啟動畫面。這可以最大限度地減少任何潛在的延遲。

例如,請查看 Flutter Gallery 實作

結語

在本文件中,我們探討了加速 Flutter Web 應用程式初始載入和渲染效能的方法。您可以採用多種策略,但請記住,每個解決方案都涉及權衡取捨。選擇最適合您的特定需求和使用者需求的優化。透過結合這些方法، 您可以為您的 Flutter Web 應用程式創造更流暢、更具回應性的使用者體驗。


優化 Flutter Web 載入速度的最佳實務 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。