互联网公司基本都有一个特征:那就是通过规模效应提升效率,满足人们的日常需求。微信/QQ提升了沟通效率,淘宝/京东提升了购物效率,滴滴提升了打车效率,美团让人们更高效地享受生活服务。不同于传统行业的厂房、设备等固定资产占比很高,互联网公司的最大资产就是人,研发投入体现着公司的核心竞争力和发展潜力,费用占比相当可观,研发同学的“客单价”一般也会高于其他部门,因此研发提效的现实意义明显。
基本特征
提效与规模效应相关,研发团队达到一定规模后,提效收益更为明显。比如:通过优化研发流程提效10%,对10个人的团队而言,只能节省1人,而优化流程的投入可能已经超出了1个人的成本;对1000人团队,则能节省100人的开支,流程层面的投入就不那么显眼了,这也是为什么大厂一般会有专门的工程团队自研基建、做流程化的事情,而小团队更多是从实际出发,化繁为简,“野路子多”。
分析
研发提效可以从研发流程、技术架构、运维几个层面考虑,下面从前端研发团队视角逐一展开分析。
提效路径
研发流程
规范性的流程尽量避免并行操作,比如:迭代周期,建议版本串行,减少分支切换、工作模式来回切换的成本。并发式流水线能提效的根源是把复杂任务分解成简单任务,虽然增加了并发协调成本,但执行简单任务的提效远大于协调成本,因此总体更优。需求的实现具有原子特性,如果将评审、方案设计、编码、自测拆分到不同人去执行,效率显然是降低的。
节奏感是可持续的重要保证,节奏乱了,会陷入整体混乱中,效率无从谈起,也无法讲可持续发展了。就像足球、篮球比赛,自己的节奏跟比赛节奏一致时,大概率会赢。业务方的按需发版诉求并非像游击队一样,打一枪换一个地方,也不是一时兴起就要发一个版本。任何靠谱的团队在做事情时都会有一定规划性和预见性,实际操作时产生偏差,更多是因为协同没做好,信息没同步到位。
正常流程外,应设计好突发机制的应对策略,黑天鹅事件总是会有的,不确定性也不得不面对。需要注意的是,节假日促销活动属于可预见性事件,不在此列,不应该临时加小版本,而应提前制定应对策略,比如:调整版本时间、调整需求优先级、封闭开发等。
流程应在完备的基础上,因地制宜,追求简化处理,并落实到文档,复杂的流程条款落地执行时反而增加成本,降低效率。
流程制定时,关联方应讨论充分、同步到位、达成一致,流程并非完美方案,而是各方痛点次优解的妥协。
流程的责权边界应该明确清晰,防止掉链子,或者多头管理。责任和权利对等是基本原则,责任越多意味处理争议时有拍板权,防止争议事件无休止地低效讨论。
流程需要严格执行,关联方应有敬畏心态,打破流程,或非正常流程的执行一般都意味着额外的成本,降低效率。比如:频繁发小版本,需求质量不高,提测Delay,上线Delay等,流程的任何一个环节异常都会导致后续环节的连锁反应,降低整个组织的运行效率。
沟通结论、任务流转应以书面形式固定存档,避免散落各处,无法查找。无法归拢的应以链接形式给出。比如:研发工作流程从PM的需求开始,需求文档按版本归档,每个版本列出需求文档清单,需求文档以链接形式列出UI稿、RD估时排期、任务分工、上线文案等。沟通确认信息在需求文档后面评论。只要有需求池文档地址,就能查找每期的需求描述,复原研发过程,避免人员变动后,无法追溯。规范化意识是基本的工作素养,需要每个人平时日积月累地修炼。
关注流程执行的过程指标,并根据不同阶段持续迭代优化。有些过程指标对团队管理有很好的指导意义,比如:版本工时的波动能侧面反映团队的业务压力情况,提测BUG数侧面反映RD是否有充分自测。研发过程数据提供了一个宏观视角去发现团队的运转状况。
需求问题
需求问题之所以拿出来单独讨论,因为它是方向性问题,而非研发基本功问题,基本功再强,方向错了,也拿不到收益,无法产生价值。功能性补全的需求一般争议不大,有分歧的更多是优化改版类的需求,常见做法是同行对标分析后,通过abtest线上验证,快速迭代寻求最优方案。常见问题有:
对需求池及优先级的认知。业务快速发展,需求一般会走得更快些,研发资源补齐通常会有一定滞后;需求时多时少也是现实存在的问题;此外不同需求实现成本也存在差异,因此,维护一个需求池,并按优先级排序,研发按期消化,避免了业务压力大起大落波动,达到削峰填谷的作用,保持平稳也是提效的积极手段。
需求前期调研不充分,需求评审及后续开发过程中需要反复讨论确认,耗费较多时间和精力。
需求目标过分关注中间指标,而忘了终极目标,比如:一个优惠券的需求,想通过在各展示页面上增加优惠券标签的曝光,来刺激用户的购买欲望,终极目标应该是看转化率是否有提升,而不是优惠券的曝光率有多少提升。
过分追求交互动效,电商类应用的核心应是准确地展示重要信息,方便用户决策,复杂的交互动效实现成本高,有时候还会干扰用户决策。
过分依赖abtest,复杂的流量切分策略,且长期线上并存,导致高昂的维护成本。
人非圣贤,凡事都能有正确判断确实很难,互联网公司有试错文化,对犯错有一定的包容性。需求层面的提效路径,可以通过评审时充分讨论,上线后定期复盘总结的方法,一起提升看问题的成熟度,降低走偏的概率。以半年为周期,定期通晒需求收益的大盘数据,比较直观,也很有效。
技术架构
代码规范
互联网公司一般有严格的用人标准,但也不得不面对一个现实问题,那就是团队成员经验不同、思维方式各异、能力不齐。规范化的代码可读性好,能大幅提升协作效率,可以考虑以下方面:
提倡注释文化,并且是有效的注释。
通俗易懂的变量、函数命名,不要用生僻单词,不要中英文混用,拼写强制检查避免笔误,接口数据前、后端统一命名。
当“回”字有四样写法时,限定一种,比如单例的各种写法。
不鼓励“炫技”文化,让人能读懂的代码才是好代码,代码可读性的要求是讲究低门槛,而不是高门槛,外行都能看得懂的代码才真绝。
代码规范应有文档说明,代码提交时应有自动化强制检查,代码仓库及CI设施基本都有类似的联动功能。
lint、findbugs、checkstyle、PMD这些常见的代码检查工具,接入是很有好处的。
“英雄要问出处”,Android尽量用Google官方的,iOS尽量用Apple官方的,不满足需求时,考虑大厂出品,慎用不知名第三方SDK。
二次封装很多时候是遇到坑时再挖一个坑,最好能从源头解决,此类问题常见的案例是全家桶解决方案,多封装几次,后续维护代码/排查问题的人就抓瞎了。
不定期通晒好的代码,作为范例固化下来。
组件化复用
组件化就是将特定功能代码抽象独立出来,形成SDK供外部使用,达到代码复用和隔离的作用。组件化经常会遇到的问题有:拆分粒度、依赖树收口、边界划定、接入等。
粒度划分过粗,意味着可能还要继续细分,接入方会带入一些不必要的功能,拆分过细,会导致组件过多,提高维护成本和接入成本。
依赖树把控是组件化需要重点考虑的方面,依赖树泛滥是组件开发的常见问题,尤其在快速功能迭代时,只关注功能实现,而忽略组件的相对独立性,因此依赖库的引入需要经过严格评审,防止级联引入不必要的库,使整个组件臃肿不堪。
边界划定就是明确组件的责任边界,不越界做过多的事情,不提供超预期的功能。
接入成本有时候会被忽略,从使用者角度看,接入成本包括理解接入文档、组件接入、功能验证等,组件接入一般包括库引入、初始化、使用等,初始化、使用传参都应考虑极简化处理,对于组件可获得的参数尽量避免直接传入,不传多余的参数,降低使用门槛,有些App能获取的参数,频道组件未必方便获取,因此会影响频道组件对功能组件的接入。
组件最好提供监控日志、调试功能,提高易用性和使用体验。
组件的推广使用,组件化后,使用方越多,提效越明显。基础组件一般非用不可,重心是简化接入、降低升级成本,好用的功能性组件需要一定的推广动作,广而告之,避免信息不畅造成的重复开发。
容器化复用
容器化是近年来比较热门的话题,从业务角度出发,容器化一般具有跨端、快速复用的特点,提效作用相当明显。电商类公司一般会有各种流量入口,一套代码可以运行在不同平台、不同宿主App上,研发效率可成倍提升。常用的容器有RN容器、小程序容器、Web容器等。容器化选型一般要考虑以下因素:
性能问题。从实现原理看,任何容器化的性能都会低于原生实现,现实的做法是通过离线化、预加载等手段,将用户体验控制在用户可接受的范围。
功能实现。不能实现的功能毕竟是少数,抓主要场景。
容器化需要考虑技术成熟度,社区活跃度,自研周边基建成本等。
容器化需要考虑团队的切换成本,包括学习成本,基建迁移,开发模式切换等。
脚手架工程
脚手架工程就是将各基础组件的接入规范化,降低接入成本,提升业务侧从0到1搭建App的效率。脚手架/最佳实践的重要性,可以从下图体会一下:
发展期的互联网公司,每月新增App约11.5个,业务新增1个App,基础组件就需要重新接入一遍,分析App的依赖树,发现依赖SDK达到了691个,其中自研552个,新增App时会接入大部分基础SDK,耗时巨大,基本都是重复劳动,SDK维护方也需要大量时间和精力来答疑解惑。如果按照30pd计算【投入2人,3周完成一款新App的发布已是较快速度,如果需要1周内完成快速上线,一般会先完成核心业务流程,相关基建后续再补齐】,每月可节省300pd以上。
脚手架工程除了基建以外,还会包含最佳实践,既有利于新同学快速上手,也方便保持代码风格统一。在团队切入新技术栈时,最佳实践尤为重要。
高效运维
问题收集
收集问题的渠道一般包括:客服反馈,销售反馈,应用市场评论,App内反馈,相关论坛,社交平台等被动渠道。除此之外,自建监控系统也会通过指标监控做出预警,主动发现问题。
运维指标。指标运营策略应从业务发展现状出发,指标数量不应追求过多、过全,但也不能太少,要符合当前阶段的业务特点,报警、指标值也是如此,同时考虑公司对标、行业对标。
监控预警。预警配置可考虑指标宽严结合,粒度粗细恰当等策略。比如:崩溃率的预警配置,日活千万级,清空崩溃记录是很难的,采用崩溃率指标,对标行业/公司即可,日活不到一万,崩溃率波动幅度很大,可以关注崩溃个数及具体的崩溃信息,不放过问题。
问题排查
对于可复现问题,排查起来相对方便,了解复现路径后排查代码即可。有些业务不具备复现条件,比如:商家类型的业务,跟账号、网络、位置相关,这个时候只能依托丰富的预埋日志排查问题,降低响应时间。
【日志系统】一般包括前端日志、后端日志,相互结合使用,操作上,先根据id信息,从实时性日志初筛,命中的话,排查问题时间可缩短至1分钟以内,效率很高。实时性日志未命中时,再从回捞日志/上报日志排查,信息较多,一般通过时间戳比对的方式加快排查速度。行为性日志更多用于数据统计,事后复盘时可用来统计影响范围,也可分析历史行为辅助排查问题。
-
前端日志
崩溃日志,比较核心的日志,收集方法、口径一致,可对标,一般通过独立的sdk收集上报,同时会搭建配套的分析系统,实时性较高。
用户行为日志,更多是产品侧的打点,实时性较差,一般会延迟1天。
关键点异常日志,定位分析问题时很有用,结合较实时的分析系统,快速定位问题。
可回捞日志,本地临时缓存,可保存较多日志,必要时通过回捞,或引导用户主动上报日志,信息较多、较全。
-
后端日志
- 接口请求打点,主要是接口请求的日志,是后端的视角,跟前端日志相比,不耗费流量,实时性高,缺点是信息相对有限。
【问题分级】主要是从岗位分工角度出发考虑如何提效。近期某互联网公司处在风口浪尖上,有离职员工吐槽大促期间,全员24小时值班。为了及时响应问题,值班制度无可厚非,但不分青红皂白,线上无关员工也拉入值班序列,只能说明管理混乱、急病乱投医了。问题分级过滤就是为了减少“传话筒”,让整个链条的成员各司其职,群策群力,提升组织整体运行效率。低级问题反复扔到研发侧,相当于降格把研发团队当客服使用,也丧失了客服的价值。
-
产品设计问题
- 一般包括已有功能不会使用、交互设计有歧义、流程设计有缺陷、风控导致的阻塞等,此类问题可以从优化产品设计、加大宣讲、机器人FAQ,引导SOP自助排查等方面解决。不需要流转到研发侧。
-
使用环境问题
设备问题【手机权限、手机时间、手机字体、厂商适配、屏幕适配、OS版本适配】,补充关联日志,重点关注可能发生的问题,比如:电话权限缺失无法拨打电话,手机时间错误导致业务逻辑混乱、证书报错等,手机字体过大导致某些促销标签不展示等。
非设备问题【网络不好、DNS劫持、定位不准】,补充监控,通过大盘数据预警。
-
代码缺陷
- 场景覆盖不全、容错不够等,此类问题只能研发侧解决,需要提升研发同学的责任感、设计能力,奖惩结合。
总结
提效是个永恒的话题,对前端研发而言,研发流程提效可以重点关注需求质量和团队协同;技术架构上做好代码规范的基本功,通过组件化、容器化、脚手架工程提效;运维层面做好问题的分级处理,根据丰富的预埋日志,提升排查问题的效率。