前段时间有幸去上海参加了Qcon,聆听了业界一些优秀经验、实践的分享,感觉收获很大。尤其对两个分享感触比较深,分别是美团田泱同学分享的: 《云+端一体化:前端工程化探索》,以及字节跳动艾石光同学分享的《微前端在字节跳动的落地》。两个分享虽然落地点不同,但是解决的却是同一个问题:开发效率。
微前端在字节跳动的落地
问题
Monolithic 应用,build / deploy / rollback 慢,无法应对应用体量增大后,大量上线诉求。
框架无法调整
工程巨大难以理解,消耗过多认知资源
每个人认知是一个有限的资源池,做一件事情时,牺牲掉注意力越多,分配到其他事情注意力越少;需要注意的东西越多,犯错的概率越大。
解决方案
1. 服务发现
将服务进行分拆,解除耦合。由此解决 Monolithic 应用带来的问题,实现独立运维,急速上线下线,流量分发,问题追踪。
2. 运行隔离
之前各个业务运行在一起,互相之间形成干扰,达到了一个很严重的程度。主要包括:
- 一些模块/组件(或其依赖)对 Javascript 原型链的修改,对其他模块/组件形成干扰,带来bug。
- CSS选择器互相干扰。
主要通过 Sandbox 解决。为 CSS,DOM,变量、数据采集、sentry、localstorage 等添加沙盒。此外还引入了时序,并且对 polyfill 和其他 delete 情况作了特殊处理
3. 环境一致
这一块主要解决环境带来的问题。为了开发体验好,效率高,不论 serverless 还是 container,都坚持要有本地开发环境,并与线上保持一致。
通过命令启动 chrome ,leverage chrome 在 debug 方面的相关能力,引入对 timeout,memory,runtimes,API Gateway 等相关模拟。
4. 其他
拆分主工程和业务模块,统一数据采集、复杂事件分析。规范和灵活动态统一等。
云+端一体化:前端工程化探索
问题
田泱同学(以下简称”演讲者“)由三年前一次与老板的对话引出话题。当时的情景是,老板提出一个简单的需求,演讲者给了一个比较久的排期。老板对此不理解,认为不应该这么久。由此引起了演讲者对前端开发效率的思考,并为自己和团队提出了5分钟上线一个MVP项目的终极目标。
经过思考,前端开发效率低,主要问题是工程师距离业务逻辑较远,经常是支持多个业务,每个业务都不深入。团队组织不利于工程化。常见的团队划分方式有两种:
- 按职能划分,一个大前端团队,支撑多个业务
- 优点:氛围好,团队稳定
- 缺点:响应慢,协同效率低
- 按业务线划分,分成多个小前端团队,嵌入各个业务team
- 优点:响应快,协同效率⾼
- 缺点:氛围差,团队不不稳定
解决方案
团队组织进化
进阶:按业务划分基础上,增加基础服务团队,并且在业务小团队中,有部分力量支持基础服务。
基础团队主要职责:制定规范,制定框架,开发工具,其他服务。
团队合作
职责清晰后,比之前的情况有了很大改观。即使如此,依然会有一些问题:
- 基建同学:维护压力,业务方无法理解工具用法,需求又很多。
- 业务同学:成长诉求,以及可能对工具不满意。
解决方案就是业务团队与基础服务团队的交集。可能是业务团队部分同学,做基础服务的业务;也可能是业务同学部分精力支持基础服务。基建团队承担主要维护压力,业务分摊部分功能的维护压力。交集存在后,合作流畅很多,基础团队能给给业务团队更多赋能。
技术方案与流程规范
分享者提出了一个开发实践中的效率公式:
效率 = 技术方案的完善程度 x 流程规范的可执行性
- 技术方案不完善:业务分摊部分功能维护压力,按层级分配职责同时,通过插件机制反哺:
- 大前端委员会,各组TL:制定前端工程规范标准
- 各团队架构师:基于标准实现内核Loader,Tools工具链,以及Plugin插件。
- 各业务线骨干:开发适合特定业务场景的Template
- 各业务线的一线开发同学:基于Template进行二次开发
- 在此基础上,各个业务线的骨干、一线开发同学,通过贡献Plugin插件,反哺架构师的工作。
- 流程规范不彻底:流程学习成本高,问题解决意愿低。
- 主要通过GUI可视化工具解决。将流程,问题暴露在开发过程中。流程可视化,透明可见,执行成本更低。
- GUI工具的主要功能:代码检查(兼容性,版本),Lint & Test,Buid,Deploy,各个流程审批。
Faas
运维成本是阻碍 Node.js 在企业落地的绊脚石,通过 Faas 实现 Serverless,带来了耕地的学习成本、开发成本、运维成本。据演讲者称,能够带来20倍提升。主要有以下好处:
- 运维托管,降低运维成本,”不用管“
- 无缝迁移,降低开发成本,利于方案推广,”不用学“
- 集中运行,充分利用机器资源,解决 nodejs 资源利用率低带来的浪费。与此同时,将 worker 分为以下两种模式,进一步提高资源利用率:
- Process模式,计算型,独享进程资源,通信效率低,适合计算型函数
- Thread模式,响应型,共享进程资源,通信效率高,适合响应型函数,HTTP/MQ trigger