Flutter 是当前跨平台技术中最火的一项,在提供极好的用户体验的同时,还能解决多端一致性问题,并有效降低人力成本。字节跳动希望把 Flutter 打造成下一代研发体系,支撑众多 App 的各种使用场景,为此,团队在 Flutter 上大力投入,覆盖了引擎技术、平台服务、开发框架等多个维度。本次将详细介绍字节跳动在 Flutter 技术上的进展和工程实践,内容整理自字节跳动高级研发工程师林帅斌在 GMTC 深圳 2019 的演讲。
今天主要分享 Flutter 在字节跳动的现状以及工程实践的经验。先介绍一下我所在的移动平台部,移动平台部是字节跳动的基础技术部门之一,服务于公司的各个 App。几乎所有的主流 App 都是我们的客户,所以我们的方案更专注于通用性以及工程实施的难度,主要是为了方便各种 App 的接入。移动平台部所涵盖的方向包括:基础架构、研发体系、APM 、端智能、跨平台等,而 Flutter 就是 APM 端智能跨平台下的研究方向之一。
Flutter 在字节跳动的现状Flutter 的优势与业务现状为什么选择 Flutter
选择 Flutter 主要有以下四个原因:
性能体验与开发效率作为官方一直在宣传的两个重点,这里就不过多赘述。除此之外,我们还看中了 Flutter 的高度一致性,这里的高度一致性不仅仅指各平台 UI 一致,更重要的是各个平台运行的是同一份代码。以前一份需求在 iOS 与 Android 上需要各实现一份,在迭代的时候就会带来额外的协商成本,对于迭代速度很快的字节跳动来说,Flutter 可以很好地抹平这个成本。
什么是高可控制性?Flutter 对宿主的依赖很低,宿主提供一个画布就可以自己运行起来,还有渲染流程和时间派发都是自行运作的。换句话说,无论是修改内部实现还是优化内部逻辑,我们都可以很轻松地做到,这点和过去的 Native 应用开发有很大区别,使用 Native 开发需要各种 Hook,API 还有较高的风险。
由此我们觉得 Flutter 的确是一个值得研究与投入的选择。
具体到业务落地,我们早期拿 Flutter 实现了一个比较简单的页面,基本上达到了 Native 的效果,在滚动和手持操作方面的体验也几乎与 Native 一致,也正是因为这一次的实验让我们对 Flutter 更加有信心,也向着这个方向继续深耕,将一些需求直接使用 Flutter 来实现。目前,公司内部大部分 App 都在使用 Flutter,这里简单列举几个:
作为字节跳动的基础技术部,我们究竟对 Flutter 进行了怎样的规划与建设?
总的来说,我们希望将 Flutter 打造成下一代大移动端开发体系。所谓大移动端,与大前端并不那么相似,大移动端更多主张移动优先,同时再去兼顾其他端。而且最好是可以用一套技术栈统一它们,Flutter 就刚好符合这个定位。我们以这个目标为愿景,围绕着这个愿景我们主要在三个方向进行努力:
第一个就是基础能力,Flutter 与 Native 毕竟存有一些差距,我们需要研究在基础能力这方面如何抹平差距,甚至让它超越 Native,所以我们在架构层面投入了大量的人力。
第二点是周边配置,一个语言、一个平台是否好用,能不能有更好的发展,往往不是这个语言或平台自己决定的,更多要看它的周边配套工具,包括 IDE、Debug 工具等等,而 Flutter 作为新生的平台,在这方面存在较大的劣势。我们也将此作为一个主要方向投入研究,提供一个更好的工具。
第三点就是针对于 Flutter 的推广,这个问题很容易理解,更多的开发者使用 Flutter,建设 Flutter 的资源就会越多,这样就会形成一个积极的循环。
围绕着以上三点,我们做了一个“3 + 1”建设规划,就是应用框架、基础服务和引擎框架三大方面加上周边建设:
引擎框架目标很明确,就是为了提高 Flutter 的基础能力,所以我们对其做了大量的性能优化,包括渲染卡顿、内存回收、启动速度等。在启动速度方面我们提升了将近百分之一百,与此同时体积也压缩了百分之五十,除了这些基础的性能优化外,我们还支持多窗口、端内复用等更多的能力;
基础服务方面主要是针对研发流程,线上高可用和降级的灰度策略等,换句话说就是除了敲代码之外的研发流程;
应用框架层我们对外说的比较少,应用框架层主要是为了打造一个开发者生态,或者称之为应用开发生态,更注重基础组件、工程方案、工程效率、最佳实践等,帮助业务更好地实施他们的工程;
除了左面的三大点外,我们也很注重 Flutter 的周边建设,包括对 Flutter 技术体系的培养,推出培训课程、建立 Flutter 知识库等,同时我们也很注重开发者的交流,建立交流大群、信息同步群等等。
接下来分享三个我们觉得通用性比较强的方案,看一下为什么我们会觉得它很强。
FlutterW 研发套件背景
为什么开发 FlutterW 研发套件呢?主要是源于三个问题:
第一点,作为基础技术部,我们要服务的业务很多,我们希望他们使用 Flutter 的前提就是可以更简单地安装配置好 Flutter。但 Flutter 的安装配置很繁琐,同时不同技术背景的开发者配置起来也会有不同的感受,比如说专攻 H5 的同学配置这个环境就会很繁琐。Flutter 引擎是一个全局变量,它需要安装在每一个同学的系统里面,而整个业务团队内每个人所使用的引擎版本不尽相同,就会导致因环境问题而产生异常现象,花大量时间处理这个问题显然是很不划算的;
第二点,Flutter 作为一个跨平台语言,无论是开发、编译还是调试,它的整个链路都特别长。简单来说就是:一旦应用中出现了一个问题,它可能发生在 Dart 上,可能发生在 Native 上,还有可能发生在这个业务同学的电脑环境配置上,导致问题排查起来十分不方便;
第三点,当我们有方案需要实施的时候,很难把方案立即部署到具体的业务团队的设备上,在实施方案的时候也具备一定的难度。
基于以上三点,我们需要一个能把用户的整个开发流程包裹起来的研发套件。比如说安装配置 Flutter、使用 Flutter 进行开发、发布 Flutter 的产物、调试 Flutter 的问题等一系列的开发流程。目前 FlutterW 主要具备四大方面的能力,如下图:
第一个是环境方面,它需要把开发环境处理好,具体来说就是帮助开发者快速部署好 Flutter,还要保证环境的基本属性一致、引擎版本一致;需要有一个独立的沙盒,某一个项目的配置不应该在一台设备上相互影响;还需要有一个依赖配置表。
同时 FlutterW 还需要具备一些工程方案的能力,可以让我们的业务通过它进行简单的实现,为什么不用文档呢?因为在各式各样的业务方团队面前,文档的效率并不高,所以我们让这个套件作为一个载体让业务团队在实施方案的时候更轻松、更快并且失误率更小。
第三个是左下方的橙色部分,也就是 Support 能力。业务方往往会遇到各种问题,找到我们的时候,我们该如何解决?跨团队、跨部门的合作已属不易,更何况还有很多是跨地区的。由此我们给 FlutterW 加了一个功能:采集用户的错误信息,直接调用我们的解决方案并部署。
最后的绿色部分是 Dryrun 功能,就是用来体验 Flutter 的功能。我们在公司内部做推广的时候发现,很多团队都有体验 Flutter 的意向,但是 Flutter 的安装势必会污染本地的电脑环境,导致他们放弃体验。FlutterW 的能力就是可以直接运行 Flutter,不需要配置。
总结下来 FlutterW 的功能中最核心的只有两点:
以一个标准的 Flutter 工程为例,由于每个用户的电脑内的环境都不一样,那么在你关注这个工程本身的同时还需要关注用户本地的环境配置。我们不可能永远知道业务团队同学在使用什么样的配置,每次处理问题都进行沟通的话,就会在无形之中多出了太多的成本。Flutter 把环境直接配置在了项目内部,通过 FlutterW 安装的项目,它的内部除了代码资源外,还会有一个依赖配置表,里面会将此项目的一些信息,诸如基础的依赖、SDK 版本、打包工具等,都描述清楚,然后根据这个配置表来自动拉取相应的资源从而形成一个沙盒环境,在这个环境内进行独立开发。
第二个是自动化工程能力。如上图,当业务团队需要反馈问题的时候,FlutterW 会收集更多信息提交给我们团队,我们基础技术部收到信息后会将问题还原并提出解决方案,这时候我们可以将解决方案部署到 FlutterW 的云端服务器,FlutterW 会自动更新这些方案从而为业务团队解决问题。通过 FlutterW 这个媒介,我们可以尽量地拿到用户信息并将解决方案实时部署。
以上两个是 FlutterW 最核心的两个能力,简单总结来说就是:
这里的容器化工程方案更多的是指 API 的容器化。Flutter 是一个跨平台语言,跨平台框架,身为一名开发者听起来实在是很美好——做一个 App 就可以各个端去跑。但当开发者真正着手开发一个跨平台应用的时候,就会发现需要了解的实在是太多了:Dart 是不可避免的,还有 Java、OC、平台相关语言...... 因为我们终究还是要依赖平台的能力,这样要求还是比较高的。正因为一般的开发很难兼顾好各个平台,所以我们很多业务开发会同时配置一个 iOS 和一个 Android,当平台出现问题时分别跟进,但这样很浪费人力。那有没有办法让我们的业务只关注在 Dart 上呢?不用再去管这些所谓的平台能力呢?显然是可以的。
我们引入了一层标准化的 API,用来规范化各个平台提供的所有能力。平台实现这样一套标准能力后,Dart 业务的开发方就不需要再烦心于各个平台的问题,面向这一层 API 进行编程就可以了。也正是引入这一层,使我们可以达到真正的多端、多业务交叉部署。
Flutter 作为一个渲染框架,自身就保证了运行环境的渲染能力的统一,而容器化 API 又保证了各个平台、各个端的基础能力的统一,有了渲染能力和基础能力的统一,业务方就可以真真正正的用一套代码跑在各个端上了。
这其实是对于开发者的开发体验的一个优化。既然是面向 API 编程,那么就不需要关注最终运行在哪里了。对于开发来说,在开发时运行一个 H5 版本岂不是更方便、更轻巧?最起码不用再连接一部手机。在实际交付的时候,再打包成产物,交付到实际的设备上。
那么容器化 API 是一个什么样的体系呢?
如上图,整个容器化 API 最重要的部分是上方的红色部分,我们需要固定 API 层并将其标准化,所以它有一个独立的 API 版本管理。但仅仅提供一层 API 也是不够的,以字节跳动为例,公司内部的 App 特别多,每一个应用都要重复实现这些接口的实现并不科学,所以我们为它提供了一套默认实现——而且这个方案可以支持他们随便移出这些实现,修改成自己的实现或者做一些其他的扩展。
经历了这么多的考量,最终得出了这个容器化 API 方案的最终产品,大概总结下来就是:
Flutter 是一种典型的响应式 UI 框架,这种框架的特点就是 ui = f(state),重要是状态而不是 UI。只要我们能管理好一个应用的状态,那我们整个应用的页面或者行为就始终受控。但 Flutter 这种框架,它状态分散在各个组件当中,各个页面之间要互动、流转,从而导致这个操作十分烦琐,很难维护。
所以我们要尝试研究之前前端的一些经验,目前业界的主流就是 Redux,那它有什么优势呢?
如上图,左侧的图更像我们平时的一些应用开发,各个元素间相互调用,各个对象间也经过各种循环来调用,一旦项目相对庞大,就会没有人敢随便动这个项目,项目就会逐渐失去可维护性。反观 Redux,它提供了一个角色,把所有的状态收归在其内部,除了参与元素外,主要是对 UI 的监听,监听那些状态有着什么样的改变。同时,我们也更容易知道它内部会发生哪些变化。
简单看一下 Redux 的原理,上文提到的管理角色叫做 Store,Store 内持有了整个应用的所有 State,同时它也持有着所有的 Reducer——用来更新这些状态的。正因为数据和更新方法都在控制范围内,整个应用就拥有较高的可控性。
大致流程就是:我们的页面元素 View 发送一个事件通知 Store,在 Store 内部会根据这个事件进行处理并遍历所有的 Reducer,哪一个 Reducer 对这个事件感兴趣就会更新的状态,同时 View 元素就会自动改变。重点在于这是一个单向的数据流和单一数据源。
当我们真正使用 Redux 的时候,就发现 Redux 有一些不足之处:
入门成本偏高,但维护成本显著降低
全局只有⼀个 Store 是个大问题
由此,我们也尝试比较了一下目前市面上其他的状态管理方案:
可以看得出来,各个解决方案都有其优缺点,但结合我们自身应用的规模化考虑还是觉得 Redux 这种强管理、数据状态可控的模式更适合我们。
方案介绍
那么之前的问题关键在于哪里呢?
回想我们的状态本身,状态分布于页面上,而且状态之间往往会有一些归属关系,例如有的页面在登陆后才会存在,有的信息在登陆后才会有。由此我们选择了一个树状结构,也就是我们的自研方案——ByteRedux。
我们引入了一个 StoreTree 来承担这个单一数据源这个角色,引入这个角色以后有什么好处呢?第一个就是高性能、低学习成本。为了避免引入开发时候的误区,我们选择了让 Store 来代理这棵树让 Store 和单一数据源完成整个交互。
举一个例子,我们的 UI 发送一个 Action 到这个最左边的 Store 的时候,这个 Store 不会直接在内部处理而是转发到根节点,从而投派给 StoreTree 这个角色,让 StoreTree 管理这个 Action,帮你去寻址到你想发送的 Store,这时它内部才会进行计算并更新内部的状态。这个过程对于我们普通开发者来说,和原本的 Redux 用法基本上没区别,并不需要额外的学习成本。高性能又是怎么理解呢?如下图,这个 UI 元素能影响到的仅有它的目标 Store,其余四个节点的状态完全不会受干预,也不会导致其他无关的界面的任何的 ReBuilt。
要支持多元开发和模块化开发,有一个问题必须要重视。如上图所示,模块 A 在宿主应用内的运行时,根结点会继续寻找合适的挂载节点,然后加入之前的应用的单一数据源——StoreTree 里面,并让自己开始运行。那么在模块开发时该如何运行呢?
我们的 Store 根结点会自己生成一个根节点,从而保证生成单一数据源的这个对象在一个小模块内依然可以正常运行。但仅仅保证可以运行还是不够的,开发者做模块开发时,总会依赖一些外部的属性。例如,很多情况下要依赖登录信息和用户状态等,我们的根结点可以 Match 一些外部的状态,从而加速我们的整个开发流程。
ByteRedux 作为我们自研的框架,如何复用社区已有资源也很重要。整个方案的核心就是维护 StoreTree,具体到每一个 StoreTree 是否需要自己实现则不是关键问题。但如果我们可以通过一个转换器用上社区中所有的轮子肯定是最好的,所以最终我们通过一个转换器实现了对社区已有资源的复用。
ByteRedux 的架构需要关注的只有中间的部分,图中的 ByteRunner 就负责刚才的模块化开发,包括判断节点是否需要、如何寻找已有的单一数据源、如何创建单一数据源等,同时它也是支持 Mork 数据的关键。
关于 ByteRedux 的优点总结下来就是:
Flutter@字节跳动Flutter 已经成为字节跳动新业务的首选技术栈之一;建设方向覆盖了引擎、框架、基础服务等方面。工程实践Flutterw 标准化 Flutter 的开发环境,提供了方案统⼀实施的能⼒。容器化方案让运行环境提供统⼀基础能力,真正实现“Write Once, Run Everywhere”。ByteRedux 状态管理方案以很低的成本解决了 Redux 的问题,保留了 Redux 的优势,使 其适应大中小型应用。
未来 Flutter 在字节跳动内部会继续作为下一代大移动端开发技术这个角色推进。在工程实践上,我们也会更注重开发者体验,致力于降低使用成本,赋予更多能力。
作者介绍
林帅斌,就职于字节跳动移动平台部,曾就职百度、阿里巴巴,参与过百度日文输入法、东南亚 Lazada 电商等重量级应用研发。目前负责 Flutter 应用框架层基础建设,主要的研究方向包括工程自动化接入、状态框架、组件容器化方案、研发流程等。字节跳动急招大量技术岗位,联系邮箱:linshuaibin@bytedance.com。
本文由哈喽比特于4年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/P74__e6Cm4okqsFIK0PVSQ
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。