开源网站建设教程,2022可以用手机看的,wordpress浏览器跳转,做个网站设计多少钱1、Web 性能差#xff0c;跟原生 App 存在肉眼可见的差距#xff1b;
2、React Native 跟 Web 相比#xff0c;支持的能力非常有限#xff0c;特定长场景问题#xff0c;需要三端团队一个一个处理#xff1b;
3、Web 浏览器的安卓碎片化严重#xff08;感谢 X5#x…1、Web 性能差跟原生 App 存在肉眼可见的差距
2、React Native 跟 Web 相比支持的能力非常有限特定长场景问题需要三端团队一个一个处理
3、Web 浏览器的安卓碎片化严重感谢 X5腾讯的同学过得相对轻松一些。
为了解决上面的问题Flutter 出现了
一套代码可以运行在两端自绘 UI脱离平台也可以简单的把它理解为一个浏览器的子集。
铺垫了这么多就是为了帮助您回忆起技术发展的脉络和技术趋势可以更好的理解下面即将要表达的文稿下面我们正式开始介绍 Flutter。
2Flutter 实现原理
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 时间也比较短暂。引擎源码层面目前也没有深入的涉猎。了解的方式可以通过自己阅读源码或者找谷歌、阿里、美团、以及我司的开发者帮忙。从技术角度来了解这些在需要的阶段不会成为大家的瓶颈。毕竟商业世界充满了壁垒而应用层面的技术本身是开放的。
3Flutter 应用层语言 Dart
简单描述一下 JIT 与 AOT
JIT 在运行时即时编译在开发周期中使用可以动态下发和执行代码开发测试效率高但运行速度和执行性能则会因为运行时即时编译受到影响。AOT 即提前编译可以生成被直接执行的二进制代码运行速度快、执行性能表现好但每次执行前都需要提前编译开发测试效率低。
Dart 是什么
它的目标在于成为下一代结构化 Web 开发语言。Dart 发布于 2011 年 10 月 Google 的GOTO 国际软件开发大会。是一种基于类编程语言class-based programminglanguage在所有浏览器都能够有高性能的运行效率。Chrome 浏览器内置了 DartVM可以直接高效的运行 dart 代码2015 年被移出。支持 Dart 代码转成 Javascript直接在 Javascript引擎上运行。dart2js
Dart 的特点
开发时 JIT提升开发效率发布时 AOT提升性能。不会面对 JS 与 Native 之间交互的问题了。Dart 的内存策略采用多生代算法与 Node 有一些类似。线程模型依旧是单线程 Event Loop 模型通过 isolate 进行隔离可以降低开发难度与 Node 也非常类似。Dart 的生态这个跟 Node.js 差距十分明显npm 还是行业中最活跃的。而静态语法与排版方式纯前端入门还是有一定成本。
备注
1TS 可以一定程度上帮助 JS 添加一些静态检测但本质上依旧是无法达成这样的效果 关于入门成本这个问题如果您想深入我相信这都不会成为问题。关键看是否能为业务和团队带来价值。
Flutter 选择 Dart 的原因
健全的类型系统同时支持静态类型检查和运行时类型检查。代码体积优化TreeShaking编译时只保留运行时需要调用的代码不允许反射这样的隐式引用所以庞大的 Widgets 库不会造成发布体积过大。丰富的底层库Dart 自身提供了非常多的库。多生代无锁垃圾回收器专门为 UI 框架中常见的大量 Widgets 对象创建和销毁优化。跨平台iOS 和 Android 共用一套代码。JIT AOT 运行模式支持开发时的快速迭代和正式发布后最大程度发挥硬件性能。Native Binding。在 Android 上v8 的 Native Binding 可以很好地实现但是 iOS 上的 JavaScriptCore 不可以所以如果使用 JavaScriptFlutter 基础框架的代码模式就很难统一了。而 Dart 的 Native Binding 可以很好地通过 Dart Lib 实现。
4Flutter 实现思路
看到了上面的介绍这里总结一下 Flutter 的实现思路。它开辟了新的设计理念实现了真正的跨平台的方案自研 UI 框架它的渲染引擎是 Skia 图形库来实现的而开发语言选择了同时支持 JIT 和 AOT 的 Dart。不仅保证了开发效率同时也提升了执行效率。由于 Flutter 自绘 UI 的实现方式因此也尽可能的减少了不同平台之间的差异。也保持和原生应用一样的高性能。因此Flutter 也是跨平台开发方案中最灵活和彻底的那个它重写了底层渲染逻辑和上层开发语言的一整套完整解决方案。
彻底跨端Flutter 构建了一整套包括底层渲染、顶层设计的全套开发套件。这样不仅可以保证视图渲染在 Android 和 IOS 上面的高度一致也可以保证渲染和交互性能媲美原生应用。与现有方案核心区别类 RN 方案JS 开发Native 渲染。数据通信 bridgeHybird 浏览器渲染 原生组件绘制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 的存在
Flutter 底层的渲染能力得到了统一不在需要使用做双端适配通过 OpenGL、GPU不需要依赖原生的组件渲染框架。Flutter 可以最大限度的抹平平台差异提升渲染效率和性能。
2Flutter 的渲染流程
用户可以看到一张图像展示至少需要三类介质CPU、GPU 和 显示器。CPU 负责图像的数据计算GPU 负责图像数据的渲染而显示器是最终图片展示的载体。CPU 拿到需要上屏的数据做处理和加工处理完成之后交给 GPUGPU 在渲染之后将数据放入帧缓冲区随后随着控制同步信号 (VSync)以周期性的频率从缓冲区内读出数据在显示器上进行图像呈现。而且操作系统就是一个无限循环的机制不停的重复上面的操作进行显示器的更新. Flutter 的渲染整体流程也是这样的 Dart 进行视图数据的合成然后交给 Skia 引擎进行处理处理之后再交给 GPU 进行数据合成然后准备上屏。当一帧图像绘制完毕后准备绘制下一帧时显示器会发出一个垂直同步信号VSync所以 60Hz 的屏幕就会一秒内发出 60 次这样的信号。
3Flutter 绘制流程 如上图所示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 被送入 EngineEngine 会把 Layer Tree 调度到 GPU 线程在 GPU 线程内合成compsiteLayer 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 的 组件 即可。 一种结构化数据的抽象包含了组件的布局、渲染属性、事件响应信息等。
1Widget 类似 React VM 的 F(x) Y 中的 x 存在
Flutter 中的 Widget 是完全不可变的只要当视图发生变化Flutter 就会重新创建一个新的 Widget 进行更新。即是 React 也是有一定的数据 Diff 的策略而这里变更即创建的方式会带来大量的销毁和重建的过程是否非常消耗性能
Widget 对标的是 标识 React 的虚拟 DOM 节点的 数据描述 JSX不是真实渲染的页面 DOM。只是数据的抽象不涉及视图渲染。并且 Widget 具有不可变性也提升了 Widget 本身的复用性。因此并没大量的性能消耗而 Dart 的作为静态语言的运行速度也会有着超越 JS 的性能。
2Element 是 Widget 的一个实例化对象
Element 承载了视图构建的上下文数据是连接结构化的配置信息到完成最终渲染的桥梁 Element 是一个可变的数据结构 可以大致理解为 Virtual DOM。可以进行 diff 更新 可以将真正需要修改的数据同步到 RenderObject 中。最大程度的降低渲染视图的修改提升渲染效率。
3RenderObject 负责视图渲染的对象
Flutter 的渲染分为 4 个部分。布局、绘制、合成、渲染其中 布局和绘制是在 RenderObject 中完成的。 Flutter 采用深度优的方式渲染对象树确定树中的各个对象的位置和尺寸并把它绘制到不同图层 绘制完成之后交给 Skia 在 VSync 信号同步时从渲染树合成位图然后交给 CPU 进而完成上 屏。
4Widget 同样分为有状态 和 无状态组件
无状态控件 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、引文
Flutter 官网Flutter 中文网Flutter 实战闲鱼技术博文
作者 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行业感兴趣的新人
都欢迎加入我们的的圈子技术交流、学习资源、职场吐槽、大厂内推、面试辅导让我们一起学习成长
资料⬅专栏获取