在传统的 React 中所有组件的 state 和 props 合起来才能表达一个页面唯一的状态,state 和 props 分散在组件中,不易收集。而在这个设计中,全局的 state tree 即表达了页面的一个状态,如果将每一次变化后的state tree 都存起来,即可通过回放来展现页面动态变化的过程。更进一步的是,利用这个特性,我们在 200 行代码之内就实现了“录制即测试用例”的功能。用户无需写任何晦涩的用例代码,在调试自己写的页面时只要觉得没问题,就可以将刚才的调试过程保存成一个用例。
这也就极大地减轻了测试环节的压力。之前的思路基本都是通过扫描代码去发现接口错误,要消耗大量资源,现在看起来没必要了。
这两个例子都是从研发的角度来思考所看到的收益,我们再单独从测试与监控的角度来看。
测试领域有一个热点,—— UI 自动化。目前的 UI 自动化有两种方案,图片对比 与 dom 树对比。
(Screenster)
这两种方案都有一个共同的缺点,即“无法正确地识别变化的类型”。例如现在有个需求,视图上的两个元素需要调换一下位置,但逻辑并没有变,希望测试平台不报警。除非人工干预,否则这两种方案都很难判断出来,因为他们是以”最后渲染结果“作为判断依据的。但是如果我们的测试是针对运行时框架来设计的话,就很容易实现。以上面研发时所讲的组件树方案为例,页面到底有没有逻辑性的变化只和 state tree 有关,因为页面的状态是 state tree,而逻辑操作的也是 state tree,所以我们只要认为 state tree 没变,就可以认为页面没有发生变化,不用触发报警。
除了能识别变化外,利用运行时框架的设计,我们还能实现更先进的功能,例如 B/S 架构中还原浏览器端出错现场的问题。在过去 debug 时,我们通常都要与测试交流,按照操作步骤手工还原到现场,如果能由程序自动化一次性达到出错现场,那无疑能给 debug 速度带来质的提升。要实现这种能力的关键点在于,任何表示页面状态的数据,都要能暴露到外部,也能由外部传入进行重置。一旦有一个决定页面状态的变量在函数中,不能取出,不能序列化后传给服务端,就无法做到。毫无疑问,这种能力也是需要应用框架来支持的。例子中 state tree 的设计,有一部分原因就是出于支持这种能力的考虑。
再来看监控领域的热点,“无埋点”监控,和自动化测试有异曲同工之妙。“无埋点”指的是无手工在代码中的埋点,通常是使用可视化的技术来进行“标记”。
手动驱动生命周期对自动化测试之类的功能来说很重要,特别是在做一些基础性的测试时,有了这个能力就不用再完全模拟外部的触发条件。而内部数据的复制和置换则能为录制、还原现场、协同等高级功能提供基础。我们现在就在尝试基于这种能力,实现“用户可以将自己的出错场景一键发送给开发人员来复现”的功能。值得注意的是,有的语言中复制对象是非常昂贵的操作,这时可能就需要考虑,是否使用 immutable 的数据格式会更好?还是依靠一些约定和标记提供自身提供廉价的复制能力?限于篇幅,在此就不再展开。对框架中的数据问题感兴趣的读者可以去搜索 Single Source of Truth 和 Shared Mutable State 之类的话题,业界已经有非常多的精彩讨论。
2.3.2 逻辑
在《月相》一章我们探讨了 web 基础研发体系的构成及部分重难点。相比于具体技术本身,这套方案对组织成长和重塑的意义更大。在这一章中我们会先从大团队中两个有启发性的问题出发,逐步深入到如何打造一个更高效的研发组织方案中。虽然问题出现是在大团队的,但对小团队仍有两点借鉴意义:
小团队随着业务发展会长成大团队,也可能碰到一样的问题。
问题本身萌芽于成长过程之中,予以正确的指导能更加节约人力,助力公司发展。
3.1 平台林立
首先注意,我们讨论的仍是 web 层的问题。这个现象在有多个不同业务的大公司中最常见。出现这种现象的原因有两个,一是公司到了万人规模,实际上就相当于上百个百人规模的小公司,必然想法很多,出现重复的自然也多。
另一个更重要是,在 web 这个领域,特别是前端,基础设施变化太快。
无论是浏览器底层所支持的 api,还是 javascript 语言本身变化都非常快。底层一变化,研发的各个环节必然出现基于新技术的空缺,很多框架和平台就是随着这些空缺出现的。现象本身存在即合理,但如果有更好的统一管理,是能从如下两个方面提取出巨大的效能的。
一、如果将研发流程中的各个环节中独立的平台统一,可以极大地加速业务开发。直接决定业务发展速度的是进行业务开发的工程师。他们最希望的就是只有一个平台将研发的所有流程都搞定,并且尽量自动化。平台一多,对业务开发工程师来说,学习、沟通、协作的成本就会陡增。这个成本有多大?在我们通过线下了解发现,这个成本很多时候甚至会超过业务开发本身。
二、加大对趋势和方向的研究,预防无序的框架和平台的投入,这样能尽量防止走偏和无效劳动,也是一种提升。越是大的团队,这一点越明显。“基础设施变化”这样一个滚滚巨轮这些年压碎了多少框架和平台,其中很多产生的效益都不足以覆盖其研发成本。更坏的是,出于个人利益等原因,有的平台过时了也不肯下线,阻挡了整个团队随基础设施一起进步的机遇,消耗的是更多的未来的人力。
我们在《月相》中提出的研发体系就是实现这两个提升的具体手段。
首先,有一个完整的体系来将研发流程当成一个整体对待,并且通过统一的平台来实现,能更好地实现流程的自动化。降低一线工程师沟通、学习成本。
其次,对运行时框架的投入,本身就包含着对趋势和新技术的研究,可以缓解被基础设施带着跑的问题。并且我们看到运行时框架研究到了一定程度,能够极大的减少后续测试、监控实现的成本,也降低了基础设施变化所产生的多米诺效应。这里对管理带来的反思是,我们应该谨慎“平台化”的思考。特别是下游环节,因为“平台化”的思维,必然要考虑对各种不同的端进行适配,必然要制定各种规范,这些都是人力成本。如《月相》中所示,上游理清楚并且统一后,下游是能有针对性地、很低成本地实现的,根本不需要“平台级”的成本投入。当然,在这里所说的只是减少技术上的投入,环节本身还是非常重要的。
平台林立从某一方面来说也表示着团队内部有着大量的无序的力量,这种力量在团队出现不同环节的分工时就产生了,尽早地建立研发体系就能尽早地将这些力量用起来,创造真正的价值。
3.2 资源池
很多大公司的 web 研发团队都被当成资源池来用,哪个业务需要就投入到哪里。现象的直接原因有两个:一是从管理的角度来说,web 层的研发工作相对来说可替换性强,具备形成资源池的可能。二是 web 研发处于业务决策链底层,人员相对来说最紧张,因此通过资源池的方式能动态地支持业务开发,是最简单的解决方案。但这个方案其实是相当低效的。我们从对工程师个人的关注来切入这个话题。
首先从主观的角度出发,一个有激情,对职业未来充满憧憬的工程师与苦大仇深的工程师在效率上是有成倍差别的。除了其本身的性格外,造就这两种态度有很大一部分是职业上升渠道的问题。首先,和任何能被当成资源池来用的工作一样,因为可替换性强,所以不容易被重视。其次,目前的上升渠道不够。web 研发工程师的上升渠道要么是纵向的,当业务发展得足够好,重要性提高,成为系统负责人。要么是横向的,随着团队扩大,管理需要,成为管理者。这两者一个基于业务一个基于人力,和技术相关不大。所以有才华的工程师自然会想要造框架、造平台,努力成为公司技术中重要的一部分。但没有正确的引导,就会成为上面所说”无序的力量“,发展得不对反而会变成公司的消耗。而当他发现自己付出的努力得不到回报的时,就有可能变成苦大仇深的工程师。
最终影响的不只是工程师自身,公司也会要在管理成本上为其买单。我们在与一些资深 hr 交流时,他们进一步说明了这个问题。在公司工作了四、五年的员工,是已经融入了公司,理解公司文化也了解公司问题的人,算是中流砥柱。如果得不到好的上升,可能会有两种情况:其中有想法有行动力的,多半会选择离开。既会对组织稳定性会造成影响,也会让公司付出的培养成本付诸东流,对公司来说可算是很大的损失;另一种更不好的则是既不离开,也不像以前一样努力。他们在团队内有一定的话语权,却丧失了进去的激情,不再发挥积极的作用。当公司需要快速扩张、快速发生变革的时候,他们就会成为隐性的管理成本。
而解决方案,其实很简单。大公司内部通常都有”框架组“、”平台组“类似的部门,但基本都停留在”可用“阶段就完成任务了。这远远不够,如果将建立 web 基础研发体系作为目标,以产品化为衡量标准,加强重视和投入。 web 工程师的上升渠道就会得以扩张,公司内无序的力量就会进入到正确的领域。创造的价值又能进一步为研发提供能量,形成一个正循环,逐步缓解人力紧张的态势,资源池现象也就自然会消失。这很像我们身体受伤时,外部肿胀只是炎症的表现,消炎了,肿胀自然也就好了。重点是找到关键进行消炎,而不是围着外部现象思考。
建立体系还能带来的好处是,通过提升 web 研发的效率,降低业务研发所需的人数,能帮助大公司重新回到小步快跑的节奏。张小龙有一篇演讲《警惕KPI和复杂流程》,讲到了小团队的重要性,随着互联网公司的竞争越来越激烈,这种重要性会变得越来越高。我们从一些互联网的新巨头上,其实已经看见了“核心技术+基础web研发能力”来快速出产品,占领市场的趋势。对小公司来说,统一的 web 基础研发体系,是帮助实现超车的重要一环。对大公司来说,则是进一步挖掘效能,防止掉队的必修课了。
4 后记
这篇文章笔者前后重写了三次,因为面对 web 一线工程师这样一个庞大的群体,效能提升已经不仅仅是技术或管理某一方面的事情,而是要综合各个方面来寻求个人和公司发展的共赢。 web 一线研发是很多工程师进入这个领域最开始做的事情,但是笔者看到了很多有才华的人困在了低效、重复的工作里面,努力了也因为方向不对而徒劳。这对个人和公司都是损失。在技术上找到方向,在管理上予以支持,多方发力,其实能提升的效能远超十倍。当然,一篇文章不足以实现任何改变,这篇文章最主要的目还是抛砖引玉,也希望对这个方向有想法,志同道合的朋友联系我,一起交流,一起推动。
邮箱: ariesate@outlook.com。
5 答读者问
问:框架研发提升效能的趋势?
答:分两个方向。一是框架本身,会朝着“增强对用户代码的理解和控制力”这个方向前进。用户按框架写的代码,能不能通过工具分析出具体的语义?人工的低级错误能不能自动检测出来并自动修正?能不能转化成某种人类习惯的表达方式,比如图?当控制力达到一定程度后,这些能力都实现后,再往下应该就是代码的自动生成。
另一个值得一提的是框架能力与业务特有属性会一起沉淀到 IDE 上,会出现面向专有框架的 IDE,面向单个具体工程的 IDE。分析图,自动扫描工具都由 IDE 作为载体,就像很多游戏的专用编辑器一样。只有沉淀到 IDE 上才是最便捷、最有针对性的。对这个方向感兴趣的读者可以跟我邮件讨论,目前我们已经有一些初步的想法。