首先感謝@棲冰 @祖建國 一塊兒對FFW的預研作的投入!css
Google在最新的Google I/O上推出了Flutter for Web,旨在進一步解決一次代碼,多端運行的問題。Flutter for Web還處於早期試驗版,官方不建議在生產環境上使用。那麼到底它的實際狀況怎麼樣呢? 咱們作了一次預研。指望此次預研的結果能夠幫你決定是用,仍是不用FFW。html
Flutter for Web和Flutter在上層都是Dart環境,二者不一樣的是,Flutter的Dart代碼運行在Dart虛擬機中,界面由Flutter引擎處理,經過Skia繪圖引擎經由GPU繪製到屏幕上。而Flutter for Web的Dart代碼編譯成JavaScript,界面上部分轉換成標準的html標籤,部分轉換成經過Canvas繪製的自定義標籤,最終構成一個dom樹。
這個原理上的差別很是重要,這直接可讓咱們經過原理得出下面的結論:前端
若是Flutter for Web追求(和Flutter)完美的一致性,勢必須要大量使用Canvas去繪製,而Canvas去繪製組件的性能(尤爲在移動端)至少不會比html標籤好。若是FFW追求性能極限而使用大量標準的html標籤,這就會帶來和Weex、RN等同樣的一致性問題:對於Flutter全部的控件都是一套代碼在繪圖引擎上繪製,對Flutter for Web若是要使用大量html標籤,那如何保證一致性呢?只能靠大量精細的打磨工做了。因此FFW必需要處理好這個平衡。android
爲啥使用canvas繪製性能不優於手寫html呢,定性的從幾個角度分析:ios
- FFW在canvas上繪製的組件帶有不少MD特點的視覺和動畫,好比陰影、Z軸變化等,這部分對性能的消耗要大於普通html標籤
- FFW是經過Dart的DSL轉成的dom樹結構,轉化後的dom樹十分複雜,不太可能比手寫的dom樹更簡潔
- 使用canvas的控件,其手勢事件的捕獲分發都是靠FFW框架本身實現的,emmmm
雖然不排除Google大力出奇跡的狀況,可是無論怎樣,相同素質的開發人員,相同的界面,性能上也不可能優於html+css+js
另一點,若是FFW在原理上涉及大量HTML標籤的轉化,那就勢必會涉及到碎片化的處理中,瀏覽器的碎片化程度可一點都不比Android系統的碎片化小。像Flutter自己之因此被那麼多人看重,就是由於其經過繪圖引擎這一層,完美的避開了碎片化,保證一致性。
因此最好的平衡就是,只有有限的一部分標準的html標籤能夠被FFW複用,其必須有幾點性質:nginx
<p>
、<div>
這種了Flutter官方就是這麼作的,因此個人結論是:
一致性上大致不會存在問題,性能上,FFW應該不會優於純手寫html標籤界面。git
根據官網和Github repo上的說法,咱們整理了一下:github
Flutter for Web和Flutter目前暫時是兩個倉庫,官方正在進行合併,沒有給出結論。這一點在工程上很是重要,它說明了幾個問題:web
對於這麼新的東西,官網上的內容的確很少,並且簡單來看這些問題好像也沒什麼,因此對於到底能不能用,咱們仍是須要抱着吃螃蟹的心態具體進去預研一下,爲了儘快弄清,我計劃找一個咱們app已經作好的flutter頁面,把它遷移成FFW,對整個遷移過程作個評估,再看下頁面效果,基本上就能得出結論了。
具體的遷移細節就不提了,官網也有遷移文檔,大致上就是這麼幾個步驟chrome
Platform.isAndroid
等等實踐的主要目的,有如下幾個:
刪了一萬行代碼跑成功以後,最終在工程、開發體驗、用戶體驗上獲得一些結論,如下的結論中,體驗部分是我在個人mix2s上的感覺:
支持debug和release模式,後者比前者性能高(差別很明顯)。
webdev build
命令編譯出index.html+js,能夠經過nginx作反向代理。main.dart.js
大小約爲500k左右,sample中的gallery大小約爲2M,閹割版的純展現用的訂單列表大小約爲1.3M。gzip對文本的壓縮率通常是80%,壓縮後也要動輒幾百k的大小。並且main.dart.js
不加載完,界面是不會展現的。很是重要flutter for web使用flutter_web庫,且不支持其餘許多插件,這會帶來幾個問題
調試困難
Platform.isAndroid
所有報錯,針對Android和iOS作差別化展現目前還不知道有沒有其餘方法能夠作到。NetworkImage
能夠直接用,可是如今來看有些糊,不肯定是官方控件的問題,仍是咱們作的cdn url策略有問題。Dart和Js語言自己的差別會帶來測試和兼容成本的增長,雖然Dart能夠編譯成Js,可是跑在DartVM上的Dart的表現,和其編譯成Js運行在瀏覽器中的表現並不徹底相同。好比對於以下代碼
Map<String, String> query = null; val b = query["abc"];
在DartVM中該代碼能夠執行,結果是b=null
;可是編譯成Js之後運行時由於query爲null,會報空指針。
使用了chrome、uc、小米自帶瀏覽器分別試了一下訂單列表和官方的sample-gallery界面,體驗以下:
main.dart.js
和部分資源文件(好比MaterialIcons
)沒有加載出來的時候,界面不會展現。
iOS的safari和chrome訪問demo頁,TextField整個不可用,包括如下問題:
按照上面的,總體總結一下,Flutter for Web有幾個比較嚴重的問題,不解決的話估計是沒法應用到生產環境上的:
包大小問題,這會帶來幾個問題:
SDK分離的問題,這也會帶來幾個問題:
本節的主要目的是列出假設要作FFW,咱們須要作的技術項和對應方案。
本文爲雲棲社區原創內容,未經容許不得轉載。