专访阿里资深前端工程师桐木:站在10年研发路上

2018-01-10

  桐木:1688的基础业务发展了很多年,在这些年里前端领域的技术也一直在飞速发展,所以前端的架构也一直在演变。WebView中留下了技术发展的脉络和痕迹。比如在一些古老的业务中,还有早期的Prototype式的,以及命名空间来挂不同模块的代码,还有晚一点的YUI的代码,然后接下来进入一个主流的“jQuery + amd loader + jQuery components”的时代,这部分代码现存的还比较多。

  但行业在发展,每个细分领域都越来越复杂,要从头搞到尾既不是不行,也不是太辛苦,而是根本就不可能。真要都搞的话,那么对每个领域的了解只能是半瓶水,搞出来的东西就是玩具。那怎么办呢?这就需要专业细分,在分工以后各自往深处去发展。

  老郭的BeeFramework/Samurai、阿里的birdnest,是在甩前两项包袱,一方面取Web标准的子集,一方面把所有东西都拉到Native的runtime里执行;FB的React Native和阿里的Weex,主要在甩第一项包袱(部分优化了第二项);Mozilla的Servo致力于并行化和GC,主要是在甩第二项包袱;Intel的crosswalk、微信的X5、阿里的UCWebView等,是在一定范围内甩第三项包袱……大家为了甩掉这些包袱,都提出了不同的解决方案。

  对于是否鼓励全栈的问题,其实,只要是有利于提升整体生产率的方式肯定都是鼓励的。全栈是否能够提升生产效率呢?这和业务特点、前后端的服务化水平,以及团队的人员结构都有关系。另外,也需要考虑个人意愿。所以,我们从两方面在推行这件事。一方面是在识别出来全栈确实能够提升生产率的场景下,通过提升服务化水平,来让这件事可能发生,这是外因;另一方面,通过职业发展路线、晋升标准和Job Model等配套设施的优化,配合技术新鲜感成就感的培养,甚至大量福利,来促进一批偏业务的、有全栈意愿的同学能放心且踏实地在这个方向发展下去,这是内因。

  但最大的原因还不在于此,而在于这样做“失去了对未来扩展的兼容”。怎么理解呢?我这里举个具体的例子大家可能就明白了:以Array.forEach方法为例,在比较早的年代,Array对象下面并没有这个方法,当年Prototype库的引领下,很流行用扩展原生对象的方式来“方便地增加一些好用的特性,于是很多人都用添加原型的方式自己添加了一些方法给Array,其中就有不少人添加遍历方法时正好选择了forEach这个方法名,就像这样Array.prototype.forEach=fuction(){...}。

  虽然企业已经使用敏捷流程来开发软件,但是我们还在构建大型的整体耦合在一起的软件。如果你还没有准备好使用微服务,那你肯定落后于学习曲线中的早期接受者阶段了。本文将帮助你创建、发现、调用微服务,开启微服务之旅。

  桐木:混合开发主要是为了实现动态化和节约开发成本,但WebView里跑的部分无论如何也很难达到Native的性能和体验。目前很多技术的发展其实都是在改造WebView,试图甩掉一些包袱或者说历史负担。有人可能会奇怪,WebView有哪些历史负担呢?我们可以来仔细看看:

  我们理解您使用ad blocker的初衷,但为了保证InfoQ能够继续以免费方式为您服务,我们需要您的支持。InfoQ绝不会在未经您许可的情况下将您的数据提供给第三方。我们仅将其用于向读者发送相关广告内容。请您将InfoQ添加至白名单,感谢您的理解与支持。

专访阿里资深前端工程师桐木:站在10年研发路上眺望前端未来爱彩秒速赛车

  桐木,阿里巴巴B2B高级前端专家,专注前端十年。从浏览器到Web前端,从数字电视到互联网,从社交到电子商务,从技术架构到团队管理,桐木老师从这些不同角度出发,深入前端领域,积累了很多经验,悟出了很多道理。桐木老师对前端的发展有着自己的看法,InfoQ带你和桐木老师一起,看前端发展,预测前端未来。

  首先,是标准兼容上的包袱。由于WebView作为一个通用的浏览器内核,本身要求具备向前兼容性,比如虽然用flexbox布局浏览器可以更高效地layout,但为了兼容它仍然必须得能认得浮动布局、相对定位布局甚至表格布局。这些逻辑交织在一起非常复杂,牵一发而动全身。假设我现在fork一个新的WebView出来,裁减掉flexbox之外的支持,就大大降低了layout逻辑的复杂度,即使不做优化就已经能快不少了,更何况情况变简单以后还能够针对flexbox布局做专门的优化,获得更大的性能提升。

  首先,我们在很多场景下做到了PC和无线使用一套核心代码,不同端一套代码。这背后一方面是对前端模型层和后端数据及模型的梳理和抽象,不同的设备和端,在模型层其实差别很小,这部分抽取出来以后就是稳定可公用的一层。另一方面,View层虽然看起来不一样,但很多东西用语义化的方式去描述,又能再次屏蔽掉一些差异。所以到最后有差别的部分只是CSS、交互逻辑、数据的适配和定制以及少量View定制了。

  可能大家已经看到了,VR和AR最近很火。在看得到的未来,我相信变革会因VR和AR的发展而发生,届时前端的很大一部分技能树,可能会完全发生改变,相应的标准也会往前迈进一大步,甚至前端的边界也可能会发生很大的变化。到那时候,称前端工程师为“视觉与交互工程师”或许更为贴切。

  说实话,这个在设计上是很难预测的,比如jQuery的$.each方法,三个参数的顺序就是index,value,array,而后来规范中的forEach三个参数顺序是value,index,array。所以设想下,如果你当时用上面的参数顺序扩展了Array.forEach,那么在标准出来之后,请问你准备怎么修改,才能够让全站所有依赖这个方法的代码和去和新的基于标准方法的代码来愉快地玩耍呢?

  Hybrid方案本身是为了在实际的项目中,使得Native与Web互相取长补短,互为备份的。这里可以特别提一下的是,需要做到面向未来的一些权衡:原则上能用Web做的还是尽量Web来做,有标准的尽量用标准,遇到碎片化、底层能力不平坦的情况,则采用Polyfill的方式。一些为了性能和体验做的一些事情,尽量对Web开发者透明,架构设计上正交出来。

  2011年,Q+的一则招聘广告,激发了我对互联网行业的热情。遂加入腾讯,在即通做平台类产品,同时负责团队的基础建设。2014年下半年,我加入阿里B2B,进入B类电商领域,从此又得到了不一样的氛围和发展空间。

  下一代人工智能应用程序需要不断地与环境交互,并从这些交互中学习。这对系统的性能和灵活性提出了新的要求,而现有的机器学习计算框架大多无法满足这些要求。为此,UC Berkeley项目组开发了一个新的分布式框架Ray,并于近日在Arvix上发表了相关论文:《Ray: A Distributed Framework for Emerging AI Applications》。

  全栈的模式这时候就被提出来了。全栈和最早的万金油模式的不同之处在于,每个领域通过服务化的方式隐藏了大量复杂度和细节,全栈工程师主要关注业务逻辑和业务架构,以及为了实现业务架构,必须掌握的前后端在服务化边界上的技术以及解决方案。这样就可以以比较小成本,由两个人分别把两块复杂业务扛下来了。

  桐木:其实我们这边不太喜欢提前后端分离,更喜欢讲前后端融合。从技术架构来看,需要把数据模型和展现层分离,这就是所谓前后端分离。那融合怎么讲呢?是讲实施层面和人的层面,因为B类业务的复杂度、跨越业务复杂度的门槛往往大于跨越技术复杂度,所以,如果我们能把两边的技术门槛,通过服务化的方式降低,那么在写业务的时候,就可以根据情况,通过后端服务化的方式让前端来把Controller也给写了,或者反过来,通过前端服务化的方式让后端把View给写了。

  另外,还有一个情况:假设有两个业务,业务逻辑非常复杂,我们有两个人来做。如果是一个前端一个后端,那两个复杂业务的大部分细节,都是两个人都要了解的。因为B类业务特别复杂,所以这种情况比较普遍。这时候又不能直接退回到原来的“万金油”模式上去,怎么办呢?

  本期主要内容:Werner Vogels脑中的未来世界@AWS re:Invent 2017;阿里巴巴正式开源其自研容器技术Pouch;从CQS到CQRS;为什么说 Service Mesh 是微服务发展到今天的必然产物?中小型研发团队架构实践:电商如何做企业总体架构?

  所谓真正的分离,应该是在架构层面的解耦,也就是说,不管你是前端还是后端,除了一层Schema约定之外,写Controller的时候完全不要考虑View,写View的时候完全不要考虑Controller。在这方面我们算是已经摸索出一条路来,近来还有一些有意思的想法和实践,有机会的话会和大家详细分享。

专访阿里资深前端工程师桐木:站在10年研发路上眺望前端未来爱彩秒速赛车

  其次,浏览器的内部机制以及js语言在设计上,其实也有一些历史包袱。比如浏览器从一开始设计,js engine和dom engine就是两块独立的黑盒,js调用dom时相当于一次rpc调用,每次调用都会涉及上下文的保存和恢复。爱彩秒速赛车同时,js excute和dom render是跑在一个线程里的,即使两者没有调用关系,dom也必须等js执行完毕才能render。这两件事的结果就是网页在运行过程中会在这两个黑盒之间来回切换,各种上下文切换,各种互相等待,这样一来掉帧就在所难免了。所以,如果我们能够让js engine和dom engine在执行层面能够打通,变rpc调用为本地调用,就能加快不少。更进一步来说,如果能够有效利用多核,把js excute和render在一定条件下并行起来,或者把style resolving和layout并行起来,也能提升新性能。

  面向未来,也体现在技术架构选择上。比如:无论是鸟巢还是Samurai,早期的DSL设计都是Web标准体系比较远的,后面都不约而同的切换到了HTML+CSS+JavaScript这套标准上来了。这里体现了一个原则,就是能用Web做的还是尽量Web来做,有标准的尽量用标准,遇到碎片化、底层能力不平坦的情况,则采用polyfill的方式。

  我刚毕业时,误打误撞进入了数字电视行业,主要工作是做机顶盒上的前端开发(当时的中间件架构,UI层是基于Web的,和后来的Web OS有点像)。我在这个行业里摸爬滚打了四年,其中三年是做前端开发,一年是做浏览器开发。

  归根结底,前端的发展与设备及交互方式的变革是分不开的。十年前我们访问的网页,和我们现在访问网页,在设备及交互方式上的变化是颠覆性的吗?并不是,我们的设备也就是从PC到了手机,在屏幕大小和交互方式上发生了一些变化,相应的,它们各自的机器性能、Runtime性能也有一些提升。但这些变化都算不上革命性的。

  例如现在经常说的一个反模式:“除非你是在很明确的知道自己在做polyfill,否则不要去扩展原生对象”。这样做有什么坏处呢?有人可能脱口而出:“扩展了prototype,会破坏对象的纯净性”。恩,这是个原因,不过因为之前的这种遗毒,大家现在都很习惯for...in的时候用hasOwnProperty过滤一下了。

  不过话说回来,我比较保守,我认为“视觉与交互工程师”这个工种出现的时间不会太近,最近看到的一些VR和AR产品,我觉得成熟度还不够。基于原生API开发的应用都捉襟见肘,更不用说在此之上产生生态和诞生相应标准,并形成类似浏览器这样的UI及交互的统一平台了。前端工程师要成为VR时代的”视觉与交互工程师”恐怕还得等一阵子。

  提一个早点的例子,在做嵌入式的浏览器的时候,WebKit还没火起来。那时,我们维护着一个内部自研的浏览器引擎,当时js引擎和layout都有各种bug,而且从设计上非常难解决。到2009年底,Android 1.5上WebKit的时候,我们意识到该放弃手上这个Web core,然后切换到WebKit了。这是一个较大的转折,当然,中间件全面转Andorid,也是不可逆的潮流。而这件事,则表明了视野和对未来方向的把握很重要。

  不论大家走哪条路,有一个共识还是大家都找到了的,那就是看齐Web的几个标准。因为Web的技术体系在UI的描述能力以及灵活度上确实设计得很优秀的,而且相关的开发人员也好招。所以,如果说混合开发指的是Native里运行一个Web标准,来看齐Runtime来写GUI,并桥接一部分Native能力给这个Runtime来调用的话,那么它应该是一个永恒的潮流。

  虽然企业已经使用敏捷流程来开发软件,但是我们还在构建大型的整体耦合在一起的软件。如果你还没有准备好使用微服务,那你肯定落后于学习曲线中的早期接受者阶段了。本文将帮助你创建、发现、调用微服务,开启微服务之旅。

  虽然企业已经使用敏捷流程来开发软件,但是我们还在构建大型的整体耦合在一起的软件。如果你还没有准备好使用微服务,那你肯定落后于学习曲线中的早期接受者阶段了。本文将帮助你创建、发现、调用微服务,开启微服务之旅。

  近几年我们不同团队也尝试了 ng、avalon、react、vue 这些 mv*的框架,这个方向最终被我们收拢到 PC React、无线 vue & react 的路线上来。总的来说,我们自己造的轮子不多,大体脉络是 YUI→jQuery→mv*,工程体系也是这几个东西的周边配套加上我们的一些定制。