大家好我是 《Flutter开发实战详解》 的作者郭树煜,很高兴今天有机会在这里和大家分享关于 Flutter 和大前端的话题,今天我主要就从 Flutter 、大前端和写作 这三个方面给大家分享一些我的理解和想法。
1、 我为什么选择 Flutter?
初识Flutter
我接触 Flutter 的契机是因为要做一场公司的内部技术分享,因为公司要做技术选型,所以那时候分享的主题是 《移动端跨平台开发的现状和分析》 ,而恰好那时候 Flutter 初出茅庐,就被我加入到 ReactNative 、Weex 的对比分析中。
初识 Flutter 的我对 Flutter 的感觉就是:“什么东西?”
是的,我对Flutter 的第一感觉并不看好:
- 首先 Flutter 的嵌套写法就恶心到我了;
- 另外 Flutter 选择了 Dart 而不是 JS,要知道 Dart 语言本来就是经历过“滑铁卢”的;
- 最后当时 Flutter 的第三方支持实在少的可怜
但是当时素材不够,为了凑字数,所以我还是把 Flutter 加入到了我的调研素材里。
当然,真香定律,随着了解的深入,我发现我之前 “草率了!”
因为经历过 ReactNative 和 Weex,所以跨平台对我最大的困扰其实是性能和兼容性适配,这类问题里最具代表性的就是 Airbnb 当时刷屏的《为什么 Airbnb 放弃了 React Native?》 这篇文章,文中大致的意思是: ReactNative 在后期不断需要面对特定的兼容性和性能问题,最终让 Airbnb 放弃了跨平台开发。
而在不断深入了解 Flutter 之后,首先最让我惊喜的就是它的渲染。
我还记得当时在 Android 上开发完基本项目效果后,第一次在 iOS 上运行完居然没有出现问题,并且渲染结果还完全一致,甚至我在 Android 上使用原本应该 Android 上特有的界面效果,也自然地出现在 iOS上,这就让 Flutter 对我产生了一种极大的吸引。
Flutter 为什么能够实现优秀的跨平台渲染效果呢?这就涉及到 Flutter 独特的跨平台渲染引擎。
如图所示,这是因为 Flutter 独立的 UI 渲染让它具备了极低的平台耦合度,同时不依赖平台的渲染引擎让性能得到了提升,从而代码的复用率也得到了保证。
我为什么选择 Flutter?就是为了提高代码逻辑的复用率,从而降低同一逻辑在不同平台因人而异的扯皮成本。
相信大家都遇到过,iOS 或者 Android 开发说,“这就是系统提供的效果,你要统一让对方改”的经历。。。
Flutter 的优势
那 Flutter 有什么优势呢?
1、 Flutter 的 UI 与平台无关,控件基本是通过独立的 Engine 绘制,不会有平台界面需要独立适配的问题,同一控件在不同平台所见即所得。
2、Skia 引擎绘制时直接与 GPU 交互,没有“中间商赚差价”,甚至不同平台版本支持 Vulkan 和 Metal 的渲染模式。
3、因为比较好的分层理念和独立的渲染引擎,Flutter 在版本升级上的成本比较低,也可以看到 Flutter 过去一两年的版本推进是迅速的。(这里的升级成本是对比 RN,因为界面可以不依赖平台api)
4、第三方依赖的深度很低,官方框架的依赖也很少,更容易追溯,这其实和 Flutter 初始创建时的理念有关系,这个后面会讲到,至于为什么说这个依赖深度,大家看这张图就知道了。
Flutter 的依赖下载也是全局共享的,不像
node_module
每个地方一份。说起来以前就遇到过,同一个项目,因为硬盘空间不够而删除了一些项目的node_module
,后来重新安装完居然就报错了,然后我们只能在黑洞里去找问题的节点。
Flutter 的劣势
当然,吹了一波 Flutter 后,也不是说 Flutter 就一定比其他框架好,一些场景下其实 ReactNative 明显是比 Flutter 更优秀的。
- 1、混合开发上 Flutter 是没有优势,甚至说很拖垮。真的是“成也萧何败也萧何”,Flutter 因为只需要平台的
Surface
,说到底就是提供一个View
就可以了,所以它的页面堆栈和渲染树是脱离原生的,这就造成不管是和原生混合 Flutter ,还是 Flutter 混合原生都比较大的成本。
比如在原生框架中混入 Flutter ,那页面堆栈的混合就是一个大问题,虽然有不少第三方框架做这个,不过总的体验和稳定性上还是存在偏差;其次就是在 Flutter 中混入原生 UI ,最常见的就是 WebView ,也是因为 Flutter 设计的特殊性,它的性能和键盘问题一直都是让人头疼的存在。
2、 也就是热更新,它没有像 ReactNative 一样成熟的 code-push 机制,打包后的二进制产物本身就不符合平台的动态化策略,虽然也有不少第三方框架利用类似映射等的方式,但是维护成本还是挺高的。
3、通过前面的介绍应该理解到,Flutter 其实是一个独立的类似游戏的引擎,所以它对内存的消耗是比较大的,特别如果你是用于混合开发的话,那相当于在你的应用里接入一个小型的游戏引擎。
4、体积,Flutter 打包后的动态库必定需要占用一定的体积,在 Android 上因为系统本身就支持 Skia 所以比较好,但是在 iOS 需要把 Skia 引擎也打包进 App 里,所以体积会变大不少。
Flutter 的嵌套问题
好了,说了那么多 Flutter 的好与坏,最后来说说大家比较关系的 Flutter 的嵌套问题。为什么可以这样设计嵌套?
其实有一定原因是: Widget
并不是真正的控件 ,如图所示的代码,其中 testUseAll
这个 Text
在同一个页面下在三处地方被使用,并且代码可以正常运行渲染,如果是一个真正的 View
,是不能在一个页面下这样被多个地方加载使用的。
在 Flutter 设定里,Widget
是配置文件告诉 Flutter 你想要怎么渲染, Widget
在 Flutter 里会经过 Element
、RenderObject
、乃至 Layer
最终去进行渲染,所以作为配置文件的 Widget
可以是 @immutable
,可以每次状态更新都被重构。
所以 Flutter 不怕 Widget
嵌套带来的性能问题,因为它不是正式干活的,嵌套不会带来严重的性能损失, 但是,我们同样怕嵌套带来的可视化问题啊。
对于语法嵌套问题,不可否认 Flutter 的语法糖不过丰富,但是官方其实还是提供了一些解决方法,比如把配置文件抽象化,其中就是 Flutter 里最常见的 Container
。
Flutter 中 Container
本身只是一个容器 Widget
,它通过搭配了 Padding
、Align
、ClipPath
、ColoredBox
、DecoratedBox
、Transform
等基础 Widget
来实现了灵活的功能搭配。
这其实就是 Flutter 一开始提供的思路之一,所以可以看出来 Flutter 和以往大家理解的 UI 框架和跨平台框架不一样,总结一下:
首先他的跨平台方式的创新,能实现更好的性能和代码效果,它的设计也让它不会因为嵌套而带来影响体验的性能损失。
Flutter 在 Dart Framework 的分层逻辑,导致了开发者写的
Widget
只是配置文件, 内部的Element
才算是实例,而 ·RenderObject· 才是绘制对象等等,这和以往的 UI 框架不大一样。
所以如果想要理解 Flutter ,你就要先理解 Flutter 中灵魂的设计,理解 Widget
、Element
、RenderObject
、Layer
等的定位和设计,这也是我之前写的书里像表达的,在第三和第四章里核心的内容。
2、 2021年大前端有怎样的技术趋势
Flutter 属不属于前端
为什么说完 Flutter 才来聊大前端呢?其实我接触过不少前端开发和我说:“ Flutter 不应该属于前端”。
但是有趣的是 Flutter 就是来源于前端 Chrome 团队。
Flutter 的创始人和整个团队几乎都是来自 Web,在 Flutter 负责人 Eric 的相关访谈中, Eric 表示 Flutter 来自 Chrome 内部的一个实验,他们把一些乱七八糟的 Web 规范去掉后,在一些基准测试的性能居然能快 20 倍,因此 Google 内部开始立项,Flutter 出现了。
所以语法糖也少了。
另外 Dart 也是起源于 Web ,可以说 Flutter 其实就是从前端诞生,并应用于客户端的技术。
跨平台在国内运用多吗?
那大前端下跨平台技术在国内的运用多吗?答案是肯定的,这里可以看一个简单的数据,我之前自己单独做过一个53款 App 的数据统计,其中对于跨平台的运用:
- Flutter 有 20 款;
- React Native 有 22 款;
- Weex 有 17 款;
从数据就看得出来,其中不少 App 使用了两种以上的跨平台技术,甚至有三种都使用的,对于这部分数据感兴趣的可以在我公众号或者掘金上找我的的这篇分析。
另外这里我给大家推荐一个开源项目:LibChecker
,它可以查看你手机上已安装的包详细信息,不看不知道,自己看看才知道现在跨平台技术在现实中的运用情况,其中如图所示是我手机上应用使用 Flutter 、React Native 、Weex 的应用情况,所以可以看到,大前端和跨平台已经深入到各种开发需求中。
当然,跨平台需要的是平台!所以平台的原生开发是基础支撑,所以平台本身的开发是不会“凉”的,这是一个重要的前提。
跨平台不是“降维打击”,跨平台和大前端只是让开发的能力更加通用,所以通过各种跨平台能力,客户端和前端融合成了大前端,注意是“融合”。
大前端需要什么?
知识的广度,这里的广度不是指你要懂很多技术,而是你要会技术的抽象与通用能力的拓展。
当然有人就说 “嚼多不烂,杂而不精的情况怎么办?”
这个确实是个问题,但是思考这个问题之前,我在和一些网友的交流中发现,有时候大家都只是停留在思考这个问题上, 主要是用这个问题来说服自己不需要学新的 。
多而不精是对的,但是反之并不是,不是你不学多就自然而然的精了,所以这个属于个人衡量的问题。
如果按照简单的分数划分,精通不属于 0-60 分的范畴,而是 80-99分,这部分需要的毅力、悟性,最重要是要有工作平台的支持。
为什么这么说?在交流过程中一些人说想要深入xxx去精通某想技术,但是最终还是“三过门而不入”。
因为很多时候精通某项技术,是需要业务场景去验证和推进的,如果不是大体量的业务场景,没有经历过各种极端的考验,很多时候所谓的精通只是表层精通。
而大部分在“考试”中,一般人其实都可以做到范围是 75 分左右,这个75 分这就是我理解的大前端。
在 0-60 分这部分是大多数人能掌握的程度,然后 60-75 分需要费些心思就可以达到的,而这个区域内的能力是可以快速地横向应用。
所以所谓的精通不是熟练掌握了 React,Vue 等框架调用和源码的背诵,也不是精通 Flutter ,Android 等框架的 API 调用技巧,而是你理解了这些东西的核心思想和理念。
- 比如把 Android 上关于 Canvas 的技能就利用到 Flutter 和 Web 上;
- 比如响应式开发和状态管理的理解可以让我在 RN 和 Flutter 也能很好地利用,甚至未来的 Jetpack Compose 也可以快速的上手;
技术的抽象能力让你的技术可以迁移适配,所以在我的眼中,大前端的未来 “不是我会什么所以做什么,而需要什么我就能做什么。”
3、 程序员为什么要写作?
这个话题其实有点“跳脱”了,但是这其实也是一个比较有用的过程。
写作的动力是什么?
其实大家都应该发现一个有趣的现象,那就是古人写诗的时候,优秀的诗句里有不少是怀才不足的主题。
“我觉得我被低估了,我希望找到伯乐。”
其实这在程序员的圈子里也类似,如果有一天你发现同事突然开始更新博客和做开源项目,那么不用怀疑,你同事可能在打算跳槽了。
其实说这个的意思是,写作是需要动力的,或者是写作的初始动力是什么,你是为了什么开始写作的。
一般就有就比如前面说的:
- 为了跳槽的;
- 还有为了给职业生涯增加背书,展示自己;
- 甚至也有是为了赚外快的;
而在经历了初期的写作冲动后,后续如何保持写作才是最难的,而这里面有个关键的因素。
“心态”
支持继续写作的一个关键点就是“心态”。
很多时候我们写东西会发现:“哦,原来网上已经有人写过了”,之后就放弃不写了,这是很正常的心态,但是这样的放弃就会让你越来越难产出内容,因为你不能保证你一定快过别人。
其实当你想写内容时,发现别人已经产出过了,那你可以参考下别人的内容是否和你的想法有什么不同,然后有什么遗漏或者可以升华的地方,甚至是你可以从另外的角度或者更系统的方式去描述你的观点。
站在别人的肩膀上可以看得更远,当然不是让你 cv 抄袭,因为抄袭的意义不大,又不是小学生罚默写。
这就是写作人需要的心态之一,不要害怕撞文。
而写作还有另外心态就是“服务”, 写作其实就是一种服务行业,一开始很多时候我们需要面临的问题就是没人看,有时会有鄙视或者否定,甚至有的知识单纯的情绪发泄,这些我都遇到过,因为你不可能面面俱到地服务好所有人。
我们提供的服务是内容,期望得到的是关注和交流,所以要比较自己陷入不必要的情绪陷阱。
“不要成为别人情绪的垃圾桶,那就在开始时把盖子盖上或者远离”,自此之后我佛系了,面对不善意的评论我会选择屏蔽或者直接给予肯定,这样可能帮我节省出更多的时候来做有用的事情。
最后好的写作进阶
最后说下什么是好的写作进阶:那就是把高级的内容变成接地气的内容
如果一篇文章你看完后觉得:“哇,牛逼,但是为什么我就只看不懂?”说明这篇文章并不是一篇好的科普内容,这部分经常出现在早期的 “RxJava”、“协程” 等领域的文章。
那好的写作一般可以分为三个阶段:
1、写文档是第一步,因为你告诉别人怎么去理解你写的东西,所以如果你想开始写作,最简单就是从写文档开始,把你的东西介绍明白了,就是一个好的开始。
2、写源码分析是第二步,那就是学习和分享如何去理解别人的东西,这个过程可以让自己在学习的过程中有所总结,并且介绍别人的内容就是一种抽象能力的进步。
3、写问题解决和应用思想是第三步,告诉别人如何去理解别人的思想,这就需要作者对要介绍的内容有自己的理解,才能够把内容变成更好理解的接地气的文字内容。
其实介绍了这么多写作内容,就是想告诉大家:“大前端是一种思想,就是让你已有的能力可以运用更广泛,而写作是帮助你把能力抽象化的一个过程。”
这也是我在写书的经历,从如何使用 Flutter,深入理解 Flutter 的 xxx 以后,回过头来我有了新的理解。
觉得可以从这个角度去告诉后来的人应该如何理解 Flutter,这样虽然 Flutter 一直在更新,但是这部分内容是它设计的核心理念,所以它并不会过时,也能成为比较好的内容承载。
就如今天的主题就是:大前端是一种思想,可以让已有的能力得到横向的应用,写作就是提炼你技术思想的过程,从而帮你把你的固定于某一个框架和某一个平台的能力变成抽象化能力。