原标题:重磅|庖丁解牛之——Flutter for Web

概述

在2018年冬的Flutter 1.0伦敦发布会上,Flutter的产品经理Tim Sneath通过一个滑动拼图的例子介绍了如何让Flutter运行在Web之上。这一当时代号HummingBird的项目后来被重命名为flutter_web,并最终合入了master分支。

Flutter Web想在单代码库的情况下,使Flutter应用拥有Web支持。这样开发者使用Dart编写的Flutter应用可以被部署到任意的Web服务器上,或嵌入到浏览器中。开发者可以使用Flutter的所有特性,也不需要特殊的浏览器插件支持。

就最新的Flutter1.9.x而言,Flutter Web还处于技术预览版阶段,离真正应用到生产环境中还是有一些距离的。

设计

那么Flutter Web是怎么做到这一切的呢?这就要从Flutter的原理说起。Flutter框架的设计如下所示:

其中,Flutter Framework是使用纯Dart开发的。我们将其分为两部分,渲染和逻辑。就渲染而言,其最终会表示为dart:ui中提供的TextBox,Picture,Image等实例对象,再通过native方法(实现dart调用C++)调用Skia,Text等C++库,最终渲染在屏幕上,逻辑部分则被Dart Runtime执行。不难看出,要实现在Web上运行Flutter,要解决两个问题。Dart如何运行在Web上以及dart:ui中的native方法如何通过标准Web的方式来实现。就前者而言,dart2js是一个已有的成熟框架,所以问题的重点就在于如何通过标准Web的方式去实现一个dart:ui库。这也就是目前Flutter Web的设计原理:

在Flutter Web的设计之初,主要考虑了两个方案用于Web支持:

1.HTML+CSS+Canvas

2.CSS Paint API

方案1具有最好的兼容性,它优先考虑HTML+CSS表达,当HTML+CSS无法表达图片的时候,会使用Canvas来绘制。但2D Canvas在浏览器中是位图表示,会造成像素化下的性能问题。

方案2是新的Web API, 属于Houdini的组成部分。Houdini提供了一组可以直接访问CSS对象模型的API,使得开发者可以去书写代码并被浏览器作为CSS加以解析,这样在无需等待浏览器原生的支持下,创造了新的CSS特性。它的绘制并非由核心Java完成,而是类似Web Worker的机制。其绘制由显示列表支持,而不是位图。但目前CSS Paint API不支持文本,此外各家厂商对齐支持也并不统一。

鉴于此,目前Flutter Web使用的是基于方案1的实现。

环境准备

flutter环境

web环境

在flutter的master分支上,开发者可以通过下方命令检查当前是否打开了Web支持:

如果不能看到Chrome/Server这两个设备,可以通过以下命令打开支持:

这个命令会将配置项保存到用户Home目录下的.flutter_settings中,一个典型的内容如下所示:

dart2js配置修改

以flutter自带的gallery为例,默认的flutter web实现下,生成的js如下所示:

可以看到此js代码可读性很差(变量名,格式等),大小为2.2MB。这是因为flutter构建过程中开启了dart2js命令的O4优化项所致。为了方便我们分析和调试,我们对此其进行如下修改:

O0将禁止很多优化,修改后的效果如下所示:

可以看到,大小增加了不少,但可读性上好很多,除特殊说明外,本文将在O0优化项下展开。

原理剖析

Gallery上的表现对比

我们首先基于Flutter提供的Gallery项目,比较下其在Mobile和Web上的表现(此处使用Flutter Web默认优化级别):

Flutter Native vs Flutter Web:

可以看出,Flutter Web在完备性上还是比较不错的,但依然有一些问题,比如本地图片在Android设备上显示正常,在iOS上却无法正常显示,网络图片则是正常的。

在Mobile/Web开发中,常见的元素包括图片,文字,形状,手势等,接下来,我们逐一进行剖析。

图片的实现

以如下代码为例:

其运行效果如下(左侧为Native,右侧为Web):

其Native与Web简要原理对比如下所示:

在flutter_web_sdk中最终调用html库(dart-sdk自带)绘制的代码如下:

相对应地,通过flutter build web --release --verbose生成的main.dart.js中部分代码如下:

最终调用到了

CanvasRenderingContext2D.drawImage这一标准W3C的API。

文本的实现

以如下代码为例:

其运行效果如下(左侧为Native,右侧为Web):

其Native与Web简要原理对比如下所示:

在flutter_web_sdk中最终调用html库(dart-sdk自带)构建和添加Element的代码如下:

相对应地main.dart.js中部分代码如下:

从文本这个例子不难看出,对于可以通过HTML+CSS形式表达的元素,flutter web将其最终翻译成Element+CSS Style形式动态生成类似静态HTML+CSS描述的内容,最终完成内容的渲染。

形状的实现

以如下代码为例:

其运行效果如下(左侧为Native,右侧为Web):

其Native与Web简要原理对比如下所示:

在flutter_web_sdk中最终调用html库(dart-sdk自带)构建Element(添加部分同文本)的代码如下:

相对应地main.dart.js中部分代码如下:

对于本例中的形状,也是通过HTML+CSS的方式实现的。

触摸事件的实现

以如下代码为例:

其运行效果如下(左侧为Native,右侧为Web):

其Native与Web简要原理对比如下所示:

此例中的PointerBinding由dart_sdk.js提供,其提供了从Window获取事件回调的机制,并最终调用到了WidgetsFlutterBinding(也是GestureBinding)的_handlePointerDataPacket$1方法,后续的路由机制同Native情景下的Flutter部分。

优缺点

优点

从目前Flutter Web选取的技术路线来说,HTML+CSS+Canvas这种方式具有最好的兼容性,这样开发者开发的Flutter代码(不包括Plugin部分对于Native的扩展)将零成本地转成标准Web展示,这一低成本扩展到Web平台带来的优势还是很明显的。

不足

尽管其优势很明显,也面临一些不足的问题

1.包大小过大的问题

目前dart2js本身并没有针对小型程序做出优化,即使是本文中的手势这么简单的代码,Flutter Web最终生成的大小也有560KB, 无法满足要求。

但从理论上来说,通过对dart2js本身做出合理的优化(鉴于dart/flutter整个的开源设计),我们可以将Flutter Web依赖的基础SDK全集嵌入应用中(或者按需下载的方式),将真正的业务代码与SDK分离,也是有可能将其大小降低的。

1.功能不完备的问题

比如在flutter_gallery的例子中Safari上图标展示为方框的问题。

2.性能的问题

当需要用到BitmapCanvas比较多的时候,Element对象直接的光栅化,会导致在一些诸如缩放等的场景下,面临性能的问题。当然缩放的问题在移动设备的场景下也是有可能避免的。

小结

总体而言,Flutter Web具有优秀的设计。它基于dart:js和dart:html这些成熟的框架,通过将与Native相关的dart:ui库重写的方式,很好地解决了Flutter扩展到Web平台上的问题。对于上层开发者而言,完全不用去做任何修改,即可产生一套符合Web标准的代码,显示和行为也同原始设计保持一致。虽然目前Flutter Web还不够成熟,存在一些诸如包大小性能等问题,但基于Flutter和Flutter Web的良好分层设计,我们有理由相信随着时间的推移和社区成熟,这些问题终将得到改善或解决。

点此了解更多详情~返回搜狐,查看更多

责任编辑:

java 庖丁解牛api_重磅|庖丁解牛之——Flutter for Web相关推荐

  1. Java、JS、OC、Flutter的Base64编码和解码

    题记 -- 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天. ** 你可能需要 CSDN 网易云课堂教程 掘金 EDU学院教程 知乎 Flutter系列文章 本文章将描述在 Jav ...

  2. 腾讯 Flutter 跨平台 Web 实践

    点击上方"开发者技术前线",选择"星标" 每天 14.00 在看 | 真爱 来源:腾讯新闻前端团队   |  作者  SegmentFault Flutter是 ...

  3. 打破重重阻碍,Flutter 和 Web 生态如何对接?

    简介: Flutter 设计之初是不考虑 Web 生态的,原因很简单:两种技术设计理念不同,强行融合很可能让彼此都丧失了优势.但是业界又有很多团队在做这种尝试,说明需求是存在的.今天,阿里无线开发专家 ...

  4. Java如何通过WSDL文件来调用这些web service

    下面我们来看Java如何通过WSDL文件来调用这些web service: 注意,以下的代码并没有经过真正的测试,只是说明这些情况,不同版本的Axis相差很大,大家最好以apache网站上的例子为准, ...

  5. 当 Flutter 遇见 Web,会有怎样的秘密?

    作者:haigecao,腾讯 CSIG Web 开发工程师 在线教育团队(简称:OED)已经将 Flutter 这样技术在业务中落地了,做为 IMWeb 前端团队的我们也要进行一些尝试.本文从前端角度 ...

  6. Flutter for Web 详细预研

    背景 Google在最新的Google I/O上推出了Flutter for Web,旨在进一步解决一次代码,多端运行的问题.Flutter for Web还处于早期试验版,官方不建议在生产环境上使用 ...

  7. 基于 Flutter 的 Web 渲染引擎「北海」正式开源!

    简介: 阿里巴巴历时 3 年自研开发的 Web 渲染引擎北海(英文名:Kraken)正式开源,致力打造易扩展,跨平台,高性能的渲染引擎,并已在优酷.大麦.天猫等业务场景中使用. 作者 | 染陌 来源 ...

  8. Flutter For Web入门

    Google在今年5月的Google大会上发布了Flutter1.5.4版本,同时也推出了Flutter for Web的预览版,并开启了Flutter的全栈框架之路.同时,今年9月举行的谷歌开发者大 ...

  9. Flutter for Web开发打包部署

    第一种渲染方式: flutter build web --web-renderer html 第二种渲染方式: flutter build web --web-renderer canvaskit 打 ...

最新文章

  1. 微信无法连接服务器501,微信成语猜猜看第501关BUG出现全是英文怎么过解决方法...
  2. Win10如何查看我们的电池健康
  3. 【dp】【路径压缩】P1052 过河
  4. android窗口泄漏,isInEditMode解决可视化编辑器无法识别自定义控件的问题
  5. Java程序猿必读的书籍,良心推荐!
  6. 修改服务器ssh登录超时时间
  7. Asp.Net Core SignalR 用泛型Hub优雅的调用前端方法及传参
  8. 如何使用Apache Drill分析高度动态的数据集
  9. 深入理解Qt的.pro文件
  10. obs之libx264编码
  11. 完美解决netkeeper 错误代码137
  12. 5号AA电池,7号AAA电池
  13. 北京车辆过户全过程(详细得狠)20160729更新,图4幅
  14. idea右侧没有maven,main方法无启动图标解决方法
  15. 角点检测的几种基本方法
  16. iOS - Icon图标、启动图片、审核图片尺寸
  17. JS逆向-新榜数据nonce和xyz参数分析
  18. html输入日期算出星座,java输入日期计算星座
  19. ic芯片写卡软件的分类
  20. 如何正确更新R实现R语言版本控制,解决程辑包‘xxx’是用R版本3.6.3来建造的问题

热门文章

  1. C语言随机函数的使用
  2. 【Python网络爬虫实战篇】使用selenium+requests爬取下载高清源视频:关于爬取m3u8文件链接解析为ts视频合并成mp4视频的分析实战
  3. Translation[VERTEBRA-FOCUSED LANDMARK DETECTION FOR SCOLIOSIS ASSESSMENT]——2021.6.18
  4. iOS-获取当前设备的局域网以及链接的WiFi分配的IP地址
  5. docker 中安装 MySQL 以及使用
  6. Freefilesync自动同步
  7. 关于RPN中proposal的坐标回归参数的一点理解及Faster R-CNN的学习资料
  8. HTML元素的水平/垂直居中方式(简单代码和图)
  9. 数据挖掘-二项逻辑斯蒂回归模型算法的R实现
  10. 交换机的初始化配置(思科模拟器)