• 1

  • 447

  • 收藏

大前端之flutter开篇

4星期前

作者:灵清

文中信息参考了google flutter团队的flutter最新进展和发展状况,此文目的在于拓展大家技术视野,了解起源、原理才能玩得出花样,起到一个带大家走入大前端世界的指引效果!后续还将推出奥创 flutter SDK系列文章,目前星环奥创版flutter SDK已在ICBU国际站落地上线.

为什么每一位大前端都应该学习flutter?为什么集团都在共建flutter?flutter为什么能让ios和android之间的壁垒逐渐消失?为何移动端的h5页面也能被逐渐取代?为何星环SDK也推出了奥创版flutter SDK?让我们也来一场前端走入移动端世界的视野拓展之旅!!!

flutter基本介绍


什么是flutter?flutter怎么实现跨平台能力的?flutter是Google主导开发的帮助开发者在移动、web和桌面多个平台实现跨平台、高质量原生应用程序的开源UI工具包,在2018年12月正式发布了1.0版本,也标志着flutter在移动端是为生产环境的应用做好了准备。

flutter与各种跨平台框架的不同点

flutter对于之前已经有过的各种跨平台框架的探索有什么不同点呢?可以分为四个方面来讲讲
image.png

  1. 美观:首先 用flutter构建的移动应用可以达到一个非常高的视觉标准,它用了skia的2D渲染引擎,让开发者能够对屏幕上的每一个像素都达到直接精准的控制

image.png
图:flutter架构图

(为什么flutter可以做到像素级的控制以及高性能这两点,其实跟它的系统架构是有关系的,flutter它的主要的像素渲染能力由C++写的flutter引擎来完成,这个引擎是建构于skia 2D引擎之上,并且包含Dart runtime和dart ui库,在flutter engine之上,有flutter ui框架可以实现对于不同设计语言的具体的在像素级上的呈现)

  1. 快速:flutter的UI渲染性能非 常好,因为它在生产环境下编译成原生机器代码来执行,可以充分地利用到每一台手机上的GPU渲染能力,并且充分的对硬件本身优化,所以用flutter写的应用,在低端手机,也能达到60帧每秒的渲染速率,能GPU加速


3.高效:有一个广受开发者喜爱的功能:热重载(hot Reload)可以让代码亚秒级即小于1秒的情况下反映到你正在运行的UI上,这样对于做UI开发的同学可以达到一个非常快速迭代的效果,并且hot reload是保留UI状态的,为什么这一点非常重要呢,因为有的时候可能你在做一个对子页面的一个快速修改,每一次修改,刷新页面之后,你不希望再从头回到起始页,再一路点击到你所在的子页面,带有状态的Hot reload可以让你保留在你所在的位置,就是刚才在快速编辑的那个子页面同时看到你UI代码的更新

4.开放:它是一个完全开源并且免费的UI toolkit,全球的开发者都可以免费的使用,并且对它做出各种各样的贡献,包括对flutter代码库本身的贡献,以及对flutter生态及文档的贡献

Flutter与其他框架本质区别

比较与其他跨平台方案的本质区别:

  • React Native之类的框架,只是通过 JavaScript 虚拟机扩展调用系统组件,由 Android 和 iOS 系统进行组件的渲染;

  • 而flutter因为重写了一整套包括底层渲染逻辑和上层开发语言的完整解决方案,则是自己完成了组件渲染的闭环,所以能够保证视图在Android和iOS上渲染的高度一致性,并且高性能(代码执行效率与渲染性能可以与原生app相比)

flutter 发展状况

StackOverflow2019年对全球开发者调研,调研结果显示,flutter是处于前三位最受开发者喜爱的框架之一,可见flutter自推出以来就受到了广大开发者的喜爱

全球有很多品牌和公司已经开始使用flutter在他们的产品中,或者为flutter打造适配于他们产品的SDK,这里也不乏一些国内的大厂,特别是阿里就有多款的app使用flutter并上线

image.png
图:已使用flutter的大厂

flutter在中国社区发展状况

中国社区贡献了大量高质量的技术文章,也翻译了很多flutter的官方文档,可查看社区网站:flutter.cn,也组织了很多线上线下的活动,国内的开发者也特别积级的参与到了全球flutter社区的活动中

中国开发者对Flutter开源项目的贡献

多个中国公司的开发者给Flutter的代码库提交了代码,并且合并到了flutter的主SDK中,特别是阿里闲鱼团队的贡献。

flutter跨平台

flutter在移动端已经证明它在技术上和开发体验上有很多独到之处,google也希望开发者能把这些优势,开发体验上的也包括性能上的能带到其他各种各样的计算平台上面和设备上面,为此发布了flutter for web技术预览,特别是在桌面端以及在桌面端iot这个领域也做了一些积极的探索,长远的flutter多平台愿景理想状态是:每一个带有屏幕的设备上都可以运行flutter,在每一个带有屏幕的设备上都可以用flutter为最终用户带去非常流畅的用户体验。

image.png

主流跨端方案

目前比较主流的跨端方案

QT Electron RN Flutter
支持平台 ios、Android、Windows、Mac、Linux、Embedded Windows、Mac、Linux  ios, Android、(PC) Fuchsia、ios、Andriod、Windows、Mac、Linux、Embedded、Web
性能 较差
渲染能力
开发效率
生态 /
动态更新

对于Flutter For Windows目前处于技术预览阶段,今年有希望进入alpha,而Flutter For Windows Release版SDK,压缩后大小为7M,远小于QT、Electron,渲染能力同于flutter for android、ios。
Flutter 是构建 Google 物联网操作系统 Fuchsia 的 SDK,主打跨平台、高保真、高性能。

Flutter和RN的主要对比: RN是通过js调用原生界面渲染,主要瓶颈在js和原生的调用上。RN用js,用户学习成本低,容易上手。

flutter能支持的平台有Fuchsia、ios、Andriod、Windows、Mac、Linux、Embedded、Web,其中重点介绍一下flutter for web,目前成熟度善可。

flutter for web

flutter for web的技术预览,可以一边在浏览器运行,一边在手机运行,同一个代码库,浏览器只是用了flutter for web重新编译了一次,渲染效果是非常接近的,这也是谷歌做flutter的初衷,希望能够在移动端已经实现过的UI能够很容易的在web端也能够让用户去交互去使用。

flutter for web实现原理

flutter for web所有代码在flutter_web里,后面合到了flutter的主的SDK里。要讲原理,还需要回到移动端的架构图,它的图像渲染是用C++ flutter engine来实现的,这个engine里向上级的架构 暴露了dart ui这个库,所以上面的移动端代码和框架的代码都是通过dart ui这个接口来跟它的引擎进行通信,dart ui做什么呢,其实dart ui这个库不知道UI组件长什么样,也不知道布局怎么布,也不知道动画怎么画,也不知道手势,它只做一件非常简单的事情,就是把上级框架给它的图像数据画到屏幕上面
image.png
在设计 flutter for web 时候,尽可能的保留了上层框架和移动端的一致性,来达到代码的最大复用能力,在引擎这一层,在web标准之上,实现了flutter web engine,这个是dart ui库在web标准上的一个实现,它具体做什么事情呢?简要的来说,它跟移动端dart UI库的实现也是非常相似的,它的任务是将上层框架给它的图像对象通过
通过web 标准API的形式画到浏览器上面。
image.png
flutter for web engine会优先使用 HTML和CSS来实现图像的绘制,因为使用这两种方式可以最大化浏览器本身的性能优化,并且在页面缩放的时候不会出现像素化的问题。
对于某一些比较难以用HTML和CSS来绘制的页面元素,它会使用 Canvas 2D来进行绘画,而canvas 2D在性能上会有一些劣势,同时会有一些像素化问题,在这方面谷歌也在积极探索,在未来可能用CSS Paint API代替 Canvas,但CSS Paint API还是一个新的标准,浏览器的支持还不太到位,所以这是一个未来在研究上面要探索的方向。

flutter web engine 仍然需要依赖于flutter框架来为它提供像布局像构建 UI组件这样一些基础性的工作,它并不去直接处理这方面的任务。

Flutter for web能运用到什么场景

目前思考主要聚焦在两个场景:

  1. 第一个场景,开发移动应用的web端配套应用:

    1. 很多产品先出来时都是以移动端优先的,会先发一个移动端app,但移动端的应用还是会有很多局限,比如说它的屏幕可能不够大,看图片的时候或看视频的时候不够舒服,或者说用户可能会经常输入文字,比如聊天类的软件,移动设备上的键盘实在是不太方便,这个时候很多厂商会去做一个桌面端或者浏览器端的一个配套应用,让这些用户能够更方便的去查看信息或者说用桌面的键盘、鼠标去做一个信息录入的工作,这方面的例子非常的多,比如大家都在用的微信,就是一个先有了移动端的产品,然后再加了一个web端的补充程序,但是大家可能平常用的多的还是移动端的微信,我们也希望能够通过flutter for web首先服务于已经用flutter开发移动端的开发者,能够让他们快速地实现一个web端的配套应用,来满足用户在某些特定场景下对于输入输出设备的需求。
  2. 第二个应用场景,关注的是已经用flutter实现的高度交互的UI元素代码复用的问题,比如交互式的数据图表,这样的图表每次去实现一个都是挺花功夫的,并且也有很多细节要协调,那么,我们已经做过这次代码之后能不能把同样的这些组件很轻松的搬去web端呢,我们如果在web端再重新开发一次就有可能跟之前的设计稿有出入,在这里,通过flutter for web 帮助已经在移动端实现过这样一些高度交互的元素的开发者,最大限度的复用已经在移动端进行了投资,能够在在web端也实现跟设计稿达到高达一致的交互体验,类似的元素,还有嵌入式的小游戏,以及大应用里的一些工具,比如日历、汽车配置、投资组合的分析工具等这类具有很高的交互性,很多时候这个开发成本都可以通过代码共享来得到提高。

flutter for web 性能

目前数据,用github上flutter for web 样例程序做性能上的测试,示例应用在桌在浏览器上面达到60FPS没有大的问题,在移动端浏览器上面如果是最近两年出的比较新的手机也没有大的问题,但在更低端的手机,还有非常大的优化空间,还在不断的优化中

Flutter跨平台及flutter for web的两种方案架构图比较

image.png
图转自Flutter For Windows& Web预研
flutter for web的WebGL+WebAssembly版本目前只是在某个预览版本保留了,当时做了两套方案,后面发现js版的变得非常火了,所以最终切换了Js 版本,有可能以后,webassembly版变火切回来也不一定。

集团内外跨平台方案现状


image.png
图转自Flutter For Windows& Web预研

Flutter组件渲染原理


计算机图像显示的基本原理:计算机中图像的显示是由CPU、GPU和显示器一起完成,CPU 负责图像数据计算,GPU 负责图像数据渲染,而显示器则负责最终图像显示。

CPU 把计算好的、需要显示的内容交给 GPU,由 GPU 完成渲染后放入帧缓冲区,随后视频控制器根据垂直同步信号(VSync)以每秒 60 次的速度,从帧缓冲区读取帧数据交由显示器完成图像显示。

操作系统在呈现图像时遵循了这种机制,而 Flutter 也采用了这种底层方案:
尽可能快的在两个硬件时钟信号之间计算合成视图数据,然后通过skia交给GPU渲染:UI 线程使用 Dart 来构建视图结构数据,这些数据会在 GPU 线程进行图层合成,随后交给 Skia 引擎加工成 GPU 数据,而这些数据会通过 OpenGL 最终提供给 GPU 渲染。
image.png
图为flutter绘制原理

底层渲染能力统一了,也就不用担心与平台相关的渲染特性了,从而保证了同一套代码调用在 Android 和 iOS 平台上的渲染效果是完全一致的。

Flutter为何选择的是 Dart而不是Javascript?

Flutter 为什么选择了 Dart,而不是前端应用的准官方语言 JavaScript 呢?,Google 公司给出的原因很简单也很直接:Dart 语言开发组就在隔壁,对于 Flutter 需要的一些语言新特性,能够快速在语法层面落地实现;而如果选择了 JavaScript,就必须经过各种委员会和浏览器提供商漫长的决议.
当然也有一些更具说服力的理由,比如:Dart 同时支持即时编译 JIT 和事前编译 AOT:动态化方案,底层引擎修改,阿里维护了一个自己的引擎;Dart 集各种语言之长等等。

dart 语言如何在浏览器里运行呢?


flutter的应用跟框架都是用dart语言写的,dart语言写的代码如何在浏览器里运行呢,这里,我们用到了一个编译工具叫Dart2js compiler,它所做的工作是把dart代码编译成javascript,然后让框架代码和你的应用代码在浏览器里运行,dart2js这个工具已经存在了可能有七八年时间,在谷歌其实有非常大规模的应用,整个谷歌的广告业务的体系都是构建于dart语言之上,并且通过dart2js这个编译器实现浏览器端的运行能力,它是一个非常高效、非常成熟并且稳定的编译工具。

flutter的工程结构

先来看看flutter的工程目录结构
image.png
以上flutter工程实际上就是一个同时内嵌了Android和IOS原生子工程的父工程;虽然flutter是跨平台开发方案,但却需要一个容器最终运行到Android和IOS平台上。

与社区共建的状态管理解决方案-provider

以状态管理为例,状态state与UI的关系,大家如果 写过任何响应式编程模型的框架,都会对这个不陌生,就是你的UI的变化是由你的状态所驱动的,你的代码并不能直接去改这个UI里面去显示什么内容,这个对于UI架构的简洁性是有非常大的帮助,这里的状态就是状态管理里面的问题,状态管理要解决状态怎么样去架构,要放在应用的代码库的什么地方,它的读写操作应该是什么样的,所以也产生了很多五花八门的状态管理的方案

在官网上也把比较主流的由社区开发者提出的状态管理方法做了一个汇总,主流的有接近十个,开发者应该根据自己项目的实际需求去做需求分析,然后了解 每一个状态管理方法的优劣来做出一个最终的选择,但很多时候对于刚入手的开发者可能没有时间去帮具体的思考,或者说看到这么多选择,产生了一个选择困难,很有可能一不小心,就杀鸡用牛刀,选了一个最复杂的状态管理方法,所以在收到很多用户反馈希望能够给出一个官方推荐,来适用于大部分的应用场景,所以谷歌2019年IO大会上正式推荐了简单的状态管理方法:package:provider
image.png
provider有一个很有意思的背景,其实是由一个社区开发者remi开发的,在provider包出来之前,谷歌团队已经自己开始做一个类似的状态管理方案叫provide,在开始要做完时,社区 突然出来一个provider包,广受欢迎 ,谷歌在仔细比较后发现provider包其实解决一个很类似的问题,但是它解决的方法更加的容易上手,在很多方面的设计上比provide更加的合理,最后,谷歌放弃了快要写完的provide包状态管理方案,和这位社区开发者进行合作,共同推广并完善provider包,这对于社区的成长也是一个比较标志性的事件,也代表了flutter社区贡献者已经有能力去解决自己的问题。

开发者体验做持续 的优化

语法

new在1.0是必写关键字,在2.0变成可写关键字

Editor UI Guides

在编辑器里加了些额外线,提示UI组件层次,增强UI可读,在androidstudio上默认打开了,这个对效率的提升是非常大的,很多开发者一旦使用一段时间后,就已经回不去了,再也看不得之前的代码。
image.png

Flutter和Dart 持续优化

  • 改进了Flutter和原生混编(add-to-app)的机制和开发体验:将原生与flutter混编进行了产品化
    • 很多大厂都有现有工程,也都很想尝试flutter,但将现有工程推倒重来,是一个不可能的任务,所以需要一个更好的途径,让已经有现有项目的团队,一步一步的尝试flutter,在一些页面上先迁移,然后根据实际的效果达到进一步的对于已有项目的改造。
  • Dart语言本身也大积极的演进
  • 更容易理解的报错信息:未来的报错信息会更方便开发者回溯错误
  • 完善桌面基本交互方式




免责声明:文章版权归原作者所有,其内容与观点不代表Unitimes立场,亦不构成任何投资意见或建议。

ios

447

相关文章推荐

未登录头像

暂无评论