打磨移动时代的前端团队(三)—— 工程效率篇

快鱼吃慢鱼的商业时代,生存法则就是 “快”!,而我今天要阐述的“快”所指的,不只是单纯的开发效率环节,同时也涵盖了协作效率、研发资源调度、组织过程资产等部分组合在一起的整体效率问题

当聊起前端,很多人会觉得非常简单,随便拿个记事本也可以做个页面,很多人正是因为前端的低门槛才开始踏上前端之路,而现在,各大前端技术社区却呈现一片迷茫之声,多少有志青年被迫沦为摆烂的码农,框架的使用者,工具的使用者,在三天一新框架的行业内卷下,哭喊着 学不动了,十年的经验,水平却停留在了工作后的第三年,而职业天花板肉眼可见——国内鲜有研发负责人的岗位是由前端负责人担任的。同时各大工厂都在哭喊:前端缺少人手

我曾和很多前端从业者聊过对这个行业的理解,最普遍的认知出奇的一致—— 易懂难精,门槛低,天花板也低

让我们不妨盘一盘整个的来龙去脉:

起初,只有原生代码,前端修着各种Bug和背着无尽的兼容兼容问题艰难前行。

接下来,非常“幸运”的有了很多诸如JQuery之类的简单又给力的各种前端库,随手就可以完成开发需求,普通的开发者要不了多久就成了一个团队的主力开发者。

当一些人以为前端不过如此,驻足享乐之时,前端领域却以爆炸式的增长出现在各种论坛,头条和Twitter 上。

和每个新兴的领域一样,造山造神造轮子,前端也不再是美工和“页面仔”们的玩具,很多服务端开发的人也踏入了这片新大陆,轰轰烈烈的跑马圈地,给力的推动了这个领域的发展。

oop 、设计模式、 MVC、前端模板、微服务、中间件各种服务端的陈旧的概念套在了前端的马车上依然锃光瓦亮,熠熠生辉 。

PC时代还没有终结,便进入了移动互联网时代,终端设备和交互方式同时发生了变化。

新的平台新的时代,带来了更多的商机,激烈的市场竞争也日以继夜地进行着。

在这种背景下,刀耕火种的编码方式再也无法跟上激烈竞争的市场变化。无数的旧有web项目,像磊高的鸟卵,随时都会崩塌,没人敢动。

我们开始重构,同时也背负了就有项目的技术债务,还有来自移动端的各种新特性和兼容问题, 很多前端团队曾一度被吐槽:

为什么一个小的需求,需要这么久?

技术的挑战对于商业需求,是不可见的。我们能做的是,找到瓶颈,提高效率!

就像住宅,
以前住山洞. 只需要铺点稻草。
现在我们要盖摩天大楼,我们需要 工程化

今天的话题就从工程效率开始:

  1. 工程效率

所谓提升效率,是一个相对概念,实际开发中,很多效率消耗是看不见的,却占用很多的时间,藏匿了很多的风险,所以首要任务是找到瓶颈,再找个趁手的兵器去解决掉这些的重复且易出错的流程。

shell ,grunt ,gulp , webpack, yeoman,vite, rollup, parcel ......

这些是搭建前端自动化工作流的常用工具:
还远不止这些,很多公司也都在做自己的构建工具,毋庸细表。

主要解决的是以下问题:

  1. 性能
    前端自动化有很大一部分工作是为了性能,yahoo在很早以前就总结了前端的34条优化原则。
```
   1. 尽量减少 HTTP 请求次数
   1. 减少DNS查找次数
   1. 避免跳转
   1. 可缓存的 AJAX
   1. 推迟加载内容
   1. 预加载
   1. 减少DOM元素数量
   1. 根据域名划分页面内容
   1. 使 iframe 的数量最小
   1. 不要出现 404 错误
   1. 使用内容分发网络
   1. 为文件头指定Expires或Cache-Control
   1. Gzip压缩文件内容
   1. 配置ETg
   1. 尽早刷新输出缓冲
   1. 使用GET来完成AJAX请求
   1. 把样式表置于顶部
   1. 避免使用CSS表达式(Expression)
   1. 使用外部JavaScript和CSS
   1. 削减JavaScript和CSS
   1. 用代替@import
   1. 避免使用滤镜
   1. 把脚本置于页面底部
   1. 剔除重复脚本
   1. 减少 DOM 访问
   1. 开发智能事件处理程序
   1. 减小Cookie体积
   1. 对于页面内容使用无coockie域名
   1. 优化图像
   1. 优化 CSS Spirite
   1. 不要在 HTML 中缩放图像
   1. favicon.ico 要小而且可缓存
   1. 保持单个内容小于 25K
   1. 打包组件成复合文本
````

这其中,很多都是可以在自动化工具的构建过程中做到的,性能有了初步保障。

  1. 流程
    一个项目在开发过程中存在很多流程,它们重复频次高且容易出错:

  2. 创建项目

  3. 创建页面

  4. 创建页面相关资源

  5. 创建模块

  6. 创建模块相关资源

  7. 详细设计

  8. 创建接口文档

  9. 创建模拟接口

  10. 接口联调

  11. 编译

  12. 单元测试

  13. 推送至联调机

  14. 提测

  15. 预上线

  16. 上线

  17. 回滚

  18. 监控

  19. 协作


协作着重点是:与PM协作,与后端协作

与PM协作:

前端团队需要跟其他团队紧密协作,沟通协作也是制约因素之一。在过去的项目中,你是否经理过由于沟通误差导致的无效开发,甚至线上事故。

我发现技术团队正在忙碌的时候,产品团队有新的需求往往又不知道我们的人力状况,这对他在指定产品迭代计划不利,导致PM单方面制定了很多不合理的“时间倒推型”项目,研发团队集体持续加班。实际上某些情况下本可以避免的,毕竟,人困马乏非常态用兵之道。

对于我们团队的人力投入状况,以及人力释放的计划,完全可以用工具 来显示。进一步的,PM可以在此申请项目,申请人力。但前提是,团队需要把技术架构统一,使得开发者更方便的跨越产品线做技术支持,对于业务的深刻理解实际上是一种组织过程资产,需要团队内部串讲与共享。

与后端协作-前后端分离

互联网伊始,并没有如今这么明细的分工,开发人员包办了所有开发任务。
回看那时的业务形态,多半是 新闻系统,企业网站,还有就是BBS。界面和交互基本都是千篇一律。

直到web2.0概念兴起,挂起了页面重构风,前后端的分工越来越明确。
时至今日,前后端分离变成了热议的话题。

联调过程一直是WEB开发的痛点,在工作流中集成解决方案,可以更快定位问题,减少沟通成本。

基于nodejs的SSR与服务层实践:

很多公司都在行动。最典型的是“某宝、某里”公司,nodejs接管了许多产品线的httpserver,做业务接口聚合,越来越多的服务端逻辑,被前端团队接管。后端变成了纯粹的数据输出层。

笔者曾在某浪公司也推动过nodejs的前后端分离解决方案,遇到了一些阻力。 究其原因是多方面的:

  1. 服务端编程并非掌握一门服务端语言这么简单,前端团队的服务端开发基本技能不够扎实。

  2. nodejs的人力来自前端团队,但就我所在的团队而言,短时间内并不是每个前端都可以胜任服务端开发。开发和维护都容易出现人力瓶颈(曾经就有杭州的一个nodejs项目接过来以后变成了烂尾,后来还是被改回了php)

  3. 技术负责人鲜有nodejs语言和项目的把控能力,一旦项目出现技术瓶颈,将很难把控。

  4. 原本后端的工作交接给前端来做,后端剩余人力又当如何安排?当然,也考虑过请后端的同学学习使用nodejs,但收效甚微。也许是他们找不到理由学习和使用nodejs。

这种架构虽然在有历史架构包袱的公司很难普及。但是一些新团队大胆的采用nodejs堆栈,推行全栈工程师文化(这里的全栈仅仅等于client端+server端开发,更深的全栈是不局限语言的,不同的需求,采用不同的技术解决方案)。

不过也有落地成功的,比如某知名技术社区“某SDN”使用nodejs支撑了全站消息通知服务。某“出行巨头“公司,甚至用nodejs支撑了整个金融系统的券服务与活动系统。

充分说明了,不是语言的问题,事在人为。

基于其它服务端语言的SSR:

笔者曾有幸在某度工作过两年,当时的前后端分离方案是基于前端写php的starty模板,前端开发需要依赖php环境。当然如果没有别的方案,这样的架构当年也是跑的可以。只是沟通和成本变得昂贵。

某东电商的前后端分离也与此类似,只是京东是基于java的。写的是java体系下的模板语言。 好在京东的前端工程化把模板环境集成了进去,使用Nodejs就可以支撑java模板。做的比较完善。如同Fis一样,京东的前端团队推出了 “jdf” 自成一体。(npmjs.com 上面可以搜索到)

相关的技术也在快速迭代—— 云函数、serverLess、graphQL

技术积累与知识共享


  1. 知识共享
    做过业务开发的人,都知道,每次的项目都会遇到一些奇葩的问题,尤其是前端领域,这种情况更普遍。知识共享的目的是希望可以有一个地方搜索别人是否遇到同样的问题

由于业务形态不同,在搜索引擎和stackoverflow未必能找到答案,所以需要我们自己的要有知识共享库,它将随着时间推移避免更多人踩同样的坑。
这在前端工程化里是个弱需求,但从长远来看它,不可或缺。前端工作流最好提供一个更简洁的方式,让开发者可以快捷的提交到知识库中。后续可以在邮件收到关注问题的互动信息。

  1. 组件生态

    组件化,也叫模块化,插件化,是一种分治思想。

    组件化之路其实也是软件世界的进化之路,前端亦是如此,从面相 对象编程到模块化开发,越来越多的框架涌现,让人目不暇接。

>我不想讨论如何做模块化开发,因为这不是工程化的重点。

当你选中一个框架,决定将后续的业务代码,按照它的规范进行模块开发, 那么问题来了: 
  1. 如何提交这些组件
  2. 如何迭代组件版本
  3. 如何解决组件依赖
  4. 别人如何使用你的组件
  5. 一个标准的组件包含哪些部分
  6. 如何沉淀出优秀组件

当你解决掉这些问题,我就认为你已经 建立了一个组件生态环境
当项目以堆积木的方式开发,才能有。

前端自动化测试


前端的自动化测试一直都有争议,问题症结在于投入产出比,以及覆盖率问题。

从工具方面其中涌现了许多给力的测试框架:

Mocha& Chai

JavaScript 在很长一段时间内是非常烦人的。测试任何代码通常都被认为是恼人的,但它却是每个开发人员都应该做的事情。每个开发人员似乎总是蔑视和忽略它,而不测试他们的代码。这个恼人的东西有一个解决办法,那就是 Mocha 和 Chai。两个库的名字都来自美味的热饮料,它们都能帮你测试代码,但方式不同。

Mocha 是一个 JavaScript 测试框架,使得你在 node 模块和浏览器 app 中测试异步代码变得更容易。Mocha 测试可以串联运行,可以为正确的测试用例添加异常跟踪的能力。
Chai 是一个行为驱动开发/测试驱动开发的断言库,可以搭配 Mocha 使用。它可以把你需要测试的东西用可读的风格简单地表达出来。

何时使用 Mocha & Chai?总是!请测试你的代码,让世界变得更美好。

Karma
既然已经把 Mocha 和 Chai 包含在这个列表中了,如果不包含用来运行这些测试或设置持续集成测试的测试运行器,那将是不完整的。Karma 是一款旨在帮助你在不同的浏览器上自动运行测试的工具。它可以帮助你在所有浏览器上运行 Mocha 和 Chai 测试。
不是每个浏览器都运行在所有平台,但幸运的是可以使用一些免费工具来测试其他浏览器,看看 Browser Screenshots。如果你正在 OS X 上运行代码,想测试 Edge 或 IE,可以 免费 使用这个工具。

在前端工具中,的每次编译任务集成自动测试使得每一次的修改更加放心,但是,很显然这里面有个测试用例和覆盖率的成本问题,这是一个博弈的过程.

我的想法是不推荐在所有业务代码中都去写测试用例,只在通用性较强和比较关键的,重复迭代的模块中使用。

开源贡献

不重复造轮子!除非你的轮子是革命性的。

在这个技术领域“物产丰富”的时代,往往会发现互联网上能找到很多你原本想要自己做的东西,你唯一需要考虑的是如何使用,如何按照自己需求去迭代。

开源是这个时代最好的礼物,可以通过开源快速满足项目需求,交流技术,认识更多更优秀的人。

如今对于程序员的社交平台 非github莫属了。

一个高产的团队,不仅要满足业务需求,还需要有开源精神。

不但要把自己团队产出的资源共享,也需要与你使用的开源项目一起迭代,积极提交PR(pull request)

github如今也变成了招聘技术人才的绝佳平台,从他的代码上基本可以基本了解这个人的技术能力,甚至性格和追求。

代码审查

关于代码审查,很多团队都表示难成其重,成本太高。作为学习使用。
也有作为开发流程的一部分,强制执行的。

在这里,我想谈的是,如何建立一份代码审查清单:

常规项

代码能够工作么?它有没有实现预期的功能,逻辑是否正确等。

所有的代码是否简单易懂?

代码符合你所遵循的编程规范么?这通常包括大括号的位置,变量名和函数名,行的长度,缩进,格式和注释。

是否存在多余的或是重复的代码?

代码是否尽可能的模块化了?

是否有可以被替换的全局变量?

是否有被注释掉的代码?

循环是否设置了长度和正确的终止条件?

是否有可以被库函数替代的代码?

是否有可以删除的日志或调试代码?

安全

所有的数据输入是否都进行了检查(检测正确的类型,长度,格式和范围)并且进行了编码?

在哪里使用了第三方工具,返回的错误是否被捕获?

输出的值是否进行了检查并且编码?

无效的参数值是否能够处理?


文档

是否有注释,并且描述了代码的意图?

所有的函数都有注释吗?

对非常规行为和边界情况处理是否有描述?

第三方库的使用和函数是否有文档?

数据结构和计量单位是否进行了解释?

是否有未完成的代码?如果是的话,是不是应该移除,或者用合适的标记进行标记比如‘TODO’?

测试

代码是否可以测试?比如,不要添加太多的或是隐藏的依赖关系,不能够初始化对象,测试框架可以使用方法等。

是否存在测试,它们是否可以被理解?比如,至少达到你满意的代码覆盖(code coverage)。

单元测试是否真正的测试了代码是否可以完成预期的功能?

是否检查了数组的“越界“错误?

是否有可以被已经存在的API所替代的测试代码?

你同样需要把特定语言中有可能引起错误的问题添加到清单中。

这个清单故意没有详尽的列出所有可能会发生的错误。你不希望你的清单是这样的,太长了以至于从来没人会去用它。仅仅包含常见的问题会比较好。

优化你的清单

把使用清单作为你的起点,针对特定的使用案例,你需要对其进行优化。一个比较棒的方式就是让你的团队记录下那些在代码审查过程中临时发现的问题,有了这些数据,你就能够确定你的团队常犯的错误,然后你就可以量身定制一个审查清单。确保你删除了那些没有出现过的错误。(你也可以保留那些出现概率很小,但是非常关键的项目,比如安全相关的问题)。

得到认可并且保持更新

基本规则是,清单上的任何条目都必须明确,而且,如果可能的话,对于一些条目你可以对其进行二元判定。这样可以防止判断的不一致。和你的团队分享这份清单并且让他们认同你清单的内容是个好主意。同样的,要定期检查你的清单,以确保各条目仍然是有意义的。

有了一个好的清单,可以提高你在代码审查过程中发现的缺陷个数。这可以帮助你提高代码标准,避免质量参差不齐的代码审查。

小结


高产的前端团队,最终还是取决于人,工具自动化,组件的生态,质量把控, 这一系列的努力,才能让一个团队保持激情和战斗力。

开源社区的使用、互动和参与迭代,甚至走出公司做技术交流的活动,让团队技术视野保持在业界水准。

最后借用jobs一句名言: 保持饥饿,保持愚蠢

你可能感兴趣的:(打磨移动时代的前端团队(三)—— 工程效率篇)