张鑫旭-鑫空间-鑫生活
it's my whole life!备份内容浏览
我理解中的“大前端”/“大无线”
2017-03-12 小芋头君 前端周末
作为一名理性的工程师,该如何看待如今前端界的繁荣景象?不妨来跟着作者窥探一番。
下面正文:
前言
最近,我所在的团队做了一些结构调整,其实我一直想讲讲这次调整,希望能够带给同行一些思考,但因调整后很多事情还未走上正轨,一直拖延着,现在终于有时间把一些想法写下来记录成文字。
今天早晨,还看到一篇文章,讲“大前端”,文中展望了近年来“前端”影响的领域,从美工时代刀耕火种的时代到现在延伸到 NodeJS ,ReactNative甚至桌面端,以及传统前端的时代,听来的确让人非常兴奋和自豪,但是作为一名理性的工程师,对于这种自High的论调一定要抱有谨慎的态度。
其实在技术选型上我是一个激进却又保守的人,所以,我同大家伙一样,对于JS语言冒出来的给人无限想象的能力非常的敏锐和兴奋,但是在落地到真正的业务中的时候却要仔细权衡好它的真正的“价值”。此处的价值更多针对的是“对公司整体业务的价值”,而不是对团队或者个人的价值或是其他,所以,引入一个技术栈,绝非看起来那样简单,“新技术”可能会给你的团队或者业务带来加持,但是更多时候,外界的人云亦云却往往会夸大某个技术的价值,然后同时刻意避免谈及这些技术带来的问题,就是我们通常所说的“脱离场景讨论技术”,而且通常带来的问题比解决的问题还要多得多,这时候如果抱着“扩大前端团队的话语权”或者“做一步看一步毕竟业界都在这样玩”的态度,那就和“技术创造价值”的本意相违背了。
其实,大家会发现我所在的团队并不是一个保守的团队,从外面看,我们始终走在最前沿,但是从内部看,其实我们一直在关注“技术创造价值”这件事情的本质,所以我们给前端团队强化了很多职能,但是却走了一些不同的道路,之所以会这样,其实就是基于我们针对每个技术栈所做的思考,接下来我会举几个例子来讲。
其实我今天本来想讲的事情,并不只是“前端”,而是这次团队组织架构调整后的“大无线”,为什么要从“大前端”到“大无线”,也是基于最大化价值输出的考虑,这是后话。
这次调整,最大的三个动作就是, NodeJS 的职能变化/ReactNative的引入/专门的架构组职能,然后包含其他一些小动作。
NodeJS 职能变化
对于 NodeJS ,我其实有挺多的话题想分享,关于前后端分离,关于服务端渲染,关于纯服务端开发。很长一段时间内,在我们团队, NodeJS 都是在做纯服务端开发,然后我们的核心关注点一直是致力于将 NodeJS 在服务端开发的整个工程能力提升到和Java生态相当甚至是超越,包括开发/部署/运维/服务化/线上保障 等。值得注意的一点是,当我们的 NodeJS 运用非常成熟的时候,我们却一直没有做业界大家在玩的服务端渲染,或者前后端分离中间层,其实不是我们不了解或者没有能力,而是我们一直在思考“为什么”,然后会”带来什么问题?“。我觉得很多公司在做服务端渲染或者前后端分离的时候,可能都没有非常全面的去思考过这个问题,是必须要做了而且带来的价值远远超越了风险?还是只是为了让团队占领更大的势力版图?我们前几天在讨论这个问题的时候还提到,包括在某些大公司内,做某些事情可能只是政治正确或者为了业绩好看,如果你去问一个服务端开发,他对这些事情的看法是什么?难有好评?那这件事情可能就已经走偏了,它可能关注了前端团队的自身价值,却偏离了整个技术团队的价值体现。
当然我不是表达不应该去做某些事情,而只是讲所有技术栈的落地都要基于场景去考量权衡。其实我们团队后来也做了业界意义上基于”服务端渲染"的”前后端分离“项目,在某个特殊业务中,我们衡量必须要做,与多方共同讨论,最终实施落地的一个和谐方案。做这个项目的目的足够单纯,但是我们并没有打算推广这个方案,因为在我看来,他只是解决某个特定场景的一个解决方案,而不是一种必须推开来的“开发方式”。而且对于服务端渲染引入的风险一定要做好风险评估,包含但不限于:运维/线上保障能力(前端的弱项);前后端开发的复杂度;性能问题(真正做过服务端的同学对内存和cpu占用都会很敏感,但是目前一些方案看来在这方面的损耗还是太夸张); NodeJS 本身的开发能力熟悉程度。其实有些问题是很严重的问题,只是在业界大家讨论的时候,大家会刻意去弱化某些话题,而是强调其革新之处,或者是未来的趋势,而这些理由,在真实场景落地的时候的作用微乎其微,别人一个质疑就足以让你的方案变成一个”糟糕的方案“。
不过,我所在的团队的 NodeJS ,最近其实在做”去服务端逻辑“化,也就是慢慢退出纯服务端开发的领域,倒不是被倒逼,我觉得一个团队应该做什么事情从来不是因为技术之间的斗争导致的,而是前面提到的整体价值,在公司飞速发展的业务背景下, NodeJS 的开发生态和团队扩张速度,都是瓶颈。 NodeJS 开发者的开发能力其实都很强,但是却缺乏传统软件工程大规模开发的经验,这些经验可能大部分都不是和技术相关的,所以越在技术上走的深入,与大规模工程化关注的方向越发背离。所以,我基本上是主动要求团队退出服务端开发,将整个公司的服务端统一到 Java 技术栈上,统一由 Java 架构组规划技术发展,由 Java 业务组统一发展业务的工程化,这样对公司的爆炸式增长会更有益处,随后Java开发在一个月内扩招20人,而 NodeJS 一年时间里基本一直维持在5个人的水平(人数也是影响工程化的重要一环),想想这五位同学曾经在一年之内建设的诸多系统,虽然真的很牛逼,但是却略显小气,没有一个统一的规划和价值体现。
那我们现在在做什么?
之前提到,我们现在整个团队成为“大无线”,其中包含两个大团队,架构和业务,而 NodeJS 正是架构中的一员,对于 NodeJS 来说,它擅长的正是对社区和标准的追逐/开发效率/异步性能,而我们则发挥这些长处,在整个“大无线”的范围内解决相关的问题。例如正在做的一件事情,一个无线网关系统,具体网关系统是做什么事情的可能无法一句话描述清楚,核心两点,1. 公司内所有api请求的入口和规则分发,2. 在网关层做服务分级。具体实现其实并不是完全的 NodeJS 技术栈,其中多个子系统,包括Nginx开发网络层/lua开发的独立的心跳检查/ NodeJS 开发的规则管理等,对于 NodeJS 来说是个不小的挑战,对于整个无线端,甚至服务端,都有深远的意义,这种事情才是真正“有意义”的,后续我们也还有其他规划,不过一切都需要一步一步调整,而对于我们 NodeJS 开发来说的调整,就是转变思路,发挥长处,而不是一心想要去改变服务端开发的格局。
ReactNative的大规模应用
我所在团队对于RN的技术积累其实从很早就开始了,大概接近1年前,但是一直处于调研的状态,甚至组件库都写好了,基础的集成SDK也写好了,但是从来没被应用到业务中。为什么?不是因为不成熟,也不是因为hold不住,而是没想明白,为什么一定要用RN?而不是H5或者Native?这其实是个很严肃的问题,你想不清楚一个技术的价值的时候,不要说是说服别人,连说服自己都很难,这样的事情注定无法落地,所以我们就一直在调研,在准备。就跟微信小程序一样,我们调研了很久,自己做了个小程序上线,但是后来还是没有做一个真正的业务相关的小程序,因为实在想不明白要做什么,为什么必须要用小程序?
后来,算是跟上了“大无线”整合的契机,也是公司业务飞速发展的契机。当我们统一规划一下公司内所有的前端和无线端之后,发现数量竟然和所有服务端(包含架构和数据等)的数量基本相当,这很不正常,当公司开始快速扩张之后,这种比例是非常吓人的,而核心问题就是我们公司无线端所有的开发工作量基本都是Native承担的,这主要受制于公司业务类型限制,公司基本所有业务都是偏商家服务类型,重交互重操作重数据,在客户端上开发,对H5来说的确难以满足需求,不管是性能还是体验还是开发成熟度上来说。所以除了公司的to C业务和PC端业务之外,大量投入客户端开发,而因为之前客户端分散在各个业务之间,每个业务的每个端都各自为政,在底层方案和组件SDK等问题上都缺乏一个统一的规划。
注意!这里提到两个核心问题:
开发人员输出价值的人均效率,对于Native来说都需要至少乘以2,如果算上两端之间的协调,将远远大于2这个最好预期。
难以统一规划整个客户端的统一发展,总是会受限于两个完全不同的端各自不同的技术栈。
这时候,ReactNative站出来了,一个真正性能折中但是可以完美解决这两个核心问题的技术方向,而且我们还是有技术积累的,至于我们如何在RN和Weex之间做选型,其实不想多说,Weex的场景并不适合我们的业务类型,而且作为创业公司,我们只会选择整个业界非常成熟的方案而不是一个还在发展期只是看起来很美好的方案。 对于ReactNative,核心价值点,其实就是上面说的这两点,听起来只是两个问题总结,但是对于整个技术团队,甚至对于整个公司的业务发展,这都是非常核心的点,所以,我们毫不犹豫的执行,短时间内快速推进了整个RN的解决方案以及落地。
针对RN,我们做了几个事情:
完全改变RN的开发流程,自己定制的脚手架以及开发流程/调试流程/发布流程/版本更新规则。(我司最擅长的点)
自己实现的集成流程/热更新方案,这里有一个核心点,我们制定了某个App依赖某个版本bundle的机制,RN代码不是每次热更新,然后RN代码是直接内置到工程里走发版,而不是线上访问,因为我们的业务场景很特殊,业务耦合很强,所以制定了严格的版本依赖规则和维护方式,热更新的能力只限于bugfix,不能用于发布新功能。
封装过客户端SDK,主要提供几个能力:Bundle依赖管理/Native组件以及提供更多组件SDK无缝接入的能力/RN和Native和H5之间通过协议互相调用的能力/性能和错误崩溃监测/其他底层优化(例如秒开,bundle分拆复用等)。
最终面向具体业务开发的一部分:开发框架/开发规范/基于设计规范的组件库/Native组件封装/工具库/文档/模板项目/example项目列表 等,通过这些,我们给具体的业务开发暴露极少的概念,可以在短时间内完成一个RN项目,并且将可能平台差异的部分都做了深度封装。
所以,可以看到,其实我们的RN开发有自己的一些特色:
大部分RN业务开发是客户端开发,而前端仍然专注于前端的领域,所以我们的方案做了大量概念封装,具体开发过程中大量使用的是自己封装的概念而不是原生的概念,也把React生态,RN本身的生态的概念做了最大化的封装,让不熟悉React的同学也可以做基础的开发。
强版本依赖,RN业务发布走发版而不是在线热更新,RN和Native和H5之间深度耦合,一个流程中可以无缝在不同的容器间切换。然后RN和H5调用Native的能力其实也是一个统一的底层封装。
这块,不想在这里展开来讲,毕竟这篇文章只是讲方向,而不是具体实现。
专门的架构组职能
到这里,才讲到,为什么要整合“大无线”?基于前文的分析,无非是让大家更关注大团队的价值输出,而不是某个业务或者某个技术工种的价值输出,前文多有体现其中的各种弊端。
如此的组织架构,对于集中输出价值的表意更为清楚:
各小组的价值,就体现在各自的职责定义上,其实这样的组织架构各自的职责定义非常清楚,业务方负责将业务实现和落地,其价值体现在更高效的落地业务,而架构组则负责统一规划技术方向,提供基础设施,推进技术演化,来解决业务落地过程中的技术问题。
二者协作,价值最终还是集中于一个点上:业务价值。对于无线来说是无线端对业务的价值,而后端则是后端对业务的价值。二者其实略有不同,无线端更关注表现和体验,后端则更关注逻辑和服务。
最终大家的价值其实都集中在公司层面,当然能不能考虑到这一层,能不能推动这一层,就是各大Leader的能力问题了。
在抽取出统一的无线端架构组之后,至少以下几件事情可以体现出深刻的价值来:
专门的跨端体验组,提供RN的整套解决方案和各种优化以及推进等,统一规划RN的发展方向,效率提升,流程规范等,而业务方则致力于快速实施推进业务开发的效率。
专门的客户端和前端架构组,统一规范“开发方式”,所谓的工程化体系,提供各种效率工具(例如我们内部的mock系统,已经和服务端自动化集成在一起,非常高效),提供基础组件,基础服务(例如前端的静态资源管理等服务)基础脚手架,提供一些底层manger的统一实现等。
专门的 NodeJS 中间件团队,提供一切与无线端的后端服务能力,例如网关服务,服务端渲染服务,RN模块管理服务,静态托管服务,消息服务等,其中有些服务挑战非常大(网关/消息等),后续,还准备做另外一个中间件的尝试,不过还是要按照上面讲的方法论进行评估。
虽然,整个无线端包含了这么多角色,但是我深感欣慰的是,我们在各自领域都有了一定的基础积累,所以在这样大整合的趋势下,能够良好运转,并快速发挥各自优势为整个团队的发展出一份力。如果我们是从开始按照这样的职责孵化,其实我觉得很难走到今天这一步,所以,这是一个趋势,但是不是一种与生俱来的合理结构。
另外,在架构组职责上,还有一点很重要就是,架构这个角色绝对不止是“研究新技术/熟悉底层/产出复杂技术方案”的角色,更多时候,架构师需要深入到业务中去发现问题,然后分析问题总结问题,思考解决方案,与其他成员脑暴,制定最终解决方案,并将其最终落地的过程。所以我们有一套自己的架构流程,大抵是这个过程:
提出问题 -> 调研 -> 初步方案 -> 讨论 -> 完整方案 -> 架构组分析图 -> 业务方评审 -> 制定计划然后实现 -> 推进落地。
你会发现其中写代码的时间可能不到20%,如果你每天不是在思考或者沟通而是一直在写代码,那你肯定是个假架构师。
其他
说了这么说,总结下我的核心观点:
不要一味追随潮流,基于场景讨论问题。
关注技术的核心价值,不要为了用而用。
不要因为自己是前端而妄自菲薄,每个领域都要深扎下去。
最终,无线和前端领域这么多概念,个人其实很难完全掌控,但是团队一定要有能力掌控,不同的人,对不同的技术栈,做好技术积累和预研,厚积薄发,这样的团队在合适的机会才能更好的发挥整体价值。
OK,本期就是这样了,希望你能耐心地看完,并引起思考,其实灵感君有一种感觉,大家从最初的新鲜,到后来的追捧、热炒,再到现在很多人开始提出问题和担忧,这应该是一个事物发展到一定时期的合理情况吧,我们无法预知前端能走多久,现有技术模式能够适用多久,保持思考和学习是肯定需要的,祝大家都越走越好吧。
PS: 备份内容仅显示纯文字。