ToB企服应用市场:ToB评测及商务社交产业平台

标题: 全面明白-Flutter(万字长文,深度剖析) [打印本页]

作者: 用多少眼泪才能让你相信    时间: 2024-8-13 12:47
标题: 全面明白-Flutter(万字长文,深度剖析)
1、Web 性能差,跟原生 App 存在肉眼可见的差距;
2、React Native 跟 Web 相比,支持的本领非常有限,特定长场景题目,需要三端团队一个一个处置惩罚;
3、Web 欣赏器的安卓碎片化严重(感谢 X5,腾讯的同学过得相对轻松一些)。
为了办理上面的题目,Flutter 出现了:
一套代码可以运行在两端;自绘 UI,脱离平台,也可以简单的把它明白为一个欣赏器的子集。
铺垫了这么多,就是为了帮助您回想起技术发展的脉络和技术趋势,可以更好的明白下面即将要表达的文稿,下面我们正式开始先容 Flutter。
2)Flutter 实现原理

Flutter 能先容的技术点其实非常多,这里找了一些具有代表性的技术项,联合自己的明白跟大家分享一下。包罗计划思路、渲染方式、UI 的生命周期。由于这几个点,跟 React 技术栈风格非常相似,以这种思考结构去对比先容,可以帮助大家更好的明白这项技术本身。
Flutter 团体架构计划

Google 了一下关键词,搜素得到了这张图片,从下向上举行一些形貌:
Embedder:是操纵体系适配层,实现了渲染 Surface 设置,线程设置,以及平台插件等平台相关特性的适配。从这里我们可以看到,Flutter 平台相关特性并不多,这就使得从框架层面保持跨端一致性的成本相对较低。
Flutter Engine:这是一个纯 C++实现的 SDK,此中席卷了 Skia 引擎、Dart 运行时、笔墨排版引擎等。不外说白了,它就是 Dart 的一个运行时,它可以以 JIT、JITSnapshot 或者 AOT 的模式运行 Dart 代码。在代码调用 dart:ui 库时,提供 dart:ui 库中 Native Binding 实现。 不外别忘了,这个运行时还控制着 VSync 信号的传递、GPU 数据的填充等,并且还负责把客户端的事故传递到运行时中的代码。详细的绘制方式,我们放在背面形貌。
Flutter Framework:这是一个纯 Dart 实现的 SDK,类似于 React 在 JavaScript 中的作用。它实现了一套基础库, 用于处置惩罚动画、画图和手势。并且基于画图封装了一套 UI 组件库,然后根据 Material 和 Cupertino 两种视觉风格区分开来。这个纯 Dart 实现的 SDK 被封装为了一个叫作 dart:ui 的 Dart 库。我们在使用 Flutter 写 App 的时候,直接导入这个库即可使用组件等功能。
PS:虽然很早知道 Flutter,但现实写 Flutter 时间也比力短暂。引擎源码层面,目前也没有深入的涉猎。了解的方式可以通过自己阅读源码,或者找谷歌、阿里、美团、以及我司的开发者帮忙。从技术角度来了解这些,在需要的阶段,不会成为大家的瓶颈。毕竟商业天下充满了壁垒,而应用层面的技术本身是开放的。
3)Flutter 应用层语言 Dart

简单形貌一下 JIT 与 AOT

Dart 是什么
它的目标在于成为下一代结构化 Web 开发语言。Dart 发布于 2011 年 10 月 Google 的"GOTO 国际软件开发大会"。是一种基于类编程语言(class-based programminglanguage),在所有欣赏器都可以或许有高性能的运行服从。Chrome 欣赏器内置了 DartVM,可以直接高效的运行 dart 代码(2015 年被移出)。支持 Dart 代码转成 Javascript,直接在 Javascript引擎上运行。dart2js
Dart 的特点

备注:

Flutter 选择 Dart 的原因

4)Flutter 实现思路

看到了上面的先容,这里总结一下 Flutter 的实现思路。它开辟了新的计划理念,实现了真正的跨平台的方案,自研 UI 框架,它的渲染引擎是 Skia 图形库来实现的,而开发语言选择了同时支持 JIT 和 AOT 的 Dart。不但保证了开发服从,同时也提拔了执行服从。由于 Flutter 自绘 UI 的实现方式,因此也尽可能的减少了不同平台之间的差别。也保持和原生应用一样的高性能。因此,Flutter 也是跨平台开发方案中最灵活和彻底的谁人,它重写了底层渲染逻辑和上层开发语言的一整套完备办理方案

3、Flutter 的 UI 渲染方案

渲染方案是 Flutter 目前独特的计划形态,就是由于渲染自闭环,才能真正跨平台。谈到 UI 渲染方案,作为前端开发,我们是绕不外如今如火如荼的三大框架的。为什么要谈类 React 方案呢?由于 Flutter 的计划方案,与 React 计划具有一样的思路。在渲染这里我们会谈及控件、渲染原理、以及生命周期。
Flutter 是如何举行页面渲染的呢?传统 Web 是通过欣赏器,而 Flutter 是自绘。所谓自绘就是用户界面上 Flutter 自己绘制到界面,无需依赖 IOS 和 Android 原生本领,是通过一个叫做 Skia 引擎举行页面画图。
1)先容一下 Skia

Skia 是一个 2D 的画图引擎库,其前身是一个向量画图软件,Chrome 和 Android 均采用 Skia 作为画图引擎。Skia 提供了非常友好的 API,并且在图形转换、笔墨渲染、位图渲染方面都提供了友好、高效的体现。Skia 是跨平台的,所以可以被嵌入到 Flutter 的 iOS SDK 中,而不消去研究 iOS 闭源的 CoreGraphics / Core Animation。
Skia 是用 C++ 开发的、性能彪悍的 2D 图像绘制引擎,其前身是一个向量画图软件。Skia 在图形转换、笔墨渲染、位图渲染方面都体现杰出,并提供了开发者友好的 API。Android 自带了 Skia,所以 Flutter Android SDK 要比 iOS SDK 小很多。正是得益于 Skia 的存在:

2)Flutter 的渲染流程

用户可以看到一张图像展示,至少需要三类介质:CPU、GPU 和 显示器。CPU 负责图像的数据计算,GPU 负责图像数据的渲染,而显示器是终极图片展示的载体。CPU 拿到需要上屏的数据做处置惩罚和加工,处置惩罚完成之后交给 GPU,GPU 在渲染之后将数据放入帧缓冲区,随后随着控制同步信号 (VSync)以周期性的频率,从缓冲区内读出数据,在显示器上举行图像呈现。而且操纵体系就是一个无穷循环的机制,不绝的重复上面的操纵,举行显示器的更新.

Flutter 的渲染团体流程也是如许的, Dart 举行视图数据的合成,然后交给 Skia 引擎举行处置惩罚,处置惩罚之后再交给 GPU 举行数据合成,然后预备上屏。当一帧图像绘制完毕后预备绘制下一帧时,显示器会发出一个垂直同步信号(VSync),所以 60Hz 的屏幕就会一秒内发出 60 次如许的信号。
3)Flutter 绘制流程


如上图所示,Flutter 渲染流程分为 7 个步调:
起首是获取到用户的操纵,然后你的应用会因此显示一些动画 ;
接着 Flutter 开始构建 Widget 对象。Widget 对象构建完成后进入渲染阶段,这个阶段主要包罗三步:

末了的光栅化由 Engine 层来完成。
4)布局

布局时 Flutter 深度优先遍历渲染对象树。数据流的传递方式是从上到下传递束缚,从下到上传递大小。也就是说,父节点会将自己的束缚传递给子节点,子节点根据接收到的束缚来计算自己的大小,然后将自己的尺寸返回给父节点。整个过程中,位置信息由父节点来控制,子节点并不关心自己地点的位置,而父节点也不关心子节点详细长什么样子。

为了防止因子节点发生变化而导致的整个控件树重绘,Flutter 加入了一个机制——RelayoutBoundary,在一些特定的情况下 Relayout Boundary 会被自动创建,不需要开发者手动添加。
边界:Flutter 使用边界标志需要重新布局和重新绘制的节点部门,如许就可以制止其他节点被污染或者触发重修。就是控件大小不会影响其他控件时,就没须要重新布局整个控件树。有了这个机制后,无论子树发生什么样的变化,处置惩罚范围都只在子树上。

缓存:要提拔性能体现,缓存也是少不了的。在 Flutter 中,险些所有的 Element 都会具有一个 key,这个 key 是唯一的。当子树重修后,只会刷新 key 不同的部门,而节点数据的复用就是依靠 key 来从缓存中取得。
在确定每个空间的位置和大小之后,就进入绘制阶段。绘制节点的时候也是深度遍历绘制节点树,然后把不同的 RenderObject 绘制到不同的图层上。
5)绘制

在布局完成之后,渲染对象树中的每个节点都有了明确的尺寸和位置。Flutter 会把所有的 Element 绘制到不同的图层上。与布局过程类似,绘制的过程也是深度优先遍历,先绘制父节点,然后绘制子节点。以下图为例:节点 1、节点 2、节点 3、4、5,最好绘制节点 6。

如上图可以看到一种场景,就是比如视图可能会合并,导致 节点 2 的子节点 5 与它的兄弟节点 6 处于同一个图层,如许会导致当 节点 2 需要重绘的时候,与其无关的节点 6 也会被重绘,带来性能题目。
为了办理上面的题目,Flutter 提出了布局边界的机制 ——重绘边界(Repaint-Boundary)。在重绘边界内,Flutter 会逼迫切换新的图层,如允许以制止边界内外的互相影响,制止无关内容虽然处于同一个层级导致的不须要的重绘。

重绘边界的一个典型场景就是 ScrollView。ScorllView 滚动的时候会刷新视图,从而触发内容重绘,而当滚动内容重绘时,一般情况下别的内容是不需要被重绘的。这个时候重绘边界就非常有价值了。
**这里简单明白,就是更风雅化的对控件的更新,举行了小范围的控制。在时间复杂度和空间复杂度中举行衡量。**未来我们优化业务,大概率也会优化这里,找到自身业务的平衡点。
6)合成和渲染

最上面已经展示了 Flutter 的 7 层渲染流水线(Renderingpipline)的图里。这里主要形貌一下对合成和渲染的明白。渲染流水线是由垂直同步信号(Vsync)驱动的。这个概念很类似我们平时说的 FPS 的概念,每秒 60 帧,过低的频率会显得页面很卡。当每一次 Vsync 信号到来以后,Flutter 框架会按照图里的序次执行一系列动作:动画(Animate)、构建(Build)、布局(Layout)和绘制(Paint)
终极天生一个场景(Scene)之后送往底层,由 GPU 绘制到屏幕上。

Flutter App 只有在状态发生变化的时候需要触发渲染流水线。当你的 App 无任何状态改变的时候,Flutter 是不需要重新渲染页面的。所以,Vsync 信号需要 Flutter App 去调理。比如,我们在 Widget 内使用了 setState 方法改变了控件的状态。
整个渲染流水线是运行在 UI 线程里的,以 Vsync 信号为驱动,在框架渲染完成之后会输出 Layer Tree。Layer Tree 被送入 Engine,Engine 会把 Layer Tree 调理到 GPU 线程,在 GPU 线程内合成(compsite)Layer Tree,然后由 Skia 2D 渲染引擎渲染后送入 GPU 显示。这里提到 Layer Tree 是由于我们即将要分析的渲染流水线绘制阶段终极输出就是如许的 LayerTree。所以绘制阶段并不是简单的调用 Paint 函数这么简单了,而是很多地方都涉及到 Layer Tree 的管理。
Flutter 只关心向 GPU 提供视图数据,GPU 的 VSync 信号同步到 UI 线程,UI 线程使用 Dart 来构建抽象的视图结构,这份数据结构在 GPU 线程举行图层合成,视图数据提供给 Skia 引擎渲染为 GPU 数据,这些数据通过 OpenGL 或者 Vulkan 提供给 GPU。
这里形貌一下合成的概念,所谓合成就是由于我们绘制的页面结构复杂,如果直接交付给画图引擎去举行图层渲染,可能会出现大量的渲染内容重绘,因此,需要先辈性一次图层合成,就是说先把所有的图层根据大小、层级等规则计算出终极的显示效果,将雷同的图层合并,简化渲染树,提拔渲染服从。
Flutter 会将合成之后的数据,交给 Skia 举行页面二维图层的渲染。
4、Widget 控件的更新计谋

在这一个部门我们对比着 React 的计划方式对比着看一下 Flutter 的实现,在 React 中您可以看到三种很重要的名称。JSX、Virtual Dom、真实 Dom,而在 Flutter 中我们依然可以看到对应的三类抽象的数据结构分别是 Widget、Element 和 RenderObject,他们的功能与 React 内三个数据抽象有异曲同工之处。Flutter 绘制界面的基础是 Widget,也就是形貌页面的最小模块。
Flutter 的核心计划头脑就是 “统统皆 Widget”:
前端同学可以把 Widget 明白为 Web Component 的 组件 即可。 一种结构化数据的抽象,包罗了组件的布局、渲染属性、事故响应信息等。
1)Widget 类似 React VM 的 F(x) = Y 中的 x 存在

Flutter 中的 Widget 是完全不可变的!只要当视图发生变化,Flutter 就会重新创建一个新的 Widget 举行更新。便是 React 也是有肯定的数据 Diff 的计谋,而这里变动即创建的方式,会带来大量的烧毁和重修的过程,是否非常消耗性能?
Widget 对标的是 标识 React 的虚拟 DOM 节点的 数据形貌 JSX,不是真实渲染的页面 DOM。只是数据的抽象,不涉及视图渲染。并且 Widget 具有不可变性,也提拔了 Widget 本身的复用性。因此并没大量的性能消耗,而 Dart 的作为静态语言的运行速率,也会有着超越 JS 的性能。
2)Element 是 Widget 的一个实例化对象

Element 承载了视图构建的上下文数据,是连接结构化的设置信息到完成终极渲染的桥梁; Element 是一个可变的数据结构, 可以大抵明白为 Virtual DOM。可以举行 diff 更新; 可以将真正需要修改的数据同步到 RenderObject 中。最大程度的低落渲染视图的修改,提拔渲染服从。
3)RenderObject 负责视图渲染的对象

Flutter 的渲染分为 4 个部门。布局、绘制、合成、渲染,此中 布局和绘制是在 RenderObject 中完成的。 Flutter 采用深度优的方式渲染对象树,确定树中的各个对象的位置和尺寸,并把它绘制到不同图层, 绘制完成之后交给
Skia 在 VSync 信号同步时从渲染树合成位图,然后交给 CPU 进而完成上​
屏。
4)Widget 同样分为有状态 和 无状态组件

无状态控件 StatelessWidget 类似 React 的 PFC。 有状态控件 StatefulWidget 就是 React 的 组件。 犹如 react 组件一样,使用有状态组件是有成本的。正确的评估你的需求,制止使用无意义的有状态组件。
这里比力大的区别,是 Flutter 直接把 Widget 计划成为了一个不可变的! 这也导致了技术方案的实现上存在了差别。
5)既然看到了 Widget,那肯定会有生命周期的存在

由于篇幅限制,这里就不在详细先容了,简单形貌一下,生命周期,让您有个影响。
**创建:**构造函数 --> initState --> didChangeDependencies --> build
更新: 主要由三个方法触发:setState、didChangeDependencies 和 didUpdateWidget。
烧毁: 体系会调用 diactivate 和 dispose 这两个方法,来移除或烧毁组件。
这里多了 APP 生命周期的概念,在传统 Web 我们相对关注较少

从后台切入前台:paused -> inactive -> resumed;
从前台退到后台:resumed-> inactive-> paused;
5、学习路线


粗略了整理了一下我近来这 2 周体验开发过程中认知的学习范围,这上面除了跟 APP 相关的部门,大部门场景已经通过代码体验和实践过了。这里由于篇幅限制,就不在一一的先容了。最重要的是关注 Flutter 的官方文档。
其次,找了三个实例,跟您分享,您可以 clone 下来,更细节的体验一下:
布局案例:https://github.com/yang7229693/flutter-study
代码实例: https://github.com/nisrulz/flutter-examples
FlutterDemo: https://github.com/OpenFlutter/Flutter-Notebook
除了上面列出的这些,还有很多要做,比如 运维、调试、自动化测试、兼容性、客户端 SDK 封装、国际化等等。当然对于开发者来说,工程化、调试、组件化都是非常重要的实践内容。
6、引文


作者: haigecao,腾讯 CSIG Web 开发工程
末了

题外话,我在一线互联网企业工作十余年里,引导过不少偕行后辈。帮助很多人得到了学习和成长。
我意识到有很多履历和知识值得分享给大家,也可以通过我们的本领和履历解答大家在IT学习中的很多困惑,所以在工作繁忙的情况下还是对峙各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提拔,故此将并将重要的Android进阶资料包罗自定义view、性能优化、MVC与MVP与MVVM三大框架的区别、NDK技术、阿里面试题精编汇总、常见源码分析等录播视频免费分享出来。
【Android学习PDF+学习视频+面试文档+知识点笔记】
【Android头脑脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的头脑脑图,给大家参考一个方向。

【Android进阶学习视频】、【全套Android面试秘笈】可以简信我【学习】查看免费领取方式!
希望我可以或许用我的力量帮助更多渺茫、困惑的朋友们,帮助大家在IT蹊径上学习和发展~
末了

小编这些年深知大多数初中级Android工程师,想要提拔自己,每每是自己摸索成长,自己不成体系的自学效果低效漫长且无助
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初志也很简单,就是希望可以或许帮助到想自学提拔又不知道该从何学起的朋友。
一个人可以走的很快,但一群人才能走的更远!岂论你是正从事IT行业的老鸟或是对IT行业感爱好的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
资料⬅专栏获取
升自己,每每是自己摸索成长,自己不成体系的自学效果低效漫长且无助**。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初志也很简单,就是希望可以或许帮助到想自学提拔又不知道该从何学起的朋友。
[外链图片转存中…(img-Hg2tbZgM-1719098255301)]一个人可以走的很快,但一群人才能走的更远!岂论你是正从事IT行业的老鸟或是对IT行业感爱好的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
资料⬅专栏获取

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4