Flutter Web 的發展歷程:Dart、Flutter 與 WasmGC

Flutter Web 應該是 Flutter 開發者里最不“受寵”的平臺了,但是其實 Flutter 和 Dart 團隊對于 Web 的投入一直沒有減少,這也和 Flutter 還有 Dart 的"出生"有關系,今天就借著 Dart 團隊的 ?mer A?acan 和 Martin Kustermann 在油管的訪談視頻來聊一聊 Flutter Web 這一路過來的變化。

其實在以前我們聊過很多次,Flutter 早期的項目代號是 “Sky” ,誕生于 Google 內部的 Chrome 團隊,早期定位其實是一個「前端項目」,本身是為了探索更優秀的 Web 渲染技術而存在,所以起初 Flutter 的創始人和整個團隊幾乎都是來自 Web :

Dart 最初的宏大愿景是在 Chrome 的 V8 引擎中內置一個專門的 Dart 虛擬機(VM) ,目的是為 Web 提供一個比 JavaScript 更結構化、性能更強的替代方案。

當然,眾所周知這個計劃最終涼了,而后 Dart 團隊將戰略重心轉向了 dart2js 編譯器,也就是將 Dart 代碼轉譯為 JavaScript,這也是一開始的 Flutter Web 打下來基礎。

所以 Flutter 選擇 Dart 其中一個原因不難理解,大家都是同一個團隊內的,并且 Dart 沒什么其他選擇,它也可以一心一意成為 Flutter 的形狀

當然,另外一個原因則是 Flutter 當時希望有一種語言同時支持 JIT 和 AOT,并且支持 Hotload ,而 Dart 恰好具備這兩種編譯模式的基礎能力。

所以,對于 Dart 來說,它的演進路徑其實可以說是“一路坎坷”,從 “Dart VM in V8” 的失敗,再到 dart2js 的“茍活”,再到后面 Flutter Web 的落地,以及之后的 WasmGC 提案,再到現在的 dart2wasm ,其實 Dart 一直心系 Web 平臺,因為這是它曾經目標的延續。

而對于 Flutter 來說, dart2js 將 Flutter 轉譯為 JavaScript 的實現,讓 Flutter 在 Web 平臺變得“不那么一致”,特別是在處理復雜動畫和大量 UI 元素時會遇到性能瓶頸,此時的 Web 平臺的特殊性也成了 Flutter 的技術債務。

所以 WebAssembly (Wasm) 平臺最終成了 Flutter Web 的新目標,它能夠讓 Flutter 在 Web 平臺和其他平臺上渲染效果對齊,并且還能提供不錯的性能,只是 Wasm 的初始版本(CanvasKit)缺少垃圾回收(GC)機制,不適合像 Dart 這樣的托管語言:

Wasm MVP 只提供了一個單一的、連續的內存塊,Wasm 模塊必須手動管理這塊內存,包括對象的分配和釋放;并且沒有 GC 支持,也就是其他語言必須將它們自己的整個垃圾回收器實現打包進 Wasm 模塊,這不僅降低了效率,還極大地增加了代碼體積。

最經典的問題是,這會導致在一個進程中同時運行兩個 GC 的尷尬局面:一個是打包在 Wasm 模塊內的 GC,另一個是瀏覽器用于管理 JavaScript 對象的 GC

所以早期 CanvasKit 在 Flutter Web 里并沒有什么優勢,大家還是更愿意基于 dart2js ,這也導致了 Flutter Web 一直處于兩種模式的尷尬局面。

因此 ,Dart 和 Flutter 團隊開始加入 WasmGC 的推動與落地工作,其實這是一項吃力不討好的過程,Google 從一開始就深度參與了標準的制定,好處就是確保了這個標準能盡可能滿足 Dart 的需求。

當然,最終受惠的還有 Kotlin/Wasm ,JetBrains 也率先基于 WasmGC 開發了全新的 Kotlin/Wasm 編譯器驗證了相對應的可行性,也是早期的積極實踐者之一。

WasmGC 從根本上將 WebAssembly 從一個“Web 上的更好的 C++ 平臺”轉變為一個“通用的高級語言虛擬機”,而 WasmGC 提案也為 WebAssembly 引入了一系列新的功能:

  • WasmGC 引入了新的堆類型,用于創建結構化數據(struct)和數組(array),讓虛擬機能夠了解它們的內存布局,從而高效地訪問字段,減少復雜的地址計算
  • WasmGC 為托管對象定義了一個類型系統,包含了子類型化(sub)的概念,也就是 Wasm 代碼能夠表示源語言中的類繼承關系,編譯器可以將語言的類型層次結構直接映射到 Wasm 的類型系統上
  • WasmGC 引入了一套新指令,例如用于創建實例的 struct.newarray.new,用于字段訪問的 struct.getstruct.set,以及用于類型轉換和檢查的指令,如 ref.cast(類型轉換)和 br_on_cast(帶類型檢查的分支)

編譯器不再是將語言的對象模型編譯到線性內存中,而是將語言的對象模型映射到 WasmGC 的對象模型上 ,而 WasmGC 相較于傳統的將 GC 捆綁到 Wasm 模塊中的方法,主要好處在于:

  • 代碼體積的急劇減小,由于不再需要捆綁內存管理代碼(無論是 malloc 還是一個完整的 GC),最終的 Wasm 二進制文件可以小得多
  • WasmGC 實現了 Wasm 和 JavaScript 之間真正細粒度的對象互操作,一個 WasmGC 對象可以持有對一個 JavaScript 對象的引用,反之也是,這讓宿主的 GC 能夠正確地追蹤和回收跨越這兩個環境的循環引用
  • 由于虛擬機了解 Wasm 堆上的對象結構,瀏覽器開發者工具(如堆分析器)能夠檢查 Wasm 內存,并顯示有意義的對象類型和字段信息

所以,基于 WasmGC 推進的順路,Flutter 官方在 Flutter 3.10 終于對于 Web 的未來有了明確的定位:

“Flutter Web 是第一個圍繞 CanvasKit 和 WebAssembly 等新興 Web 技術進行架構設計的框架。”

Flutter 團隊表示,Flutter Web 的定位不是設計為通用 Web 的框架,類似的 Web 框架現在有很多,比如 Angular 和 React 等在這個領域表現就很出色,而 Flutter 應該是圍繞 CanvasKit 和 WebAssembly 等新技術進行架構設計的框架。

而對于 Dart,也從 Dart 3 開始,對于 Web 的支持將逐步演進為 WebAssembly 的 Dart native 的定位

什么是 WebAssembly 的 Dart native 現在應該很好理解了吧?一直以來 Flutter 對于 WebAssembly 的支持都是:使用 Wasm 來處理CanvasKit 的 runtime,而 Dart 代碼會被編譯為 JS,而這對于 Dart 團隊來時,其實是一個「妥協」的過渡期,而基于 WasmGC, Dart 已經開始支持直接編譯為原生的 Wasm 代碼

dart2js 切換到 dart2wasm 帶來了顯著的性能飛躍,例如 WasmGC 編譯的應用在幀渲染速度上平均提升了 2 倍,而在衡量卡頓情況的第 99 百分位幀上,性能提升高達 3 倍 ,另外 wasm 構建的 Flutter Web 應用還支持了使用多個線程場景,而 HTML renderer 也在 3.29 版本正式移除

skwasm 支持通過一個專用的 Web Worker 在獨立線程上進行渲染,可以將部分渲染工作負載分流,利用多核 CPU 來減少卡頓并提高響應性,前提是服務器必須配置特定的 COOP 和 COEP HTTP 標頭,從而滿足 SharedArrayBuffer 的安全要求 。

當然,WasmGC 目前還是存在瀏覽器兼容性問題,比如:

  • Chromium (Chrome, Edge): 從 119 版本穩定支持 WasmGC
  • Firefox: 盡管從 120 版本開始支持 WasmGC,但存在一些特定錯誤,某些情況可以會導致 Flutter 的 skwasm 渲染器無法正常工作
  • Safari/WebKit: 同樣已經支持 WasmGC,但也存在阻礙 Flutter 渲染的錯誤,特別是 iOS 上的 WebKit 兼容問題

目前 WebKit 已經默認支持了 WasmGC ,但是歷史版本依然存在需要兼容的場景:

而回歸到 Flutter Web 上,就是 canvaskitskwasm 有什么區別?簡單說:

  • canvaskit 使用 dart2js,兼容性更廣
  • skwasm 使用 dart2wasm ,性能更好體積更小,但是依賴 WasmGC 環境

所以,也許 Flutter Web 在開發者領域并不是很受寵,但是 Flutter 和 Dart 對它的投入并不少,因為 Wasm 的潛力已經遠遠超出了瀏覽器的范疇 ,例如 WASI(WebAssembly System Interface)就是未來的重要趨勢之一,作為新興的標準,它的目的是為 Wasm 模塊提供一種安全、可移植的方式來與系統資源(如文件系統)進行交互 。

WASI 的目標是定義一套標準的 API,讓 Wasm 代碼可以“一次編譯,在任何(支持 WASI 的)運行時上運行”,無論是服務器、邊緣設備還是桌面應用。

例如:

  • WASI 可以讓 WebAssembly 成為 Node.js 和 Python 等傳統服務器運行時的高性能替代品
  • 借助 WASI,Wasm 模塊將能夠和傳感器、本地文件系統交互來處理邊緣設備上的數據,從而實現邊緣的實時決策
  • WASI 的系統級功能能讓 WebAssembly 在傳統容器領域成為輕量級替代品

dart2wasm 編譯器目前是主要針對瀏覽器中的 JS 環境,但未來它也許可以被擴展以支持非 JS 的、符合 WASI 標準的運行時,例如 Wasmtime 或 Wasmer ,從而支持更多場景,這也是為什么 Flutter 和 Dart 對于 Wasm 持續投資的原因之一。

這也是訪談里 A?acan 和 Kustermann 未來愿景:在一個通用的、高性能的、可移植的運行時的驅動下,原生應用和 Web 應用之間的界限會更加模糊,盡管挑戰依然存在,但其發展軌跡已經為一類全新的 Web 體驗設定了方向。

而回歸的目前的 Flutter Web 和當前推進的情況,未來大概會有:

  • Flutter Web Hotload 的穩定版發布
  • 基于 Flutter Web 的 IDE 內 Widget Preview 穩定版
  • 基于語義樹實現 SEO 優化,例如 #145954 就提到過,通過將無障礙的 Semantics Tree 翻譯成 HTML 結構的管線,讓 Web 可以滿足搜索引擎爬蟲讀取的需求

雖然 Flutter Web 現在還不夠好用,不夠通用,但是它也確確實實撐起了 Flutter 在 Web 平臺的能力,對比起剛剛才合并到 master 的桌面端多窗口的情況,其實 Web 的投入在每個版本都有目共睹,未來 Flutter Web 應該也不會往通用領域發展,但是在 WebAssembly 領域,Flutter 和 Dart 應該還是可以有一席之地。

參考鏈接

  • https://www.youtube.com/watch?v=vgOABOvtBT8

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/914768.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/914768.shtml
英文地址,請注明出處:http://en.pswp.cn/news/914768.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c#方法關鍵字,ref、out、int

在 C# 中,ref、out 和 in 是用于方法參數傳遞的關鍵字,它們控制參數如何在方法和調用者之間傳遞數據。以下是對這三個關鍵字的詳細分析:1. ref 關鍵字(引用傳遞)作用允許方法修改調用者的變量:通過引用傳遞…

設計模式—初識設計模式

1.設計模式經典面試題分析幾個常見的設計模式對應的面試題。1.1原型設計模式1.使用UML類圖畫出原型模式核心角色(意思就是使用會考察使用UML畫出設計模式中關鍵角色和關系圖等)2.原型設計模式的深拷貝和淺拷貝是什么,寫出深拷貝的兩種方式的源…

深度學習-參數初始化、損失函數

A、參數初始化參數初始化對模型的訓練速度、收斂性以及最終的性能產生重要影響。它可以盡量避免梯度消失和梯度爆炸的情況。一、固定值初始化在神經網絡訓練開始時,將權重或偏置初始化為常數。但這種方法在實際操作中并不常見。1.1全零初始化將所有的權重參數初始化…

格密碼--Ring-SIS和Ring-LWE

1. 多項式環&#xff08;Polynomial Rings&#xff09; 設 f∈Z[x]f \in \mathbb{Z}[x]f∈Z[x] 是首一多項式&#xff08;最高次項系數為1&#xff09; 則環 RZ[x]/(f)R \mathbb{Z}[x]/(f)RZ[x]/(f) 元素為&#xff1a;所有次數 <deg?(f)< \deg(f)<deg(f) 的多項式…

前端工作需要和哪些人打交道?

前端工作中需要協作的角色及協作要點 前端工作中需要協作的角色及協作要點 前端開發處于產品實現的 “中間環節”,既要將設計方案轉化為可交互的界面,又要與后端對接數據,還需配合團隊推進項目進度。日常工作中,需要頻繁對接的角色包括以下幾類,每類協作都有其核心目標和…

萬字長文解析 OneCode3.0 AI創新設計

一、研究概述與背景 1.1 研究背景與意義 在 AI 技術重塑軟件開發的浪潮中&#xff0c;低代碼平臺正經歷從 “可視化編程” 到 “意圖驅動開發” 的根本性轉變。這種變革不僅提升了開發效率&#xff0c;更重新定義了人與系統的交互方式。作為國內領先的低代碼平臺&#xff0c;On…

重學前端006 --- 響應式網頁設計 CSS 彈性盒子

文章目錄盒模型一、盒模型的基本概念二、兩種盒模型的對比 舉例三、總結Flexbox 彈性盒子布局一、Flexbox 的核心概念??二、Flexbox 的基本語法????1. 定義 Flex 容器???2. Flex 容器的主要屬性????3. Flex 項目的主要屬性????三、Flexbox 的常見布局示例??…

rLLM:用于LLM Agent RL后訓練的創新框架

rLLM&#xff1a;用于LLM Agent RL后訓練的創新框架 本文介紹了rLLM&#xff0c;一個用于語言智能體后訓練的可擴展框架。它能讓用戶輕松構建自定義智能體與環境&#xff0c;通過強化學習進行訓練并部署。文中還展示了用其訓練的DeepSWE等智能體的出色表現&#xff0c;以及rLL…

rocky8 --Elasticsearch+Logstash+Filebeat+Kibana部署【7.1.1版本】

軟件說明&#xff1a; 所有軟件包下載地址&#xff1a;Past Releases of Elastic Stack Software | Elastic 打開頁面后選擇對應的組件及版本即可&#xff01; 所有軟件包名稱如下&#xff1a; 架構拓撲&#xff1a; 集群模式&#xff1a; 單機模式 架構規劃&#xff1a…

【JVM】內存分配與回收原則

在 Java 開發中&#xff0c;自動內存管理是 JVM 的核心能力之一&#xff0c;而內存分配與回收的策略直接影響程序的性能和穩定性。本文將詳細解析 JVM 的內存分配機制、對象回收規則以及背后的設計思想&#xff0c;幫助開發者更好地理解 JVM 的 "自動化" 內存管理邏輯…

Qt獲取hid設備信息

Qt 中通過 HID&#xff08;Human Interface Device&#xff09;接口獲取指定的 USB 設備&#xff0c;并讀取其數據。資源文件中包含了 hidapi.h、hidapi.dll 和 hidapi.lib。通過這些文件&#xff0c;您可以在 Qt 項目中實現對 USB 設備的 HID 接口調用。#include <QObject&…

Anaconda Jupyter 使用注意事項

Anaconda Jupyter 使用注意事項 1.將cell轉換為markdown。 First, select the cell you want to convertPress Esc to enter command mode (the cell border should turn blue)Press M to convert the cell to Markdown在編輯模式下按下ESC鍵&#xff0c;使單元塊&#xff08;c…

[硬件電路-20]:模擬信號處理運算與數字信號處理運算的相同點與不同點

模擬信號處理運算與數字信號處理運算是信號處理領域的兩大核心方法&#xff0c;二者在信號形式、處理機制、性能特點和應用場景上存在顯著差異&#xff0c;但也共享一些基礎目標與理論支撐。以下從多個維度進行系統對比分析&#xff1a;一、相同點1. 核心目標一致信號變換與分析…

Redis 高頻面試題

1. 緩存穿透 1.1 描述 用戶想要查詢某個數據,在 Redis 中查詢不到,即沒有緩存命中,這時就會直接訪問數據庫進行查詢。當請求量超出數據庫最大承載量時,就會導致數據庫崩潰。這種情況一般發生在非正常 URL 訪問,目的不是為了獲取數據,而是進行惡意攻擊。 1.2 現象 1、應…

OWASP Top 10 攻擊場景實戰

OWASP (開放式Web應用程序安全項目) Top 10 榜單是全球公認的、針對Web應用最關鍵安全風險的權威指南。它不是一份詳盡無遺的清單&#xff0c;而是一份凝聚了安全專家共識的“高危預警”。本文將不止于羅列這些風險&#xff0c;而是深入每個風險的核心&#xff0c;通過生動的比…

Three.js 實戰:使用 PBR 貼圖打造真實地面材質

在 Three.js 中&#xff0c;我們可以通過 MeshStandardMaterial 材質配合多張貼圖來實現真實的地面效果。這種方式模擬了物理世界中光照與表面材質的復雜交互&#xff0c;常用于構建高質量場景&#xff0c;如數字孿生、建筑可視化、游戲等。 本文將以一個完整示例為基礎&#x…

Java基礎的總結問題(第一篇)

JDK和JRE的區別&#xff1f;JRE是Java運行環境&#xff08;Java Runtime Environment&#xff09;&#xff0c;包含了JVM和Java核心類庫JDK是Java開發工具包&#xff08;Java Developers Kit&#xff09;,包含了JRE和Java常見的開發工具與equals的區別&#xff1f;可以用來比較…

[智能算法]MOEA/D算法的Python實現

一、初始化不同于NSGA-II&#xff0c;MOEA/D在進行迭代之前需要先進行初始化&#xff0c;初始化的主要內容是計算個體向量權重之間的歐氏距離&#xff0c;并得出其鄰域集合。# 計算T個鄰居 def cpt_W_Bi_T(moead):# 設置的鄰居個數錯誤(自己不能是自己的鄰居)if moead.T_size &…

Java設計模式之-組合模式

什么是組合模式&#xff1f; 組合模式允許你將對象組合成樹形結構來表示"部分-整體"的層次結構。它讓客戶端能夠以統一的方式處理單個對象和對象組合。 簡單來說&#xff0c;就像公司的組織結構&#xff1a; 公司有部門部門有小組小組有員工但無論是對公司、部門還是…

2021-10-29 C++與反轉數的和

緣由輸入一個三位數 與它倒過來的數相加&#xff0c;輸出和-編程語言-CSDN問答 直接寫 int n0,nn0,nnn0; cin>>n;nnn; while(nn)nnn*10,nnnnn%10,nn/10; cout<<nnnn<<endl; 緣由https://ask.csdn.net/questions/7552128 int 反轉數(int n) { int nn 0…