内容简介:更多精彩
作者 白及, 阿里无线开发工程师
背景
Google在最新的Google I/O上推出了Flutter for Web,旨在进一步解决一次代码,多端运行的问题。Flutter for Web还处于早期试验版,官方不建议在生产环境上使用。那么到底它的实际情况怎么样呢?我们做了一次预研。期望这次预研的结果可以帮你决定是用,还是不用FFW。
Flutter for Web原理
Flutter for Web和Flutter在上层都是Dart环境,两者不同的是,Flutter的Dart代码运行在Dart虚拟机中,界面由Flutter引擎处理,通过Skia绘图引擎经由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绘制性能不优于手写html呢,定性的从几个角度分析:
-
FFW在canvas上绘制的组件带有很多MD特色的视觉和动画,比如阴影、Z轴变化等,这部分对性能的消耗要大于普通html标签
-
FFW是通过Dart的DSL转成的dom树结构,转化后的dom树十分复杂,不太可能比手写的dom树更简洁
-
使用canvas的控件,其手势事件的捕获分发都是靠FFW框架自己实现的,emmmm
-
虽然不排除Google大力出奇迹的情况,但是不管怎样,相同素质的开发人员,相同的界面,性能上也不可能优于html+css+js
另外一点,如果FFW在原理上涉及大量HTML标签的转化,那就势必会涉及到碎片化的处理中,浏览器的碎片化程度可一点都不比Android系统的碎片化小。像Flutter本身之所以被那么多人看重,就是因为其通过绘图引擎这一层,完美的避开了碎片化,保证一致性。
所以最好的平衡就是,只有有限的一部分标准的html标签可以被FFW复用,其必须有几点性质:
-
标签本身的功能简单又直观
-
最好不要有直接图形化的展示,或者只负责简单的图形化展示(比如画方形)
那几个比较典型的标签就是
、
这种了Flutter官方就是这么做的,所以我的结论是:
一致性上大体不会存在问题,性能上,FFW应该不会优于纯手写html标签界面。
官方现状&建议
根据官网和Github repo上的说法,我们整理了一下:
-
Flutter for Web和Flutter目前暂时是两个仓库,官方正在进行合并,没有给出结论。这一点在工程上非常重要,它说明了几个问题:
目前官方对FFW的成熟度没有信心,同时FFW的迭代速度也很快。
目前FFW和Flutter最多保证API一样,实现原理差异可能非常大,同时不保证所有控件都已经在FFW上实现。
-
官方不建议应用在生产环境
-
目前插件能力十分有限,和系统交互的一些能力缺失,比如拍照等。
-
性能无法保证,运行会慢,可能会有掉帧
-
FFW中针对桌面的UI部分没有完成(跟我无线有什么关系?)
-
开发中只能在Chrome中调试(又有什么关系?),release版是可以运行在任意浏览器中(除了IE,另支持的最低版本存疑)。
实践
对于这么新的东西,官网上的内容的确不多,而且简单来看这些问题好像也没什么,所以对于到底能不能用,我们还是需要抱着吃螃蟹的心态具体进去预研一下,为了尽快弄清,我计划找一个我们app已经做好的flutter页面,把它迁移成FFW,对整个迁移过程做个评估,再看下页面效果,基本上就能得出结论了。
具体的迁移细节就不提了,官网也有迁移文档,大体上就是这么几个步骤
-
安装Flutter for Web的工具webdev
-
改SDK依赖,新增Web文件夹(和之前存在的android、ios文件夹同级),新增一些其他文件(index.html, main.dart等)。
-
将所有flutter代码中依赖的flutter包,改成flutter_web包
-
去掉所有不兼容的代码,比如多语言、路由、Platform.isAndroid等等
-
编译运行
实践的主要目的,有以下几个:
-
对整体坑的深度和广度有个认知,方便推算出填坑成本
-
对FFW整体的性能和体验有个把握,尤其是我们自己的页面跑在FFW上是什么体验。
-
对FFW和JS相互调用有具体的了解,如果可行,那复用集团已有能力(比如mtop)的坑就会小很多
删了一万行代码跑成功之后,最终在工程、开发体验、用户体验上得到一些结论,以下的结论中,体验部分是我在我的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不加载完,界面是不会展示的。
开发体验
-
非常重要flutter for web使用flutter_web库,且不支持其他许多插件,这会带来几个问题
工程上无法优雅的解决flutter和flutter_web共存的情况,最多搞个dart2的conditional import(这个特性可不在官方文档中哦)
依赖flutter sdk的几个库,尤其是多语言库无法应用在flutter_web上,并且Google肯定不会再单独为flutter_web适配,而是在合并时做支持。这就意味着现阶段所有依赖flutter sdk的库不能被flutter_web使用。
-
调试困难
错误日志可以打印到浏览器的console中,但是try catch部分的堆栈不好拿
浏览器中的堆栈很复杂,但是基本上能找到出错的dart代码
目前没有发现单步调试的能力
-
Platform.isAndroid全部报错,针对Android和iOS做差异化展示目前还不知道有没有其他方法可以做到。
-
目前没有发现控件的api不一致的地方,不过有些控件的行为十分异常,比如下拉刷新,在Android手机上经常卡死、失效。猜测重交互的一些控件都有可能存在类似的问题,但是测一遍的成本太高。
-
图片控件NetworkImage可以直接用,但是现在来看有些糊,不确定是官方控件的问题,还是我们做的cdn url策略有问题。
-
dart代码可以调用js,开发体验和反射类似,并且需要处理JS类型和Dart类型的转换。Dart和JS的交互速度未知。只能说哪怕FFW有很多浏览器的API不支持,也可以通过JS来扩展能力。
-
Dart和Js语言本身的差异会带来测试和兼容成本的增加,虽然Dart可以编译成Js,但是跑在DartVM上的Dart的表现,和其编译成Js运行在浏览器中的表现并不完全相同。比如对于如下代码
在DartVM中该代码可以执行,结果是b=null;但是编译成Js以后运行时因为query为null,会报空指针。
用户体验
使用了chrome、uc、小米自带浏览器分别试了一下订单列表和官方的sample-gallery界面,体验如下:
-
加载速度差不多,因为是局域网环境,感知不到差异。
-
非常重要打出的唯一的main.dart.js和部分资源文件(比如MaterialIcons)没有加载出来的时候,界面不会展示。
-
帧率或者流畅度上,chrome > uc >> 小米自带浏览器,其中chrome算是最流畅的体验,但是sample中的一些动画和页面转场也可以看到明显的卡顿。
-
文字展示上,看flutter for web的界面,chrome对大部分文字处理的很清晰,小米自带浏览器看文字明显模糊。对比下面两张图,点开放大之后查看,FFW页面的文字模糊的很明显。
-
所有浏览器都不能选中文字复制粘贴。flutter for web应该是以canvas处理展示文字的,这样才能解释为啥有的字体size会模糊,并且不能选中文字。
-
iOS的safari和chrome访问demo页,TextField整个不可用,包括以下问题:
软键盘弹出逻辑诡异,大部分时候弹出自动缩回,小部分时候正常弹出(Android这部分表现正常);但焦点转移的时候不会自动收回
safari不能输入文字,chrome可以输入(Android这部分表现正常)
可以选中文字,复制和粘贴不生效(Android问题相同)
焦点到TextField的时候界面会自动放大,这个时候很难缩放回去(Android这部分表现正常)
总结
按照上面的,整体总结一下,Flutter for Web有几个比较严重的问题,不解决的话估计是无法应用到生产环境上的:
-
包大小问题,这会带来几个问题:
FFW的包远大于正常h5的包,对流量和页面加载速度都是很大的挑战
FFW打成一个JS包,多个FFW页面无法对公共组件进行复用,进一步造成浪费。
FFW的js包不加载完,页面无法展示,用户体验极差;而H5可以渐进加载,js可以后入场。
-
SDK分离的问题,这也会带来几个问题:
工程上,很难优雅的解决两个SDK并存的问题
能力上,依赖Flutter SDK的官方库,比如多语言库,不支持FFW SDK。只能自研一套多语言方案。
-
表单场景不要用FFW,上述说到的TextField的问题不知能否在应用层去解。
-
一些重交互的组件,比如下拉刷新等,存在问题,几乎无法使用。不确定整体组件的质量情况如何,挨个去看成本太大。
结论
-
没有非常强的业务诉求或者技术推动,不要在目前尝试在生产环境使用Flutter for Web。
-
如果有填坑的决心,并且舍得投入,并且对包大小不关心,对帧率等用户体验也不看重,可以考虑现阶段进行尝试。
-
我个人判断填坑成本在100人日以上(上限未知),并且有些坑(包大小)可能根本填不了。
-
什么时候可以再次跟进?我认为在FFW合并进Flutter SDK的时候,至于他们具体的规划需要问下Google的人了。
填坑指北
本节的主要目的是列出假设要做FFW,我们需要做的技术项和对应方案。
-
更多精彩
2019阿里云618大促主会场全攻略
GMTC2019|闲鱼-基于Flutter的架构演进与创新
如果觉得本文还不错,点击在看一下!
点 此 阅读作者更多好文!
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Twenty Lectures on Algorithmic Game Theory
Tim Roughgarden / Cambridge University Press / 2016-8-31 / USD 34.99
Computer science and economics have engaged in a lively interaction over the past fifteen years, resulting in the new field of algorithmic game theory. Many problems that are central to modern compute......一起来看看 《Twenty Lectures on Algorithmic Game Theory》 这本书的介绍吧!
XML、JSON 在线转换
在线XML、JSON转换工具
XML 在线格式化
在线 XML 格式化压缩工具