Flutter for Web 详细预研

背景

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呢,定性的从几个角度分析:

  1. FFW在canvas上绘制的组件带有很多MD特色的视觉和动画,比如阴影、Z轴变化等,这部分对性能的消耗要大于普通html标签
  2. FFW是通过Dart的DSL转成的dom树结构,转化后的dom树十分复杂,不太可能比手写的dom树更简洁
  3. 使用canvas的控件,其手势事件的捕获分发都是靠FFW框架自己实现的,emmmm
    虽然不排除Google大力出奇迹的情况,但是不管怎样,相同素质的开发人员,相同的界面,性能上也不可能优于html+css+js

另外一点,如果FFW在原理上涉及大量HTML标签的转化,那就势必会涉及到碎片化的处理中,浏览器的碎片化程度可一点都不比Android系统的碎片化小。像Flutter本身之所以被那么多人看重,就是因为其通过绘图引擎这一层,完美的避开了碎片化,保证一致性。
所以最好的平衡就是,只有有限的一部分标准的html标签可以被FFW复用,其必须有几点性质:

  1. 标签本身的功能简单又直观
  2. 最好不要有直接图形化的展示,或者只负责简单的图形化展示(比如画方形)
    那几个比较典型的标签就是<p><div>这种了

Flutter官方就是这么做的,所以我的结论是:
一致性上大体不会存在问题,性能上,FFW应该不会优于纯手写html标签界面。

官方现状&建议

根据官网和Github repo上的说法,我们整理了一下:

  1. Flutter for Web和Flutter目前暂时是两个仓库,官方正在进行合并,没有给出结论。这一点在工程上非常重要,它说明了几个问题:

    1. 目前官方对FFW的成熟度没有信心,同时FFW的迭代速度也很快。
    2. 目前FFW和Flutter最多保证API一样,实现原理差异可能非常大,同时不保证所有控件都已经在FFW上实现。
  2. 官方不建议应用在生产环境
  3. 目前插件能力十分有限,和系统交互的一些能力缺失,比如拍照等。
  4. 性能无法保证,运行会慢,可能会有掉帧
  5. FFW中针对桌面的UI部分没有完成(跟我无线有什么关系?)
  6. 开发中只能在Chrome中调试(又有什么关系?),release版是可以运行在任意浏览器中(除了IE,另支持的最低版本存疑)。

实践

对于这么新的东西,官网上的内容的确不多,而且简单来看这些问题好像也没什么,所以对于到底能不能用,我们还是需要抱着吃螃蟹的心态具体进去预研一下,为了尽快弄清,我计划找一个我们app已经做好的flutter页面,把它迁移成FFW,对整个迁移过程做个评估,再看下页面效果,基本上就能得出结论了。
具体的迁移细节就不提了,大体上就是这么几个步骤

  1. 安装Flutter for Web的工具webdev
  2. 改SDK依赖,新增Web文件夹(和之前存在的android、ios文件夹同级),新增一些其他文件(index.html, main.dart等)。
  3. 将所有flutter代码中依赖的flutter包,改成flutter_web包
  4. 去掉所有不兼容的代码,比如多语言、路由、Platform.isAndroid等等
  5. 编译运行

实践的主要目的,有以下几个:

  1. 对整体坑的深度和广度有个认知,方便推算出填坑成本
  2. 对FFW整体的性能和体验有个把握,尤其是我们自己的页面跑在FFW上是什么体验。
  3. 对FFW和JS相互调用有具体的了解,如果可行,那复用集团已有能力(比如mtop)的坑就会小很多

删了一万行代码跑成功之后,最终在工程、开发体验、用户体验上得到一些结论,以下的结论中,体验部分是我在我的mix2s上的感受:

工程

  1. 支持debug和release模式,后者比前者性能高(差异很明显)。

    1. debug模式支持代码修改后自动重新编译,和其他的前端框架(我只用过Django)一致
  2. 支持hotreload,暂时没有尝试
  3. 支持webdev build命令编译出index.html+js,可以通过nginx做反向代理。
  4. 非常重要 编译出来的代码,gzip压缩前,最简单的helloworld的main.dart.js大小约为500k左右,sample中的gallery大小约为2M,阉割版的纯展示用的订单列表大小约为1.3M。gzip对文本的压缩率一般是80%,压缩后也要动辄几百k的大小。而且main.dart.js不加载完,界面是不会展示的。

开发体验

  1. 非常重要flutter for web使用flutter_web库,且不支持其他许多插件,这会带来几个问题

    1. 工程上无法优雅的解决flutter和flutter_web共存的情况,最多搞个dart2的conditional import(这个特性可不在官方文档中哦)
    2. 依赖flutter sdk的几个库,尤其是多语言库无法应用在flutter_web上,并且Google肯定不会再单独为flutter_web适配,而是在合并时做支持。这就意味着现阶段所有依赖flutter sdk的库不能被flutter_web使用。
  2. 调试困难

    1. 错误日志可以打印到浏览器的console中,但是try catch部分的堆栈不好拿
    2. 浏览器中的堆栈很复杂,但是基本上能找到出错的dart代码
    3. 目前没有发现单步调试的能力
  3. Platform.isAndroid全部报错,针对Android和iOS做差异化展示目前还不知道有没有其他方法可以做到。
  4. 目前没有发现控件的api不一致的地方,不过有些控件的行为十分异常,比如下拉刷新,在Android手机上经常卡死、失效。猜测重交互的一些控件都有可能存在类似的问题,但是测一遍的成本太高。
  5. 图片控件NetworkImage可以直接用,但是现在来看有些糊,不确定是官方控件的问题,还是我们做的cdn url策略有问题。
  6. dart代码可以调用js,开发体验和反射类似,并且需要处理JS类型和Dart类型的转换。Dart和JS的交互速度未知。只能说哪怕FFW有很多浏览器的API不支持,也可以通过JS来扩展能力。
  7. 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界面,体验如下:

  1. 加载速度差不多,因为是局域网环境,感知不到差异。
  2. 非常重要打出的唯一的main.dart.js和部分资源文件(比如MaterialIcons)没有加载出来的时候,界面不会展示。
  3. 帧率或者流畅度上,chrome > uc >> 小米自带浏览器,其中chrome算是最流畅的体验,但是sample中的一些动画和页面转场也可以看到明显的卡顿。
  4. 文字展示上,看flutter for web的界面,chrome对大部分文字处理的很清晰,小米自带浏览器看文字明显模糊。对比下面两张图,点开放大之后查看,FFW页面的文字模糊的很明显。


iOS的safari和chrome访问demo页,TextField整个不可用,包括以下问题:所有浏览器都不能选中文字复制粘贴。flutter for web应该是以canvas处理展示文字的,这样才能解释为啥有的字体size会模糊,并且不能选中文字。

    1. 软键盘弹出逻辑诡异,大部分时候弹出自动缩回,小部分时候正常弹出(Android这部分表现正常);但焦点转移的时候不会自动收回
    2. safari不能输入文字,chrome可以输入(Android这部分表现正常)
    3. 可以选中文字,复制和粘贴不生效(Android问题相同)
    4. 焦点到TextField的时候界面会自动放大,这个时候很难缩放回去(Android这部分表现正常)

总结

按照上面的,整体总结一下,Flutter for Web有几个比较严重的问题,不解决的话估计是无法应用到生产环境上的:

  1. 包大小问题,这会带来几个问题:

    1. FFW的包远大于正常h5的包,对流量和页面加载速度都是很大的挑战
    2. FFW打成一个JS包,多个FFW页面无法对公共组件进行复用,进一步造成浪费。
    3. FFW的js包不加载完,页面无法展示,用户体验极差;而H5可以渐进加载,js可以后入场。
  2. SDK分离的问题,这也会带来几个问题:

    1. 工程上,很难优雅的解决两个SDK并存的问题
    2. 能力上,依赖Flutter SDK的官方库,比如多语言库,不支持FFW SDK。只能自研一套多语言方案。
  3. 表单场景不要用FFW,上述说到的TextField的问题不知能否在应用层去解。
  4. 一些重交互的组件,比如下拉刷新等,存在问题,几乎无法使用。不确定整体组件的质量情况如何,挨个去看成本太大。

结论

  1. 没有非常强的业务诉求或者技术推动,不要在目前尝试在生产环境使用Flutter for Web。
  2. 如果有填坑的决心,并且舍得投入,并且对包大小不关心,对帧率等用户体验也不看重,可以考虑现阶段进行尝试。
  3. 我个人判断填坑成本在100人日以上(上限未知),并且有些坑(包大小)可能根本填不了。
  4. 什么时候可以再次跟进?我认为在FFW合并进Flutter SDK的时候,至于他们具体的规划需要问下Google的人了。

填坑指北

本节的主要目的是列出假设要做FFW,我们需要做的技术项和对应方案。


原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/518564.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

坚持探索与落地并重,阿里巴巴云原生之路全景揭秘

阿里妹导读&#xff1a;阿里云已经成功地规模化落地云原生&#xff0c;26日的 KubeCon 大会上&#xff0c;CNCF TOC 和阿里云资深技术专家李响发表主题演讲&#xff0c;分享了阿里巴巴在规模扩展、可靠性、开发效率、迁移策略等方面的经验&#xff0c;并探讨云原生的落地及应对…

Java-抽象类

// abstract 抽象类 // 类是 单继承&#xff0c; 接口是 多继承 public abstract class Action {// 约束~ 有人帮我们实现// abstract, 抽象方法&#xff0c;只有方法名字&#xff0c;没有方法的实现public abstract void doSomething();/*1. 不能 new 这个抽象类&#xff0c…

在Kubernetes上部署一个简单的、类PaaS的平台,原来这么容易!

作者 | Bram Dingelstad译者 | 弯月 责编 |徐威龙封图| CSDN下载于视觉中国我们都遇到过这种情况&#xff1a;有人发现了一个bug&#xff0c;然而这不是一般的软件bug&#xff0c;甚至都不是通常意义上的bug&#xff0c;其本质上是人员的问题&#xff1a;盲目跟风的开发者。一开…

对话阿里敏捷教练 | 成功辅导过淘宝、闲鱼,他都是如何帮助团队

为了让大家对敏捷有更多的了解&#xff0c;小编特意采访了阿里巴巴高级技术专家、敏捷教练张燎原。他是如何看待敏捷、如何帮助团队落地敏捷的&#xff0c;作为研发团队的一员&#xff0c;我们可以从哪些地方着手敏捷&#xff0c;以下是对他的采访。 嘉宾简介&#xff1a;张燎原…

用Flink取代Spark Streaming!知乎实时数仓架构演进

作者 | 知乎数据工程团队 “数据智能” (Data Intelligence) 有一个必须且基础的环节&#xff0c;就是数据仓库的建设&#xff0c;同时&#xff0c;数据仓库也是公司数据发展到一定规模后必然会提供的一种基础服务。从智能商业的角度来讲&#xff0c;数据的结果代表了用户的反…

Java-接口的定义与实现

// 接口都需要有实现类 public interface UserService {// 常量 默认是 public static final&#xff0c;一般不会再接口定义常量int AGE 99;// 接口中的所有定义的方法其实都是抽象的 public abstract // public abstract void run();void add(String name);void delete(S…

4 年 46 个版本,一文读懂 Spring Cloud 发展历史

作者 | 方剑责编 | 唐小引头图 | CSDN 下载自东方 IC出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;Spring Cloud 自 2016 年 1 月发布第一个 Angel.SR5 版本&#xff0c;到目前 2020 年 3 月发布 Hoxton.SR3 版本&#xff0c;已经历经了 4 年时间。这 4 年时间里…

让开发部署提速 8 倍,我参与贡献这款 IDE 插件的全过程

如何像参与开源那样&#xff0c;去参与一款 IDE 插件的设计&#xff1f; 作为一款 IDE 插件的使用者&#xff0c;我是否能决定下一个版本的功能&#xff1f; 自从产品经理银时小伙和他的开发小哥们在去年12月发布 Cloud Toolkit&#xff08;一款 IDE 插件&#xff09;以来&am…

这难道是原子、比特and供应链的新内涵?京东如是说……

本文为CSDN博主「L-JingJing」的原创文章 原文链接&#xff1a;https://blog.csdn.net/sch881226/article/details/105301572 从遍览采茶风光到感受入口醇香&#xff0c;如今我们真的可以做到高效追溯每一片茶叶的“记忆”了吗&#xff1f;答案显然是肯定的&#xff0c;据了解…

干货!看云原生时代阿里云的四个“最”

云原生已经成为 IT 领域最热的词之一。到底有多火&#xff0c;大家感受一下&#xff1a; 2015 年在旧金山召开的首届 KubeCon 只有 200 余参会者&#xff0c;而今年第二次在中国举办的KubeCon迎来了3000现场观众&#xff0c;遍布全球的线上关注开者则更是不计其数。Gartner最近…

深入解读 Knative Eventing 0.7 版本新特性

前言 Knative Eventing 0.7 版本已经于 6 月 26 号正式发布。本次发布主要围绕重构 Channel 特性展开。本篇文章重点解读了这些特性&#xff0c;并且以此展望一下 Knative Eventing 后续版本的发展。 新特性 重构 Channel 作为 Eventing v0.7 版本最大的特性&#xff0c; 重…

Java-异常01 Error和Exception

异常 捕获异常 https://www.bilibili.com/video/BV12J41137hu?p77&spm_id_frompageDriver

OpenKruise - 云原生应用自动化引擎正式开源

在本次 KubeCon 上&#xff0c;阿里云将为全球用户分享阿里巴巴超大规模云原生落地实践、云原生前沿技术与应用包括OpenKruise 开源项目、开放云原生应用中心&#xff08;Cloud Native App Hub&#xff09;&#xff0c;同时将重磅发布边缘容器、云原生应用管理与交付体系等产品…

过去15年间,到底是什么真正推动了云计算的革命?

来源 | Ohad Maislish译者 | 孙薇 责编 | 徐威龙封图| CSDN下载于视觉中国虚拟机的兴起我还记得&#xff0c;我第一次听说虚拟机是在2002年&#xff0c;我们需要一种能够在Windows OS上运行Linux的方法。当头一次看到在VMware Workstation上运行的虚拟机时&#xff0c;我非常震…

支付宝的商业与技术创新双轮驱动 创造数字时代普惠金融“奇迹”

2019年6月28日&#xff0c;在中国国际软件博览会上&#xff0c;蚂蚁金服金融科技产品技术总监杨冰发表主题演讲&#xff0c;分享了蚂蚁金服在过去的十多年里&#xff0c;是如何通过商业创新与技术创新的双轮驱动&#xff0c;创造出数字时代的普惠金融“奇迹”。 蚂蚁金服金融科…

Java-异常02 捕获和抛出异常

ArithmeticException 算术异常 public class Test {public static void main(String[] args) {int a 1;int b 0;try { // try监控区域System.out.println(a/b);} catch (ArithmeticException e){System.out.println("程序出现异常&#xff0c;变量B不能为0");} fi…

基于Tablestore Tunnel的数据复制实战

前言 数据复制主要指通过互联的网络在多台机器上保存相同数据的副本&#xff0c;通过数据复制方案&#xff0c;人们通常希望达到以下目的&#xff1a;1&#xff09;使数据在地理位置上更接近用户&#xff0c;进而降低访问延迟&#xff1b;2&#xff09;当部分组件出现故障时&a…

今天,我要教妹子学会Spring:Aware、异步编程、计划任务

来源 | 沉默王二教妹子学 Spring&#xff0c;没见过这么放肆的标题吧&#xff1f;作者我有一个漂亮如花的妹妹&#xff08;见封面图&#xff0c;别问我怎么又变了&#xff1f;还不能一天做个梦了&#xff1f;&#xff09;&#xff0c;她叫什么呢&#xff1f;我想聪明的读者能猜…

Java-异常03 自定义异常

// 自定义的异常类 public class MyException extends Exception{// 传递数字 > 10private int detail;public MyException(int a) {this.detail a;}// toString: 异常的打印信息Overridepublic String toString() {return "MyException{" detail };} }public …

SLS机器学习最佳实战:批量时序异常检测

0.文章系列链接 SLS机器学习介绍&#xff08;01&#xff09;&#xff1a;时序统计建模SLS机器学习介绍&#xff08;02&#xff09;&#xff1a;时序聚类建模SLS机器学习介绍&#xff08;03&#xff09;&#xff1a;时序异常检测建模SLS机器学习介绍&#xff08;04&#xff09;…