“站在10年研发路上,眺望前端未来”:读后感_html/css_WEB-ITnose
偶然间看到了这篇阿里大神的采访稿,看过之后,作为一个对前端抱有极大兴趣客户端开发,作为一个不太懂前端的小白,依然觉得好赞。
站在10年研发路上,眺望前端未来
以下为原文引用
App混合开发的优缺点有哪些?是否会成为主流?
桐木:混合开发主要是为了实现动态化和节约开发成本,但WebView里跑的部分无论如何也很难达到Native的性能和体验。目前很多技术的发展其实都是在改造WebView,试图甩掉一些包袱或者说历史负担。有人可能会奇怪,WebView有哪些历史负担呢?我们可以来仔细看看:
首先,是标准兼容上的包袱。由于WebView作为一个通用的浏览器内核,本身要求具备向前兼容性,比如虽然用flexbox布局浏览器可以更高效地layout,但为了兼容它仍然必须得能认得浮动布局、相对定位布局甚至表格布局。这些逻辑交织在一起非常复杂,牵一发而动全身。假设我现在fork一个新的WebView出来,裁减掉flexbox之外的支持,就大大降低了layout逻辑的复杂度,即使不做优化就已经能快不少了,更何况情况变简单以后还能够针对flexbox布局做专门的优化,获得更大的性能提升。
其次,浏览器的内部机制以及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并行起来,也能提升新性能。
再次,WebView本身确实也在越变越快,但有些OS的限制或者一些设备老旧WebView的存在,会导致碎片问题,这也在拖慢我们的脚步。这个大家比较熟悉了,例如iOS的Nitro、WKWebView之于UIWebView,还有Andorid4.4之后的Chromium WebView之于之前的WebKit WebView。
老郭的BeeFramework/Samurai、阿里的birdnest,是在甩前两项包袱,一方面取Web标准的子集,一方面把所有东西都拉到Native的runtime里执行;FB的React Native和阿里的Weex,主要在甩第一项包袱(部分优化了第二项);Mozilla的Servo致力于并行化和GC,主要是在甩第二项包袱;Intel的crosswalk、微信的X5、阿里的UCWebView等,是在一定范围内甩第三项包袱……大家为了甩掉这些包袱,都提出了不同的解决方案。
不论大家走哪条路,有一个共识还是大家都找到了的,那就是看齐Web的几个标准。因为Web的技术体系在UI的描述能力以及灵活度上确实设计得很优秀的,而且相关的开发人员也好招。所以,如果说混合开发指的是Native里运行一个Web标准,来看齐Runtime来写GUI,并桥接一部分Native能力给这个Runtime来调用的话,那么它应该是一个永恒的潮流。
对fe有兴趣的一个外行
我自己在刚毕业的时候做游戏,做过半年时间的cocos2dx-lua的开发,早在3年前,就已经产生了这种,纯lua脚本动态更新整个游戏app的解决方案,这种脚本解释驱动native的方案,当时就已经让我一个刚毕业的新人产生无限的探索求知欲望。
后来转行iOS,因为业务原因,接触到了和排版相关的工作内容,发现我们的文字排版引擎,都很类似浏览器内核的webcore部分,将UI描述文件JSON(内容类似HTML,CSS)通过解析生成数据结构(类似dom树的东西),再经过排版计算(类似flexbox),生成了渲染结构(类似render树的东西),再进行渲染。
再后来接触了JSPatch,React-Native,这些看起来都能实现动态更新这一目标,但深入思考会觉得这里面很多思路都是完全相通的
- 脚本去驱动native(C++native,源生平台native,runtime动态native)
- 界面描述语言组织布局和渲染
怀着对这种动态化hybrid方案的极度好奇,对于脚本驱动native,对于html+css驱动布局渲染,到底是怎么实现的,极大地求知欲,我对前端也产生了浓厚的兴趣
我从来不认为什么H5开发与Native开发是冲突或者对立的,这俩谁抢谁饭碗的问题,就像引文最后这一段所说的,native与web,我觉得应该是水乳交融的状态。
第四个包袱
我还很不了解FE,但从客户端的角度看这个问题,也有点自己的琢磨,也不知道对不对,真的很希望能有专业人士帮我指正一下,同时我也会尽可能的弥补自己在FE方面知识的欠缺
回到这种水乳交融的Hyrbrid话题上,我觉得,除了大神提到的三个包袱,我觉得还有第四个包袱,rpc不只存在于js与dom之间,还存在于Web环境与native环境两个环境的协议沟通。
既然是hybrid,那离不开na的工作,na的运行环境与js的运行环境是完全独立的两个环境,虽然在一个app内,但二者之间也不是那么顺畅的无缝调用,都依赖于一个桥
- 基于webview hybrid依赖于webview的JSbridge设计
- cocos2dx-lua 依赖于tolua++ 半自动生成的 lua/C++bridge设计
- 基于JavaScriptCore的桥接API的JSbridge设计
桥的设计与调用方案各不相同,但走过这个桥也是有开销和成本的,并不是随便调用的。如果想减少这个包袱,那就应该尽可能的减少web-native通信次数,可能的布局运算,逻辑运算,都先放在web这个环境的内部。
如果拿cocos2dx-lua对比react-native来说,cocos2d-x确实是以脚本驱动native实现了动态更新的目标,但是缺失的确是一整套UI描述语言的布局能力,也就是第一个包袱,正因为完全缺失了第一个包袱,所以才必须频繁的切换luaengine(类比jsengine)与native的上下文,用lua来使用na的布局代码方案进行界面编写,从而造成了我说的第四个包袱的问题(不再是脚本与dom切换,而是脚本与native切换频繁)。
但cocos2dx有个特点,得益于lua这种语言的C内核解释器的运行效率以及以及同为C/C++语言的native部分的相似性,这部分开销在普通的2D简单UI型游戏的开发上,目前看还没啥瓶颈,但是,遇到COC这种同屏多兵种每个兵种各自有独立AI运算的情况下,就会有吃力(以前游戏组遇到的case,不过具体情况还有点复杂,不太好完全归结于第四个包袱)
而react-native正如文中所说,一方面着手优化第一个包袱,而且还以React.js的virturl dom的特点优化了第二个包袱,并且由于在js层处理了布局运算,从而减轻了我说的第四个包袱的压力
我对前端的了解一知半解,这些理解,也不知道说的对不对,片面不片面,最近也在学习前端,希望能补上自己这块知识点的空白,也希望能得到前端同学的指导
我觉得Hyrid,确实就是引文所说,如果说标准webview不能满足性能或者native独有硬件设备上的需求,那么我们就参照借鉴web标准,在native内重新打造一个,经过优化包袱后的web native runtime,毕竟web的标准从灵活性上经历了那么久的考验,而客户端如果能改变一些内核策略,甩掉一些包袱,争取到适应当下移动设备性能并且兼顾动态性的最优体验,那就真的是客户端与前端的水乳交融的hybrid了
以上内容感觉都是嘴炮,没啥干货,也没啥源码,就是自己的一点乱七八糟的想法。。。我还是不归类在搬砖里,归类在扯淡里吧