生活随笔
收集整理的這篇文章主要介紹了
Flutter for Web 详细预研
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
背景
Google在最新的Google I/O上推出了Flutter for Web,旨在進一步解決一次代碼,多端運行的問題。Flutter for Web還處于早期試驗版,官方不建議在生產(chǎn)環(huán)境上使用。那么到底它的實際情況怎么樣呢? 我們做了一次預研。期望這次預研的結果可以幫你決定是用,還是不用FFW。
Flutter for Web原理
Flutter for Web和Flutter在上層都是Dart環(huán)境,兩者不同的是,Flutter的Dart代碼運行在Dart虛擬機中,界面由Flutter引擎處理,通過Skia繪圖引擎經(jīng)由GPU繪制到屏幕上。而Flutter for Web的Dart代碼編譯成JavaScript,界面上部分轉換成標準的html標簽,部分轉換成通過Canvas繪制的自定義標簽,最終構成一個dom樹。 這個原理上的差異非常重要,這直接可以讓我們通過原理得出下面的結論:
Flutter for Web的一致性和體驗上存在矛盾
如果Flutter for Web追求(和Flutter)完美的一致性,勢必需要大量使用Canvas去繪制,而Canvas去繪制組件的性能(尤其在移動端)至少不會比html標簽好。如果FFW追求性能極限而使用大量標準的html標簽,這就會帶來和Weex、RN等一樣的一致性問題:對于Flutter所有的控件都是一套代碼在繪圖引擎上繪制,對Flutter for Web如果要使用大量html標簽,那如何保證一致性呢?只能靠大量精細的打磨工作了。所以FFW必須要處理好這個平衡。
為啥使用canvas繪制性能不優(yōu)于手寫html呢,定性的從幾個角度分析:
FFW在canvas上繪制的組件帶有很多MD特色的視覺和動畫,比如陰影、Z軸變化等,這部分對性能的消耗要大于普通html標簽 FFW是通過Dart的DSL轉成的dom樹結構,轉化后的dom樹十分復雜,不太可能比手寫的dom樹更簡潔 使用canvas的控件,其手勢事件的捕獲分發(fā)都是靠FFW框架自己實現(xiàn)的,emmmm 雖然不排除Google大力出奇跡的情況,但是不管怎樣,相同素質的開發(fā)人員,相同的界面,性能上也不可能優(yōu)于html+css+js
另外一點,如果FFW在原理上涉及大量HTML標簽的轉化,那就勢必會涉及到碎片化的處理中,瀏覽器的碎片化程度可一點都不比Android系統(tǒng)的碎片化小。像Flutter本身之所以被那么多人看重,就是因為其通過繪圖引擎這一層,完美的避開了碎片化,保證一致性。 所以最好的平衡就是,只有有限的一部分標準的html標簽可以被FFW復用,其必須有幾點性質:
標簽本身的功能簡單又直觀 最好不要有直接圖形化的展示,或者只負責簡單的圖形化展示(比如畫方形) 那幾個比較典型的標簽就是<p>、<div>這種了
Flutter官方就是這么做的,所以我的結論是: 一致性上大體不會存在問題,性能上,FFW應該不會優(yōu)于純手寫html標簽界面。
官方現(xiàn)狀&建議
根據(jù)官網(wǎng)和Github repo上的說法,我們整理了一下:
Flutter for Web和Flutter目前暫時是兩個倉庫,官方正在進行合并,沒有給出結論。這一點在工程上非常重要,它說明了幾個問題:
目前官方對FFW的成熟度沒有信心,同時FFW的迭代速度也很快。 目前FFW和Flutter最多保證API一樣,實現(xiàn)原理差異可能非常大,同時不保證所有控件都已經(jīng)在FFW上實現(xiàn)。 官方不建議應用在生產(chǎn)環(huán)境 目前插件能力十分有限,和系統(tǒng)交互的一些能力缺失,比如拍照等。 性能無法保證,運行會慢,可能會有掉幀 FFW中針對桌面的UI部分沒有完成(跟我無線有什么關系?) 開發(fā)中只能在Chrome中調(diào)試(又有什么關系?),release版是可以運行在任意瀏覽器中(除了IE,另支持的最低版本存疑)。
實踐
對于這么新的東西,官網(wǎng)上的內(nèi)容的確不多,而且簡單來看這些問題好像也沒什么,所以對于到底能不能用,我們還是需要抱著吃螃蟹的心態(tài)具體進去預研一下,為了盡快弄清,我計劃找一個我們app已經(jīng)做好的flutter頁面,把它遷移成FFW,對整個遷移過程做個評估,再看下頁面效果,基本上就能得出結論了。 具體的遷移細節(jié)就不提了,大體上就是這么幾個步驟
安裝Flutter for Web的工具webdev 改SDK依賴,新增Web文件夾(和之前存在的android、ios文件夾同級),新增一些其他文件(index.html, main.dart等)。 將所有flutter代碼中依賴的flutter包,改成flutter_web包 去掉所有不兼容的代碼,比如多語言、路由、Platform.isAndroid等等 編譯運行
實踐的主要目的,有以下幾個:
對整體坑的深度和廣度有個認知,方便推算出填坑成本 對FFW整體的性能和體驗有個把握,尤其是我們自己的頁面跑在FFW上是什么體驗。 對FFW和JS相互調(diào)用有具體的了解,如果可行,那復用集團已有能力(比如mtop)的坑就會小很多
刪了一萬行代碼跑成功之后,最終在工程、開發(fā)體驗、用戶體驗上得到一些結論,以下的結論中,體驗部分是我在我的mix2s上的感受:
工程
支持debug和release模式,后者比前者性能高(差異很明顯)。
debug模式支持代碼修改后自動重新編譯,和其他的前端框架(我只用過Django)一致 支持hotreload,暫時沒有嘗試 支持webdev build命令編譯出index.html+js,可以通過nginx做反向代理。 非常重要 ?編譯出來的代碼,gzip壓縮前,最簡單的helloworld的main.dart.js大小約為500k左右,sample中的gallery大小約為2M,閹割版的純展示用的訂單列表大小約為1.3M。gzip對文本的壓縮率一般是80%,壓縮后也要動輒幾百k的大小。而且main.dart.js不加載完,界面是不會展示的。
開發(fā)體驗
非常重要 flutter for web使用flutter_web庫,且不支持其他許多插件,這會帶來幾個問題
工程上無法優(yōu)雅的解決flutter和flutter_web共存的情況,最多搞個dart2的conditional import(這個特性可不在官方文檔中哦) 依賴flutter sdk的幾個庫,尤其是多語言庫無法應用在flutter_web上,并且Google肯定不會再單獨為flutter_web適配,而是在合并時做支持。這就意味著現(xiàn)階段所有依賴flutter sdk的庫不能被flutter_web使用。 調(diào)試困難
錯誤日志可以打印到瀏覽器的console中,但是try catch部分的堆棧不好拿 瀏覽器中的堆棧很復雜,但是基本上能找到出錯的dart代碼 目前沒有發(fā)現(xiàn)單步調(diào)試的能力 Platform.isAndroid全部報錯,針對Android和iOS做差異化展示目前還不知道有沒有其他方法可以做到。 目前沒有發(fā)現(xiàn)控件的api不一致的地方,不過有些控件的行為十分異常,比如下拉刷新,在Android手機上經(jīng)常卡死、失效。猜測重交互的一些控件都有可能存在類似的問題,但是測一遍的成本太高。 圖片控件NetworkImage可以直接用,但是現(xiàn)在來看有些糊,不確定是官方控件的問題,還是我們做的cdn url策略有問題。 dart代碼可以調(diào)用js,開發(fā)體驗和反射類似,并且需要處理JS類型和Dart類型的轉換。Dart和JS的交互速度未知。只能說哪怕FFW有很多瀏覽器的API不支持,也可以通過JS來擴展能力。 Dart和Js語言本身的差異會帶來測試和兼容成本的增加,雖然Dart可以編譯成Js,但是跑在DartVM上的Dart的表現(xiàn),和其編譯成Js運行在瀏覽器中的表現(xiàn)并不完全相同。比如對于如下代碼
Map<String, String> query = null;
val b = query["abc"]; 在DartVM中該代碼可以執(zhí)行,結果是b=null;但是編譯成Js以后運行時因為query為null,會報空指針。
用戶體驗
使用了chrome、uc、小米自帶瀏覽器分別試了一下訂單列表和官方的sample-gallery界面,體驗如下:
加載速度差不多,因為是局域網(wǎng)環(huán)境,感知不到差異。 非常重要 打出的唯一的main.dart.js和部分資源文件(比如MaterialIcons)沒有加載出來的時候,界面不會展示。幀率或者流暢度上,chrome > uc >> 小米自帶瀏覽器,其中chrome算是最流暢的體驗,但是sample中的一些動畫和頁面轉場也可以看到明顯的卡頓。 文字展示上,看flutter for web的界面,chrome對大部分文字處理的很清晰,小米自帶瀏覽器看文字明顯模糊。對比下面兩張圖,點開放大之后查看,FFW頁面的文字模糊的很明顯。
iOS的safari和chrome訪問demo頁,TextField整個不可用,包括以下問題:所有瀏覽器都不能選中文字復制粘貼。flutter for web應該是以canvas處理展示文字的,這樣才能解釋為啥有的字體size會模糊,并且不能選中文字。
軟鍵盤彈出邏輯詭異,大部分時候彈出自動縮回,小部分時候正常彈出(Android這部分表現(xiàn)正常);但焦點轉移的時候不會自動收回 safari不能輸入文字,chrome可以輸入(Android這部分表現(xiàn)正常) 可以選中文字,復制和粘貼不生效(Android問題相同) 焦點到TextField的時候界面會自動放大,這個時候很難縮放回去(Android這部分表現(xiàn)正常)
總結
按照上面的,整體總結一下,Flutter for Web有幾個比較嚴重的問題,不解決的話估計是無法應用到生產(chǎn)環(huán)境上的:
包大小問題,這會帶來幾個問題:
FFW的包遠大于正常h5的包,對流量和頁面加載速度都是很大的挑戰(zhàn) FFW打成一個JS包,多個FFW頁面無法對公共組件進行復用,進一步造成浪費。 FFW的js包不加載完,頁面無法展示,用戶體驗極差;而H5可以漸進加載,js可以后入場。 SDK分離的問題,這也會帶來幾個問題:
工程上,很難優(yōu)雅的解決兩個SDK并存的問題 能力上,依賴Flutter SDK的官方庫,比如多語言庫,不支持FFW SDK。只能自研一套多語言方案。 表單場景不要用FFW,上述說到的TextField的問題不知能否在應用層去解。 一些重交互的組件,比如下拉刷新等,存在問題,幾乎無法使用。不確定整體組件的質量情況如何,挨個去看成本太大。
結論
沒有非常強的業(yè)務訴求或者技術推動,不要在目前嘗試在生產(chǎn)環(huán)境使用Flutter for Web。 如果有填坑的決心,并且舍得投入,并且對包大小不關心,對幀率等用戶體驗也不看重,可以考慮現(xiàn)階段進行嘗試。 我個人判斷填坑成本在100人日以上(上限未知),并且有些坑(包大小)可能根本填不了。 什么時候可以再次跟進?我認為在FFW合并進Flutter SDK的時候,至于他們具體的規(guī)劃需要問下Google的人了。
填坑指北
本節(jié)的主要目的是列出假設要做FFW,我們需要做的技術項和對應方案。
原文鏈接 本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉載。
總結
以上是生活随笔 為你收集整理的Flutter for Web 详细预研 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。