Flutter性能真的秒杀其它框架吗?
01. 认识Flutter
1.1. Flutter是什么?
相信很多看到这篇文章的童鞋都已经知道了Flutter是什么?
官方在两个地方都Flutter进行了解释:
对上面的话进行总结:
Flutter是一个UI SDK(Software Development Kit);
可以进行移动端(iOS、Android),Web端(Beta),桌面(technical preview),跨平台解决方案;
目前已经很多公司在用,Google、Facebook、阿里、腾讯;
特别是阿里的咸鱼团队,为Flutter做了非常多的贡献;
Flutter它是有一统大前端的野心的,并且它正在侵蚀iOS、Android这些原生开发;
1.2. Flutter特点是什么?
Google公司在国内做过很多宣讲,其中多次提到Flutter的几个特点:美观、快速、高效、开放。
美观:
使用Flutter内置美丽的Material Design和Cupertino widget(什么是widget,不着急)、丰富的motion API、平滑而自然的滑动效果和平台感知,为您的用户带来全新体验。
快速:
Flutter 的 UI 渲染性能很好。在生产环境下,Flutter 将代码编译成机器码执行,并充分利用 GPU 的图形加速能力,因此使用 Flutter 开发的移动应用即使在低配手机上也能实现每秒 60 帧的 UI 渲染速度。
Flutter 引擎使用 C++ 编写,包括高效的 Skia 2D 渲染引擎,Dart 运行时和文本渲染库。高效:
Hot Reload (热重载) ,在前端已经不是什么新鲜的东西,但在移动端之前一直是没有的
开放:
Flutter 是开放的,它是一个完全开源的项目。
02. 图像的渲染原理
2.1. 图像是如何显示的?
首先,你需要知道,我们在屏幕上可以看到的所有内容都是计算机绘制出来的图像
无论是视频还是GIF图片,还是操作系统给我们看到的图形化界面中的画面,都是图像。
比如下面的一个GIF图片:
如果我们对这个gif图片进行分解,它就会变成一张张的图像:
但是我们为什么能看到类似于动画的效果呢?为什么看到的不是一幅幅图像?这是因为它播放的速度非常快,研究表明:
当图片连续播放的频率超过16帧(16张图片),人眼就会感觉非常流畅,当少于16帧时,会感觉到卡顿;
所以我们平时看到的电影,通常都是24帧或者30帧的(李安之前拍摄120帧的电影,目的就是让图片间隔更小,画面更加的流畅);
我之前做过很长时间的流媒体技术,就是在和一帧帧的图像打交道;
2.2. 屏幕的刷新率
上面提到的概念就是帧率,CPU和GPU通常情况下需要为显示器提供一帧一帧的图像,让显示器来显示。 但是显示器是提供一帧就显示一帧吗?
并不是,显示器有自己的固定刷新频率;
比如iPhone的 60Hz、iPad Pro的 120Hz;
Hz赫兹是国际单位制中频率的单位,它是每秒中的周期性变动重复次数的计量;
也就是显示器我不管你给我提供了多少帧图像,我的刷新频率通常是固定的;
2.3. 帧率和刷新率的关系
帧率和刷新率是典型的 生产者-消费者 模型:
CPU/GPU 向 Buffer 中生成图像;
屏幕从 Buffer 中取图像、刷新后显示;
但是,但是上面的图像是否过于理想了了?
理想的情况是帧率和刷新频率相等,CPU/GPU绘制一帧;
屏幕从Buffer中取出一帧,绘制到屏幕上一帧;
但是实际往往它们的大小是不同的,特别是CPU/GPU绘制和我们依赖的技术框架有很多的关系;
如果没有锁来控制同步,很容易出现问题:
例如,当帧率大于刷新频率,当屏幕还没有刷新第 n-1 帧的时候,GPU 已经在生成第 n 帧了;
从上往下开始覆盖第 n-1 帧的数据,当屏幕开始刷新第 n-1 帧的时候,Buffer 中的数据上半部分是第 n 帧数据,而下半部分是第 n-1 帧的数据
显示出来的图像就会出现上半部分和下半部分明显偏差的现象,我们称之为 “tearing”(撕裂)
2.4. tearing的解决方案
为了解决单缓存的“tearing”问题,就出现了 双重缓存和 VSync :
注意,这里的VSync对于我们理解Flutter的原理非常重要;
两个缓存区分别为 Back Buffer 和 Frame Buffer。
GPU 向 Back Buffer 中写数据,屏幕从 Frame Buffer 中读数据;
VSync 信号负责调度从 Back Buffer 到 Frame Buffer 的复制操作;
工作流程大概是这样:
在某个时间点,一个屏幕刷新周期完成,VSync 信号产生,先完成复制操作,然后通知 CPU/GPU 绘制下一帧图像。
复制操作完成后屏幕开始下一个刷新周期,即将刚复制到 Frame Buffer 的数据显示到屏幕上。
但是一定要注意:
在这种模型下,只有当 VSync 信号产生时,CPU/GPU 才会开始绘制;
所以我们应该明白,VSync对于CPU/GPU的绘制是非常重要的,相当于会给它们发送指令;
2.5. 双重缓存存在的问题
双重缓存的缺陷在于:当 CPU/GPU 绘制一帧的时间过长(比如超过16ms)时,会产生 Jank(画面停顿,甚至空白)。
蓝色代表 CPU 生成 Display List;
绿色代表 GPU 执行 Display List 中的命令从而生成帧;
黄色代表生成帧完成,在屏幕上显示;
双缓存模型中:
CPU生成蓝色B的数据,由GPU进行B的绘制,但是这个过长由于过长,那么第二个A就产生了Jank。
B在屏幕上显示之后,发出Vsync信号,A开始绘制,但是由于绘制时间过长,第二个B位置又产生了Jank
如何解决双重缓存的问题了?
在第二个A展示,Vsync信号发出后,直接绘制C Buffer
在第一个B展示,Vsync信号发出后,绘制A Buffer
因为C已经在缓存中,可以直接从缓存中取出C Buff来进行展示,依次类推
其实本质是在每次Vsync信号发出后,多缓存一个Buffer作为备用
但是三重缓存可以完全解决Jank问题吗?
当然不行,如果CPU和GPU无法快速的为Buffer提供一帧帧画面,Jank现象依然会大量出现;
03. Flutter的核心优势
3.1. 为什么RN性能有劣势?
在寻求最佳跨平台解决方案的过程中,无疑React Native 是之前最优秀的一个。
React Native (简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,是Facebook早先开源的JS框架 React 在原生移动应用平台的衍生产物,目前支持iOS和安卓两大平台。
RN的技术架构是怎么样的了?
RN的技术架构决定它生成Buffer的性能出现瓶颈:
RN使用JavaScript语言,类似于HTML的JSX,以及CSS来开发移动应用,因此熟悉Web前端开发的技术人员只需很少的学习就可以进入移动应用开发领域;
并且在保留基本渲染能力的基础上,用原生自带的 UI 组件实现核心的渲染引擎,从而保证了良好的渲染性能;
但是,由于RN的本质是通过JavaScript VM调用原生接口,通信相对比较低效,而且框架本身不负责渲染,而是是间接通过原生进行渲染的;
所以必然会出现性能瓶颈,无法保证底层GPU的高效渲染;
在RN上做出非常多贡献的Airbnb之前就宣布放弃RN,而转向Native进行开发;
3.2. Flutter的渲染原理
从Flutter出现到现在,我个人就一直非常看好,因为它可能才是我们很久以来所期待的跨平台的终极解决方案。
我们直接看下面这幅图来对比flutter - native - rn的区别:
不存在任何中间商赚差价!!
Flutter利用Skia绘图引擎,直接通过CPU、GPU进行绘制,不需要依赖任何原生的控件
Android操作系统中,我们编写的原生控件实际上也是依赖于Skia进行绘制,所以flutter在某些Android操作系统上甚至还要高于原生(因为原生Android中的Skia必须随着操作系统进行更新,而Flutter SDK中总是保持最新的)
而类似于RN的框架,必须通过某些桥接的方式先转成原生进行调用,之后再进行渲染。
Flutter的渲染闭环:
直接看这幅图很难理解两个GPU的作用:
GPU将信号同步到 UI 线程 - UI 线程用Dart来构建图层树
图层树在GPU 线程进行合成 - 合成后的视图数据提供给Skia 引擎
Skia 引擎通过OpenGL 或者 Vulkan将显示内容提供给GPU
第一个GPU在什么时候开始将同步信号同步给UI线程了?
当收到VSync信号的时候,这就是为什么我们前面花了大量的篇幅来讲解图像渲染原理的原因;
它的优势到底是什么?
渲染闭环
从上面的图像中我们发现Flutter框架自己形成了一个渲染闭环;
这个渲染闭环完成不需要依赖原生的Android或iOS控件来完成一帧图像的渲染;
一切的一切工作,都由Flutter自身来生成-组合-渲染;
这才是Flutter的核心优势所在;
04. 如何学习Flutter?
4.1. 大前端学不动了
很多人看到Google的flutter框架的时候,第一反应就是:别出新东西了,实在学不动了。
但是作为大前端开发者就是这样,各种折腾:
客户端开发者:从Android到iOS,或者从iOS到Android,到RN,甚至现在越来越多的客户端开发者接触前端相关知识(Vue、React、Angular、小程序)
前端开发者:从jQuery到AngularJS,到三大框架并行:Vue、React、Angular,还有小程序,甚至现在也要接触客户端开发(比如RN、Flutter)
大前端开发就是,不像服务器一样可能几年甚至几十年还是那一套的东西,新技术会层出不穷。
但是每一样技术的出现都会让惊喜,因为他必然是解决了之前技术的某一个痛点的,所以我们要学会拥抱这种变化。
并且很多知识在学习的过程中,你会发现他们都是相同的,并不是说都要从头再来,最重要的是建立属于自己的知识体系。
4.2. Flutter学得会吗?
很多人对于学习flutter望而却步,主要是基于两点考虑:
学习一门全新的语言:dart,也就是你必须从你原来熟悉的语言JavaScript或Swift或Java或其他转向这门全新的语言。
flutter是全新的跨平台技术,意味着自己需要去学习很多新的内容:开发模式、框架原理、底层原理渲染机制等等
dart语言并不复杂,而且非常现代化
首先,所有编程语言都是大同小异,你花两天的时间去练习一定可以快速掌握它。(我个人一直认为一个开发者不可能在整个开发生涯只会一种编程语言,不现实!)
其次,dart语言几乎集结了现代语言所有好用的特性,并不复杂(后面我们慢慢来学)
flutter并没有非常多创新的概念:
flutter从其他框架中借鉴了非常多设计思想:框架原理、底层渲染机制、事件处理方式都大同小异。
声明式编程方式、组件化开发也是现代框架都有的特性,比如Vue、React。
【福利来了】为了大家更好的学习Flutter,给大家强烈推荐本文的作者——小码哥教育王红元老师讲授的《Flutter从入门到实战》课程,帮助大家快速掌握Flutter开发精髓,让学习越来越轻松。
本次课程,由小码哥教育王红元老师亲授。
课程内容也是覆盖了从Dart、Flutter基础入门,到深入Flutter,到项目实战整个完整的学习体系和学习路线,一定能带着你,深入浅出的快速拿下Flutter!
↑↑如果学习,务必添加↑↑
目前,已经有超过500名学员,已经在跟着王红元老师学习Flutter了,你还不行动起来吗?你参加,我们提升你的竞争力,你不参加,我们提升你未来对手的竞争力!!
这次我们为大家带来的【小码哥Flutter从入门到实战】课程,原价398元的课程,入群之后咨询老师,还有超值优惠!
除了课堂上有老师指导,课下有老师答疑,群里还有班主任老师的督课服务,效果怎么样,同学的反馈说话!
学习的脚步从来都不应该停止,尤其是互联网行业,激烈的竞争环境、实时更新的技术都在提醒我们:每时每刻都要抓紧时间和机会学习,提升自己的技术实力,实现自我逆袭和蜕变!
在懦夫和犹豫不决者眼里,任何事情看上去都是不会成功的!从现在就马上行动起来吧!
↑↑ 扫码立即开始学习吧!↑↑