隨著 Flutter 3.10 發(fā)布,F(xiàn)lutter Web 也引來(lái)了它最具有「里程碑」意義的更新,這里的「里程碑」不是說(shuō)這次 Flutter Web 有多么重大的更新,而是 Flutter 官方對(duì)于 Web 終于有了明確的定位和方向。
提升
首先我們簡(jiǎn)單聊提升,這不是本篇的重點(diǎn),只是順帶。
本次提升主要在于兩個(gè)大點(diǎn):**Element 嵌入支持和 fragment shaders 支持 **。
首先是 Element 嵌入,Flutter 3.10 開始,現(xiàn)在可以將 Flutter Web嵌入到網(wǎng)頁(yè)的任何 HTML 元素中,并帶有 flutter.js
引擎和 hostElement
初始化參數(shù)。
簡(jiǎn)單來(lái)說(shuō)就是不需要 iframe
了,如下代碼所示,只需要通過(guò) initializeEngine
的 hostElement
參數(shù)就可以指定嵌入的元素,靈活度支持得到了提高。
<html>
<head>
<!-- ... -->
<script src="flutter.js" defer></script>
</head>
<body>
<!-- Ensure your flutter target is present on the page... -->
<div id="flutter_host">Loading...</div>
<script>
window.addEventListener("load", function (ev) {
_flutter.loader.loadEntrypoint({
onEntrypointLoaded: async function(engineInitializer) {
let appRunner = await engineInitializer.initializeEngine({
// Pass a reference to "div#flutter_host" into the Flutter engine.
hostElement: document.querySelector("#flutter_host")
});
await appRunner.runApp();
}
});
});
</script>
</body>
</html>
PS :如果你的項(xiàng)目是在 Flutter 2.10 或更早版本中創(chuàng)建的,要先從目錄中刪除
/web
文件 ,然后通過(guò)flutter create . --platforms=web
重新創(chuàng)建模版。
fragment shaders 部分一般情況下大家可能并不會(huì)用到,shaders 就是以 .frag
擴(kuò)展名出現(xiàn)的 GLSL 文件,在 Flutter 里是在 pubspec.yaml
文件下的 shaders
中聲明,現(xiàn)在它支持 Web 了:
flutter:
shaders:
- shaders/myshader.frag
一般運(yùn)行時(shí)會(huì)把 frag 文件加載到
FragmentProgram
對(duì)象中,通過(guò) program 可以獲取到對(duì)應(yīng)的shader
,然后通過(guò)Paint.shader
進(jìn)行使用繪制, 當(dāng)然 Flutter 里 shaders 文件是存在限制的,比如不支持 UBO 和 SSBO 等。
當(dāng)然,這里不是講解 shaders ,而是宣告一下,F(xiàn)lutter Web 支持 shaders 了。
未來(lái)
其實(shí)未來(lái)才是本篇的重點(diǎn),我們知道 Flutter 在 Web 領(lǐng)域的支持上一直在「妥協(xié)」,F(xiàn)lutter Web 在整個(gè) Flutter 體系下一直處于比較特殊的位置,因?yàn)樗恢贝嬖趦煞N渲染方式:html 和 canvaskit。
簡(jiǎn)單說(shuō) html 就是轉(zhuǎn)化為 JS + Html Element 渲染,而 canvaskit 是采用 Skia + WebAssembly 的方式,而 html 的模式讓 Web 在 Flutter 中顯得「格格不入」,路徑依賴和維護(hù)成本也一直是 Flutter Web 的頭痛問(wèn)題。
面對(duì)這個(gè)困境,官方在年初的 Flutter Forword 大會(huì)上提出重新規(guī)劃 Flutter Web 的未來(lái),而隨著 Flutter 3.10 的發(fā)布,官方終于對(duì)于 Web 的未來(lái)有了明確的定位:
“Flutter 是第一個(gè)圍繞 CanvasKit 和 WebAssembly 等新興 Web 技術(shù)進(jìn)行架構(gòu)設(shè)計(jì)的框架?!?/strong>
Flutter 團(tuán)隊(duì)表示,Flutter Web 的定位不是設(shè)計(jì)為通用 Web 的框架,類似的 Web 框架現(xiàn)在有很多,比如 Angular 和 React 等在這個(gè)領(lǐng)域表現(xiàn)就很出色,而 Flutter 應(yīng)該是圍繞 CanvasKit 和 WebAssembly 等新技術(shù)進(jìn)行架構(gòu)設(shè)計(jì)的框架。
所以 Flutter Web 未來(lái)的路線更多會(huì)是 CanvasKit ,也就是 WebAssembly + Skia ,同時(shí)在這個(gè)領(lǐng)域 Dart 也在持續(xù)深耕:從 Dart 3 開始,對(duì)于 Web 的支持將逐步演進(jìn)為 WebAssembly 的 Dart native 的定位。
什么是 WebAssembly 的 dart native ?一直以來(lái) Flutter 對(duì)于 WebAssembly 的支持都是:使用 Wasm 來(lái)處理CanvasKit 的 runtime,而 Dart 代碼會(huì)被編譯為 JS,而這對(duì)于 Dart 團(tuán)隊(duì)來(lái)時(shí),其實(shí)是一個(gè)「妥協(xié)」的過(guò)渡期。
而隨著官方與 WebAssembly 生態(tài)系統(tǒng)中的多個(gè)團(tuán)隊(duì)的深入合作,Dart 已經(jīng)開始支持直接編譯為原生的 wasm 代碼,一個(gè)叫 WasmGC 的垃圾收集實(shí)現(xiàn)被引入標(biāo)準(zhǔn),該擴(kuò)展實(shí)現(xiàn)目前在基于 Chromium 的瀏覽器和 Firefox 瀏覽器中在趨向穩(wěn)定。
目前在基準(zhǔn)測(cè)試中,執(zhí)行速度提高了 3 倍
要將 Dart 和 Flutter 編譯成 Wasm,你需要一個(gè)支持 WasmGC 的瀏覽器,目前 Chromium V8 和 Firefox 團(tuán)隊(duì)的瀏覽器都在進(jìn)行支持,比如 Chromium 下:
通過(guò)結(jié)構(gòu)和數(shù)組類型為 WebAssembly 增加了對(duì)高級(jí)語(yǔ)言的有效支持,以 Wasm 為 target 的語(yǔ)言編譯器能夠與主機(jī) VM 中的垃圾收集器集成。在 Chrome 中啟用該功能意味著啟用類型化函數(shù)引用,它會(huì)將函數(shù)引用存儲(chǔ)在上述結(jié)構(gòu)和數(shù)組中。
現(xiàn)在在 Flutter master 分支下就可以提前嘗試 wasm 的支持,運(yùn)行 flutter build web --help
如果出現(xiàn)下圖所示場(chǎng), 說(shuō)明支持 wasm 編譯。
之后執(zhí)行 flutter build web --wasm
就可以編譯一個(gè)帶有 native dart wasm 的 web 包,命令執(zhí)行后,會(huì)將產(chǎn)物輸出到 build/web_wasm
目錄下。
之后你可以使用 pub 上的 dhttpd
包在 build/web_wasm
目錄下執(zhí)行本地服務(wù),然后在瀏覽器預(yù)覽效果。
> cd build/web_wasm
> dhttpd
Server started on port 8080
目前需要版本 112 或更高版本的 Chromium 才能支持,同時(shí)需要啟動(dòng)對(duì)應(yīng)的 Chrome 標(biāo)識(shí)位:
enable-experimental-webassembly-stack-switching
enable-webassembly-garbage-collection
當(dāng)然,目前階段還存在一些限制,例如:
Dart Wasm 編譯器利用了 JavaScript-Promise Integration (JSPI) 特性,F(xiàn)irefox 不支持 JSPI 提議,所以一旦 Dart 從 JSPI 遷移出來(lái),F(xiàn)irefox 應(yīng)啟用適當(dāng)?shù)臉?biāo)志位才能運(yùn)行。
另外還需要 JS-interop 支持,因?yàn)闉榱酥С?Wasm,Dart 改變了它針對(duì)瀏覽器和 JavaScript 的 API 支持方式, 這種轉(zhuǎn)變是為了防止把 dart:html
或 package:js
編譯為 Wasm 的 Dart 代碼,大多數(shù)特定于平臺(tái)的包如 url_launcher 會(huì)使用這些庫(kù)。
最后,目前 DevTools 還不支持 flutter run
去運(yùn)行和調(diào)試 Wasm。
最后
很高興能看到 Flutter 團(tuán)隊(duì)最終去定了 Web 的未來(lái)路線,這讓 Web 的未來(lái)更加明朗,當(dāng)然,正如前面所說(shuō)的,Flutter 是第一個(gè)圍繞 CanvasKit 和 WebAssembly 等新興 Web 技術(shù)進(jìn)行架構(gòu)設(shè)計(jì)的框架。
所以 Flutter Web不是為了設(shè)計(jì)為通用 Web 的框架去 Angular 和 React 等競(jìng)爭(zhēng),它是讓你在使用 Flutter 的時(shí)候,可以將能力很好地釋放到 Web 領(lǐng)域,而 CanvasKit 帶來(lái)的一致性更符合 Flutter Web 的定位,當(dāng)然,解決加載時(shí)長(zhǎng)問(wèn)題會(huì)是任重道遠(yuǎn)的需求。
最后不得不提 WebGPU, WebGPU 作為新一代的 WebGL,可以提供在瀏覽器繪制 3D 的全新實(shí)現(xiàn),它屬于 GPU硬件(顯卡)向 Web(瀏覽器)開放的低級(jí) API,包括圖形和計(jì)算兩方面相關(guān)接口。
WebGPU 來(lái)自 W3C 制定的標(biāo)準(zhǔn),與 WebGL 不同,WebGPU 不是基于 OpenGL ,它是一個(gè)新的全新標(biāo)準(zhǔn),發(fā)起者是蘋果,目前由 W3C GPU 與來(lái)自蘋果、Mozilla、微軟和谷歌一起制定開發(fā),不同于 WebGL (OpenGL ES Web 版本),WebGPU 是基于 Vulkan、Metal 和 Direct3D 12 等,能提供更好的性能和多線程支持。
WebGPU 已經(jīng)被正式集成到 Chrome 113 中,首個(gè)版本可在會(huì)支持 Vulkan 的 ChromeOS 設(shè)備、 Direct3D 12 的 Windows 設(shè)備和 macOS 的 Chrome 113 瀏覽器,除此之外 Linux、Android 也將在 2023 年內(nèi)開始陸續(xù)發(fā)布,同步目前也初步登陸了 Firefox 和 Safari 。
提及 WebGPU 的原因在于:WebGPU + WebAssembly 是否在未來(lái)可以讓 Web 也支持 Impeller 的可能?。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-449823.html
詳細(xì)可見(jiàn):https://cohost.org/mcc/post/1406157-i-want-to-talk-about-webgpu 和 https://www.infoq.cn/article/qwawharqawdragtcoxqv文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-449823.html
到了這里,關(guān)于Flutter 3.10 之 Flutter Web 路線已定,可用性進(jìn)一步提升,快來(lái)嘗鮮 WasmGC的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!