极光&饿了么 联合论坛 前端技术综合实践

活动背景
随着业务产品的规模越来越大,带来的复杂度也越来越高,前端工程也变得越来越重要。前后端的分离开发,导致了前端与后端小伙伴在开发过程中沟通问题频发。
开发人员在完成产品业务功能的同时,还需要为业务提供高质量的服务;而随着互联网技术的发展,从早期的 Node.js ,让前端开发人员可以触碰到后端的服务,到后来 React Native 的出现,让前端开发人员可以尝试 App 的开发。

面对这些可能出现的实际问题,需要一些小诀窍去让技术栈与业务完美结合。
本期分享聚集了饿了么、极光、Glow、Strikingly 的一线技术专家,就让我们结合实战经验来聊一聊前端技术的综合实践。

主持人:今天是极光和饿了么共同主办的前端专场,首先我们是共同联合举办,现在有特别多的互联网公司,虽然极光不像饿了么特别知名,但是它给很多大公司做一些用户分组,信息处理,积累了非常多的数据经验,也是我们非常666的合作伙伴。

我们整场活动都有直播,可以让小伙伴回去可以看老师讲的是什么,前段时间我看阿里巴巴有新闻说,取消了UI设计师,有很多IT类的知识分享视频学习,另外,今天提问的小伙伴会送到前端相关的图书,中间也会有10分钟茶歇的时间,希望大家可以吃好喝好。

互联网变化特别快,前端的变化也特别快,以前做前端就是页面,现在是可以接触到后端和整个APP的开发,互联网的小伙伴特别需要出来看看大佬们做哪些新的实践,看看小伙伴有哪些心得,你现在做不到的事情无法解决,可以看看大佬们是如何解决,行业内的相关新闻,行业内的动向。

饿了么每个月都会有一两场的技术沙龙,给大家打造技术平台,让小伙伴们听听大佬们讲的是什么,加群后老师们和小伙伴们都在这个群里可以互相交流。有一些疑问也可以在这个群里互相交流。

第一位是技术天才,拿奖拿到手软,有在外企做前端开发负责人,现在是国内第一批涉足Assembly的人,他的主题是Assembly—Web新纪元。

于航:我没有准备开场词,就按照PPT来,我先问一下大家,大家有听过Assembly或者是自己实践过的有吗?我今天给大家分享的是Assembly—Web新纪元,时间比较短,30分钟之内让大家对Assembly有了解就可以了,大家可以在自己电脑上尝试。

我叫于航,现在主要在饿了么π前端做一些事情,为什么是饿了么π,听着很好听是干杂活的,别人不做的我都在做,也有在做一些插件。今天主要是WebAssembly,第一个词是Web,说到Web大家都很熟悉,50%以上的人都是做前端的吧,说到Web就是Web前端、Web开发。第二个词是Assembly,大家是计算机专业都学过一门课叫汇编语言,Assembly就是汇编语言的意思,这里的Assembly是搭配去想,它是汲取了Web技术和Assembly技术的优势,它是汇编语言的效率很高很快,给大家直观的定义是Assembly是可以运用在Web浏览器的汇编语言,还有一点它是汲取了Assembly语言的特性效率很高,速度很快。

我们做下进一步了解,介绍一下WebAssembly的历史。这个词我都没有听过,它是2015年4月WebAssemblyCG出现的,你可以理解为是基于兴趣和需求下自己建立的组织。接下来是2017年3月,两年后四家浏览器达成共识,直到前几个月3月份的时候才纳入WebAssemblyW3C, Working Group 进入了第一个草案。

WebAssembly技术本身的一些东西:第一点,WebAssembly这个词是表现二进制的格式,它是一种汇编语言,我修正一下它是一种格式,把这个二进制格式后,你会发现前两个字节是由Ox6d736100开头。这种格式是以.wasm作为后缀,比如说你生成了一个.wasm然后直接加载运行就可以了,然后增加自己的思路。这里提出一个问题,为什么WebAssembly相比JS性能很高,我要开发二进制的格式,为什么要提出WebAssembly,为什么JS性能很低?所以我才有WebAssembly这种格式。核心问题就是Java Script,只要用它定义就可以。

我们来看一下JS引擎在写JS的时候,它的痛点在哪里,为什么它会很慢?我这里给出一个很简单的:JS是ab。我们来看一下JS引擎要解决这个代码,这是它的流程,要经过这么长的流程,就是JS的+号,在JS的文档都可以看到我对+号,这个引擎在发现加号会做如下的判断,直到判断到最后才能告诉你A+B的结果是什么。它是不是Number,相比之下JS在算Segmnetfault,在.wasm诞生之前,我们创造语言类型是有很多工作要去做的,我们在创立二进制之前有没有人去做呢,其实是有的。在WebAssembly之前曾经做过的尝试,我不需要重新创立的数据结构,只需要把JS稍微修改一下让它去配合尝试AsmJS。AMS.JS是用推送的方式,比如说我给你一个代码,这个代码就是AMS.JS代码,这个不是没有用的,这个AMS.JS是不能去掉的,这个就是AMS.JS引擎。你不需要再去走之前一连串的背景判断,引擎看到这个注释就可以直接做Int去处理,因为它是int,这个代码也是需要浏览器去实践的,我的UIB要如何出来,它是需要去配合处理的。明确标注了AMS.JS的类型和优化,为什么它被抛弃了呢?后面看。

WebAssembly的优化目标,是告诉你不用去判断了,直接拿来用就可以了,WebAssembly的应用是什么呢?我这里给了两条,WebAssembly的目的是说看到A+B不用去解释,直接给到比特码,直接转换成机器码,WebAssembly是让新的格式不再像JS一样进行多层的优化,可以把JS转成机器码,这个就是AMS.JS的区别。

这里给大家看一下V8的编译流程,比如说Java Script从解释器到浏览器(大家不用深入的了解它具体的原理)。我在每层编译器之前是把它抽象的迭代数,经过6层编译器或者是解释器最后才能变成机器码,我把6个编译器减少或者是不要了,我直接放里面效率就提高了。刚才是比较细的。我把每个编译器的名字都放进去。

这里是抽象好的图,这里是JS的函数,这里是Unoptimized没有优化过的编码,然后是再经过一些Hot代码的分析,把机器码变成Backend代码,可以看到从JS代码到最后是有很多步骤,WebAssembly是如何做的?它是从这个地方,整个流程将近末位的地方,这个就是WebAssembly代码直接进入编辑后端到编辑好的代码运行。

JS代码和WebAssembly相比,WebAssembly是减少掉前面,因为在你编译的时候就已经处理好了,这个就是WebAssembly比JS快的原因,经过了前面的优化编译器等等操作,所以我的性能就会大幅度的提升。这个是WebAssembly的二进制,它会把WebAssembly的指令级,这个是可以直接在浏览器运行的机器码。

为什么WebAssembly比JS快,为什么比JS好?这里提一下。为什么WASM被淘汰了,它不需要在中间经过优化编译器的处理,它不需要优化编译器去判断它的类型,所以还是需要前面这一段的过程,WASM是两年前出现的技术,现在已经没有人用了。

再往下看。前面讲了WebAssembly的好处和优势,这里讲一下如果把WebAssembly来用是如何用,现阶段可以通过Emcc等编译器直接将C++代码直接变成WebAssembly格式。emcc是专门用来生成WebAssembly的编译器。这个函数最关键的一句话就是WebAssembly,可以通过这个代码把WebAssembly加载到这个里面,一个最基本的二进制就这么简单,然后它就打出来了,这个是它结果。

这里内存模型会比较枯燥一点。WebAssembly它在内存模型的结果是怎样的?WebAssembly它在内存模型中是独立的,它好的特性是独立出来的,比如说在Fvections为的时候,为了防止去改数据源的安全性,WebAssembly是独立的内存,是有保护的,保证WebAssembly的安全性。独立于应用线性内存的调用栈,保存了所有程序中用到变量的值,保障了WebAssembly的安全性。还有我在C++中写的函数不是以指针写在里面,而是以索引的方式,在WebAssembly就是可以翻译成是多少,我把内存分成了0到Mem—size,它这里是100,那100就会有,从100这里的直接拿掉就可以了,它是通过Ponit来做指针的。还有是说WebAssembly,比如说它是直调用JS,第二点因为WebAssembly是运行在浏览器中,它会遵循浏览器的策略,浏览器的策略你都要遵守。这个是砂箱机制,它不会干涉到浏览器本身的内存。

为什么它用索引会比pointer要好?在处理WebAssembly代码的时候会把函数指针对应索引值,比如说调100那就在100,这个好处就在于我在检测调用函数指针边界,它将会很方便,100是0—10000之间,相比之下普通的程序在Bounds操作的时候如何做,它可能是在整个操作系统上分散的内存端,所以我给你一个函数值,你可能要去编译整个内存才可以找到内存端,但是它不需要,函数是索引,你直接就是0—100可以直接调用。这个Bounds checks,它是有到5%的Overtead,它是零损耗,这个也是WebAssembly在内存模型上优于WebAssembly的地方,现在的是32位的内存,现在是用的很少用不到那么多。

这里会有一个Addressable stack,这个大家知道就可以。

我刚才说了很多WebAssembly的好处,它的介绍性怎么样,我在讲它历史的时候就在讲,WebAssembly与4家达成一致就会根据统一的WebAssembly的标准研发迭代体系。

现在已经有了一些资源给大家看一下。这些资源已经有人实现过的,比如这样一个应用,它是用来对比WebAssembly和JS的对比,第一条线是代表着WebAssembly的性能损耗,下面这条线是蓝色的,这个是用来把一段视频旅游象素都拿出来,把象素流通过WebAssembly处理形成滤镜的特效,我给大家看一下。随便选一个滤镜,WebAssembly性能是高于JS的,大家可以回去尝试一下。

这里还有编译器,大家都想尝试的话可以去编译器尝试,左边是写代码,右边是直接写JS代码,它会自动编译,然后点击运行。如果你想看的更深入一些可以是这种,这边会把所有的机器码,WebAssembly,WebAssembly可读文本,还有左边的代码都列出来,你可以深入的去了解WebAssembly的格式流程是怎样的,还有一些内存特性。

我这里还写过9篇文章,是稍微深入一些内容,大家也可以去看一下,我想通过这个论坛让大家知道WebAssembly比JS好在什么地方。

比如说如何从C++如何转到WebAssembly,还有Emscripten,它是把C++代码到与JS脚本结合,它本身也是提供了很好的虚拟文件系统,第三个是Binaryen是官方推荐的。WebAssembly还有很多特性,比如说WebAssembly只有10兆,它是可以通过IndexedDB进行本地化存储。还有WebAssembly的Memory和Table特性,包括我们说的WebAssembly的二进制编码和机遇前向表达式的Wat或者是WAST,花10个小时也讲不完,大家有兴趣可以去看一下,未来方向是这3个,大家可以看前两个,第一个是GC,就是垃圾回收,系统会自动回收。在JC之后就可以从C++中对DOM引用,GS操作DOM,GC之后对DOM无会直接从C++指针的方式处理,这样就会有很大提升。第二是Threads,主要是应用在优化机器学习和密集计算中比较多,比如说你在浏览器上处理去跑一些机器学习的模型,那么现在只能一个线上跑会很慢,等多线了之就是四核跑会很快。SIMD单指令多数据流,现在是大家用的不多,我今天的演讲就是这样,谢谢!大家有什么问题可以问一下?

提问:你刚刚主要提到WebAssembly的性能提升,效率提升,它相对JS有什么劣势和不好的地方吗?
于航:劣势肯定是有的,绿线一直在上面,其实不是这样的,如果我用WebAssembly,它相当于用JS是低的,低就低在在GS调用WebAssembly模块,甚至它的内存环境都是损耗的,我在JS直接把这个模型加到内存中,然后再代入它里面,就是JS的效率高很多。现在你把整个结算放到C++中实现,这个时候WebAssembly会大很多,所以这是WebAssembly的劣势,还是有损耗在里面。

提问:我之前看到用ASM.js,你现在WebAssembly是可以开发这种游戏的吗?
于航:这个是可以的,我讲的工具链是从JS转成Assembly的。

提问:这个是比较简单就是Java,它使用场景我理解的是有限制调策略,还有是借助前端的UI。
于航:UI方面,不知道你指的UI是哪一块的UI?

提问:是控键,我们编写是用C++来做,哪些能用,哪些不能用,就是像计算逻辑一样的。
于航:比如说框架吗?

提问:它能做哪些东西。
于航:现在只能用在复杂计算上比较好,或者在浏览器到虚拟机,当我们的JC出现之后,你弄这个框架都可以放到WebAssembly中实现,或者是把它移动都是可以在C++中实现。

提问:做图表的话,有些计算的逻辑在里面?
于航:我不知道你指的是哪个UI,它不是用在UI布局,比如说现在是比较耗性能的,你可以理解为把C++可以想到用到的场景都可以放到里面用。

提问:有什么逻辑不想公开的也可以放到里面?
于航:是的。

提问:它反面的是有吗?
于航:成本是有的。

主持人:谢谢于航老师的分享,每个老师就给3个提问机会,接下来请的是极光前端开发负责人 - 凌艺宾给大家分享。凌艺宾老师是中南大学计算机系,他给我们讲最近很火的工具Angular2,接下来请凌艺宾老师给大家分享。

Angular2 组队打怪升级之旅
极光前端开发部负责人 凌艺宾

凌艺宾:这是我第一次来上海,我一过来就下雨。刚才于航老师讲的东西比较烧脑,比较有深度。我希望我讲的风格是比较轻松的风格。今天先简单做一个小调查,我想知道目前在座的各位使用React 、VUE、Angular,还是Angular2?其实都蛮多的,搞的我很有压力。

今天我分享的内容宽度比较广,东西比较多,主要是分几块来讲,这边说的组队打怪升级,组队是讲的极光前端的发展,打怪指的是对框架的使用,升级的是对框架更深度的理解。我先做个自我介绍,我叫凌艺宾,毕业于中南大学计算机专业,之后去了腾讯,当时H5刚出来就开始转前端开发,当时比较早,前端开发发展没多久,包括大家看到的于航老师跟我们分享的WebAssembly、H5也带来了浪潮,很多新技术的是这几年发展出来的,现在去招前端是比较难招的,因为以前很多学校学的、很多培训机构都是后端,前端的很少,因为市面上没有这个课程。前端是在后面工作中发现自己对这块感兴趣就开始转前端了,在组建极光团队的时候也是面了很多人,将近有五六十个,录取的就那么几个,这个行业现在发展看来还是比较新的东西,在座各位前端这方面的开发还是比较幸运的。我们开始吧。

今天分享的内容主要分这5块,第一部分是讲前端发展的现状,讲到前端不得不讲它的历史、兼容性、Angular、Angular和它的背景。前端发展到现在没有多久,以前是做一些页面,对外展示的一些东西,直到04—06年是Google使整个Web体验非常好,当时很多工程师效仿。到06年的时候JQuery才出现,是进行DOM的操作,用DOM改变它的属性和内容。现在流行的V8引擎也是08年才出来的,直到09年的时候Node.js Common JS模块化,不是简单的写一堆编码。

我做的第一个项目是写了一万个代码,是改一个功能到处去搜关健词,当时实在是忍不住了,然后对它进行了改写。从2010年开始,模块化的方式才慢慢开始流行起来。2010年开始框架AMD才开始慢慢出现,大家看这个时间点到现在是不到7年的时间,Angular第一个版本才发布,然后是像MVC在这个时候才出现,还有SPA前后端的分离才开始出现。之后是2013年React发布,2014年Vue框架,这是前端目前最流行的框架,他们是想把DOM去掉,因为是要用DOM去修改它的属性和内容。这里Angular、JQuery技术是想用它底层的逻辑。

这个是目前流行的框架,我们讲一下浏览器兼容性。I9版本是很小,从2014年开始发布了Angular1.3的时候就不对IE8支持,甚至到最后微软自己搞了一个Edge,这个图是Martet Share统计的,一个是市场占有率,Chrome是占到了6%,IE只生最后的17%,我们现在统计的极光官网的浏览器内核,大家也看到Blink,还有Webkit、Gecko加起来是90%了,这个是极光官网的情况,大家看到IE的市场占有率是占4%对于极光官网来说。

为什么极光采用Angular框架?问到这个问题的时候我想说这是世界上最好的语言。今天不对这些框架做比较,从学习曲线来讲Vue和Angular是比较容易学的,所以它需要很多第三方的库去支持,当时是从这里面选,因为历史的原因,内部是自己选了Angular1去写的,权衡了一下就使用Angular去做团队的基本框架,我也是比较过,再怎么比较也没办法。

第二部分开始讲极光在Angular这方面的踩坑过程。Angular最早是09年Google的员工业余创建的框架,之后交给Google维护,2010年发布了第一版本,2012年发布了1.0版本,直到去年2016年的时候Angular2.0对外发布。Angular还在快步的往前跑,2017年3月是发布了4.0,这个月会发布5.0的版本,Google完全推翻了之前的框架重写,为什么呢?因为AngularJS官方用来替代Angular,第一是它的脏检查,它控制JS到更新的控制器,一个大的变量;第二是Scope对象设计论乱,它也是事件派发器;第三是Controller功能太过弱化;第四是Provider体系太复杂,给开发者带来太多的困惑。第五点是Angular设计比较早,它只是为了PC端做考虑设计。

Angular2,第一是引入TypeScript ,第二是WebCompoent,在它的概念中一个大的就是:Component下面有很多个小组建。第三点,它是单向数据流,第四是高效的变化检测机制,异步数据变化,主动大于被动,只需要买些钩子做它自己的一些检测。第五是Service,不用思考,就是用Service。第六是警号的平台兼容性。第七是更现代的框架,这个是Angular2,看一下它大概的定义过程,不细讲了。这个是它的兼容性,可以兼容到IE9。

刚才讲到说极光有很多项目,当时是用Round1的版本去写的,做2就对1进行了迁移,我们是想尝试UPgrade,官方加载两个核,然后是Forward,这个是第三方的解决方案,是用Angular2的风格去写Angular1的代码,这个已经停止维护了。现在是直接把代码全部改成2,第一步是把Angular1配置改成Angular2,并结加上TYPEScript改写,第三是Component迁移,第四是Service迁移,最后是HTML绑定语法改写。

首先我们讲一下编译打包的方式。首先是官方提供了Angular Cli,提供了创建项目骨架,创建组建,测试,运行开发环境,打包,我们发现太复杂了,可能性比较低,不够灵活,我们就把以前的配置优化一下。主要做的这些事情,首先是把TypeScrip编译,第二是开发环境,测试环境,QA环境,生产环境。第三是HMR。第四是用懒加载,预加载,打包上传到它上面去。之后是CDN分环境上传,然后是更新代码里的资源地质,四最后是推送到CI系统,出发自动发布。

接下来是发布的过程,打包、整合、压缩、上传,它的一些资源都是可以通过Gitlab持续继承,发布的时候是把Index发布到主题里面主动更新。AOT编译模式,主要是针对Angular2版本,会把代码加入浏览器里面对模板进行解析,然后是重新界面,首先是都翻译成JS代码,就省去了在浏览器转译的过程,这个内核基本上是占Angular内核的一半大小,可以提前发现绑定错误,用AOT的模式可以发现简单的错误,还有是这个模板方便有更大的安全性,因为在AOT上都已经是变异好了。

前面讲的都是极光使用Angular2的情况,接下来是讲组建化的东西。当时为什么要做组建库呢?当时的项目都有自己的组建,我们的同事很有创造性,自己去找第三方的库,也是各自踩坑,有的组建其他人也有写过,他们可能互相不知道。另一个方面是用了第三方的库,这个库不好扩展,有些需求你可能想都没有想过,而且各种库是要引入JS和CSS,特别是CSS会影响你这些库里面的样式。

前端开发有一半的时间是做UI和交互,另一半的时间是踩坑,Fix bug。我们想到了一些公共的东西找出来。这里是D.ts定义文件,引入功用组建库的时候是如何引入代码的方式,直接Copy代码是不现实的,因为你直接Copy代码别人就不好更新了。当时也在内部创建了私有的Npm registry,拉不下来。当时考虑用Java Scritt还是TypeScrip,最后把Tsc换成ngc。我们用了这些代码是分为这些文件,一个是定义文d.ts是组建公文的文件,做过后端的同学看到会比较熟悉,这个是Java里面的。我们会在d.ts的时候把它放出来,我们在开发的时候需要用到它的什么方法就直接看到d.ts就好了,用其他代码也是直接跳到d.ts来。这个是组建打包的方式,目前极光前端开发一套Jpush ui组建,从项目中来也用到项目中去。然后不断的调整让它更好用,虽然目前有很多第三方的开源组建,我们想自己去开发维护组建,自己开发也可以锻炼我们的小伙伴动手能力,这个不仅是UIkit,它在做的时候不仅是这么一个界面,我们这边拿一个Pager组建举例,自己去分装都是要去缓存一个问题,页面不求缓存就没有这个问题。

先看一个例子,我们要加载一个列表,这个列表是1—50条,去取每页10条,1—10,20—30,然后我要把它切换到每页20条,打开到第一页,只需要加载哪些就可以了。如果是更复杂的情况含成每页40条,那是需要加载哪些呢?这里可以思考一下,可能会认为分两段加载,第一段是10—20,另一段是30—40还没有,网络成本是非常高的,这里是分10—40,合并一个请求加载,但是我们减少了一个网络请求,上面是讲了这么一个缓存问题。还有更复杂的情况,开发者在做每个项目的时候都要考虑缓存问题,哪个加载是最块的,在开发组建的时候就把这个逻辑粉状到Pager组建里面去,我们对Pager做了优化就是数据缓存的算法,我们也做了一个List容器,就是当前页的列表,除此之外是更复杂的删除逻辑,当前页删除之后要补一条,从后面一页补充就是请求一条,是在请求的时候多拉一页,加起来是有11条,当言删完会自动换页,想做的不仅是界面,我们想做的更多的东西是让组件更好用,目前这个组件是在开发中,之后会把它开放给外面的开发组用。

最后一个是讲深入一些讲Angular的优化,会稍微有点烧脑子,先介绍一下Zone.js,Ngzone,异步钩子,被动触发更新,通过这些方式Angular可以做被触动更新就可以了。Angular把Zone封装了一层到内核里。

下面举个例子,我们当时在做开发的时候遇到一个问题,我们做Table的时候遇到一个大而复杂的问题,Table是有很多列,也有很多行,产品要求表头固定,要求左右滑动,而且它要求每行可以展开,展开之后还有很多详细的内容,而且要求每个展开之后有各种不一样的布局,两边的列要固定,中间可以滚动,可以想象一下这是什么样的组建。然后我们用了第三方的组件,改的实在是改不动了,做的是非常崩溃,最后逼的我们不得不去做一些优化。带三方的Table组建通过它去,我们也在整理层面去掉能去掉的东西,然后是把行内一些复杂的详情移到外面去,通过定位的方式定位到它具体的地方,最后实在是受不了了,重写了表格组件,但是最后还是卡,实在是很崩溃。不得不去找其他方案,然后从NgZone上切入,ngZone是鼠标稍微点的时候都会对ngZone做一个更新,表格上下滑动的时候就根本没必要去做这些更新,所以当时发现它有一个Run OutsideAngular,我们去接管整个Angular的变化机制。

最后一点Angular是现代的框架,大家看到现代框架的特点是有服务端渲染功能,Angular也是有的,它是可以开通第三方的工具库去实现,我不去细讲,有个概念就行,今天就分享到这里,大家有什么问题吗?

提问:我们公司也在用Angular4,一个是实践上有问题,我想了解一下贵公司极光测试这一块是如何做的?
凌艺宾:单元测试吗?
提问:是的。
凌艺宾:这个也是我纠结的点,会拖了我们开发的进度,后面会有更多新人进来的时候还会做这方面的东西,现在测试是项目结束之后会有人对整个项目进行测试,现在是比较简单粗暴。
提问:是人肉测试吗?
凌艺宾:是人肉测试,也有自动化的,但是是比较初级的,会有进度的问题,都是要求一两周做出来,后面随着加入的同学越来越多,我们会去重启这方面的工作。

提问:编译完之后打包完的JS还是很大的,互联网这一块有什么好的实践吗?除了刚才说的之外还有吗?
凌艺宾:包括VUE,其实应该也就还好,也就是两三百左右,应该还好。
提问:依赖其他的会大一些?
凌艺宾:也有这方面的考虑,一开始尝试那套解决方案,也引入了太多东西,会有点不爽。

提问:我看到你PPT里是分模块处理的,您是用哪种模式来组织模块呢?是用工具组织还是?
凌艺宾:都不是,我们尝试过很多,但是最后都没有NPA(音)安装好。
提问:是手动的用NPA同步?
凌艺宾:会做这方面的优化,会考虑各个项目的问题。

提问:Angular没有接触过,组件开发,刚刚说了组件每个人都开发了自己的组件,最终是如何让大家一起用你们的组件呢?是如何管理的?
凌艺宾:我是有两三个小伙伴组件开发,各自踩坑,最后把组件抽出来,选一个范围确定,操作都是基本的操作,把这个抽出来之后打包组件,甚至去找某个日期的格子。
提问:你已经有很多的组件了,以后也是小伙伴越来越多,如何让小伙伴知道你这些组建,这些组建是如何做的,你是有库的,我不清楚你到底有没有用,还是有其他的解决方案。
凌艺宾:我们是内部有一个私有库,最主要问题还是Window里面要装私有库,现在拿出来是装不了,最后不得不先写方案。
提问:是装到Window上面的?
凌艺宾:是安装的时候安装不了。 你问题是小伙伴如何知道,我们是组建好伙伴学习,会告诉他这些东西是这么用,在内部把这些东西告诉给其他人,其他人才会知道,不然他还是会开发自己的东西。谢谢大家。

主持人:谢谢凌艺宾老师,有什么问题可以在群里交流。接下来是许帅带来React Native 的实践经验和性能调优。

React Native 的实践经验和性能调优
Glow ios 工程师 许帅(Allen)

许帅:大家知道我今天要讲的是React Native,后面大部分是关于React NativeS,其实是在Web开发当中也是可以用到,前面有问到谁用过React Native?告诉剩下那些人你之前写代码很容易就变成APP,React NativeAPP。

简单介绍一下自己,我叫许帅,在公司里大家叫我Allen,在腾讯实习Web开发,作为Web开发进去之后就做ios开发,下面是我的微博和微信,有问题可以加我。可能大家没有听过Glow这家公司,这家公司是美国女性用户,Glow是健康管理备孕工具,那我们有两个平台是8个F,8个平台是有社区,可以看视频里面React Native社区,今年年初花了1.5个月的时间,从4.6万行的代码变成了1.4万行,改进还是很明显的。

我们为什么会选用React Native呢,年初的时候苹果进入了Hot Upgrade,它也可以跑到安卓上,部署更快,还是要集成8字,第三点整个工作流程比之前的要开发快很多,你只需要刷新一下就可以直接看到你改的效果。PErformance,以前在做React Native开发,这里主要是把你所有非主线操作放到主线上,以前可以通过多效在JS上就得不到了,Phone对于浏览器兼容是自己实现的,在渲染的时候是不一样的,WEEX,我们是先用的WEEX,它在iPhone上有很多BUG。

对于不太熟悉React Native的同学,这个图简单介绍一下,知道React Native不太有的写的是右上方的一部分,你写的代码会跑到React上。从这边开始大部分是关于React,我个人理解React 就是Component&jsx,这里是比较常见的Component,这相当于是Component的指数。前面比较特殊的语法,它最后是被翻译成JSX的话不要害怕,它就是中间的这一段代码,那样写起来会很复杂,所以JSX是提供更方便的语法生成下面的方法。每一个Component主要有两个属性,一个是State,一个是Props,数据流是非常重要的,在State当中是传给你的子,这个例子当中是维护了name State。

接下来是4个点,第一点是关于URL路由,为什么要用URL做路由呢,我们在做APP开发,挑APP会把URL作为像AT一样的东西是非常适合的。第二个是用来GL,它是有系统通知中心,每个通知会跳到不同的页面,最初是定义10种通知,10种通知会出来10种页面,会取出数据,最大的代码就是在通知中心里面,它会知道所有的存在。URL会跳到比较中心化的路由组件。第三个是Fallback页面。这个URL就是用游览其打开也是Ttopick,它里面有一个URL属性,最简单的方式就是正切表达,它如果是个Topick,如果什么都没有配置上就是404,。一般来说是RootComponent,这里会尝试要求每一个Root都是用URL来生成标识,在URL它对应到这边最后渲染到Topickpage,前面的表达是看着很丑,到这一块是把所有的路由作为一个const,被渲染的时候就是作为TopickID,它所需要的模块是不一样的,是需要不同路由的配置文件实现组合的路径。需要在JS挑选Topickpage的时候,就是直接改,而是跳到Native。URL讲完了。

下面是Redux,有很多人用。Reducer,这整个是一个单向,这里的Reducer是纯函数,当你输入一定的时候输出也是一定的,第三,它不会依赖于外部可变的状态,如果你需要有一些副作用的话可以用Sam语言,你只要从React redux的方法绑定到里面去,一般是通过Table区分,Redux。

在用Redux的时候,做Ios开发的同学对这个会有所概念,这里我先说一下一个问题,比方说你生成了一个A,它有一个name叫Allen,你改变了B也就是改变了A,当你的名字有所改变的时候,你是很难知道它有所改变的,你不能通过3个等号来说它变了。一个常见的是Object的方法,这时候你改变B的时候A是不会改变的,这个方案的缺点就是你改变A的时候B已经不一样了,其实它是一样的。你之前拷贝了A,当你改变Bouthor的时候,你会感觉非常浪费内存,这种方案其实并不是很好。faceboook额应该是有很多应用,它是把Map都用成一个A的方法,你靠A改变它方法的时候不是直接去改变,而是通过这个值之后反馈给你一个新的A,这个A本身不会被改变,它优化当这行你尝试把A里面的name改变成Allen,那这个时候B和A是一样的,他恩认为是同一个东西,当你改成另外一个值的时候就是不一样的,除了你改变这条路上的东西,其他的都是引用原来的节点,引用的内存也是很高的。

为什么要用ImmuTable,一般的Purecomponent它会作为一个前比较,所有的T都是相等,三个等号相等,那就是很明确,那3个等号也是安全,如果你用object就是没有刷新之类的。第二是为多线程做准备,用多线程也是比较安全的。前面提到做改变的时候不会改变某一个值。

后面是Single source of truth,这个规范化是什么意思?就是比如说你刷微博,反拍微博的首页,他个人页面也会有首页微博,那是不是同一个对象呢,你默认的话是不同的对象,你点了一个赞,不把它指向同一个东西的话比如说通知之类的来实现就会变得很复杂。我们看一个比较常见的结构,这个是Topic,这里两个author是同一个人,很多代码都不是我们写的,这边是定义了3种数据,你会方便Component,还有一个ComponentList,还有一个只是为了做数据规范化,前面也有数据规范成这样的结构,这样的结构是不是很熟悉,它跟像是关系型数据库,会根据你的对象类型分布表。它是用ID来做,这样的好处是你永远只有一个ID是Component,它是通过ID来引用之前的东西,当你真正想用它的时候,还是反过来传过来你要的类型,然后就会得到对应的Topic。如果你真的想在APP中应用的时候结合这3个东西,你会发现它可以做很多事情,帮你实现很多你想要的功能,比如说一些数据的绑定,一些观察者模式,你有很多Bug也会因此并掉,用了它之后整个APP都是用State,你们用React Native的话,我推荐用这3个(Redux+Immutable+Date Normalization)。

提问:是否有自己的数据库?
许帅:没有一个固定的DB,通过这样的方式在内存里面做一个像数据库的东西便于管理。
提问:我看最后只有一个ID,Component在使用的时候级我需要像以前一样Component。
许帅:你拿到的是object,而不是这个数据库里的一条。
提问:是需要手打吗?
许帅:相当于一个方法。
提问:比如说可以用Get center。

提问:Redex在各个文件中切换,经常要去控制它。
许帅:官方文章中有一个小章节是组织你的Redex。第二点不是手动打出来,都把它定义为不是手感比较细的东西。
提问:因为Redex有些东西不是同步的。
许帅:数据回来之后把这个指令发出去。

提问:对性能这一块你是有什么可以分享的,特别是安卓。
许帅:最早准备的时候,你看活动页面是这些加一个关于性能调优,因为只有30分钟时间就把那一块切掉了,比如说Angular里面比较多的是Angular,你只要在Angular上把它都调掉就变成蓝的,同样的你把红色的变成绿色的也都是很好,ios和Angular的时候是不太一样的,ios你前面有一个文本,后面有一个白色背景,这个时候效率是最高的,它们是反的,这样就是做一些判断。
提问:常列表。
许帅:Flat list,你一开始有一个空的数据库,它不会run一万个当你增加一个的时候,你是从空的出来的时候那就是1万零1个,所有这些事情都是在Flush优化的。

主持人:大家有问题的话可以继续在活动群里提问,接下来请张钊老师来给大家演讲,。钊老师是典型的技术大神,你问他有什么爱好,他会云淡风轻的跟你说自己也会发些文章和写些小工具,是特别热爱技术,特别愿意分享的一个人,上次在公众号发了文章以后,下面很多人会说要看钊哥哥。

百万级应用的服务端渲染实践
Strikingly 前端开发工程师 张钊

张钊:大家好,我是Strikingly的前端开发工程师,因为服务端渲染是非常占CPU的行为,我们的CPU也会经常出现这些情况,希望今天可以跟大家分享一下迁移的活动。

在开始之前想问一下大家,有没有公司一定要服务端渲染的产品。服务端渲染最后是要发到官网上,之前像我们刚才说的在框架不是很成熟的时候,就起一个JSEC包,这样会有很多问题,我们之后会切换到Node的过程。

首先如果大家这两年参加比较多的议题是Google的PWA,服务端渲染也是比较常见的话题,今天主要谈的是另外一个框架叫Hypernova,当我们用户点击输入请求到Server,它会在里面渲染一些Tiger,一般我们不会硬编码,会通过后面的模板进行动态输出模板,然后会有一些问题,在前后端,前端和后端没有分离,MVC难以分离,韩端开发需要服务端环境,沟通成本大。后端专注于数据与业务的逻辑,前端通过数据的火炬进行业务的渲染。这么做还是有一个问题,通过数据才可以渲染出来,这样的话就会有白屏的空档期。这是第一个问题。第二个问题是说SEO问题,每次不是将SEO定编码放在服务端,网站的SEO会有一些问题,在第一次请求之后,我要扔掉的书记就是要操作DOM,这个时候前端组件化的时代降临,后面也是慢慢活了起来。但是使用React和VUC,对于整个爬虫也好,对于组件里面的内容对于SEO是没有任何帮助的。

新的时代以后,Node中间层作为数据的获取实行更多的操作。这使用Express框架,是使用服务端渲染的模板,也是输出,这里通过访问Node的目录就把数据渲染出来,其次使用Node对Jade、ejs再粉状,使用评论框的内容,后面是返回了所有评论,通过具体ID返回用户的基本信息。首先是获取ID,拿到评论的内容渲染对应的标签到页面上,这个时候是到Node层,简单就是分装一下就可以拿到整个结果。Server+JS context使得React和V无ue的服务端宣传变得可能,Hypernova框架,它主要应用的地方是适合新手的项目,直接从头开始创建,它是集成了很多内容,但是Hypernova就是适合冷项目的迁移,这里简单对比一下这两个框架,这两个排名最靠前的两个项目,Open issues和issues处理的都是比较及时,这个是首先做的简单的Hello World,比如说这个文件必须命名为Nice.Js,今天给大家主要介绍一下Hypernova的技术渲染。

首先Hypernova首先是支持插件的环境,Hypernova首先是React,一套组件既可以跑到服务端进行渲染,也可以跑到客户端,这个是简单的例子,对于已有的现成组建,我们只需要重新Hypernova Serner额端,因为我们的Hypernova可以触发这次的渲染。

这个是Hypernova Serner,这个发送请求是需要后端发送请求的,这个时候的后端是需要去发送末端的过程,这里是有多种插件配合,这里是有HypernovaRuby,Hypernova Tiger请求Client,加入说使用Hypernova ruby的话作为HypernovaClient发送请求,它同时提供了不依赖于Responce的方法。

Hypernova是如何工作的,首先用户通过发送请求进行网站访问,,服务端获取到当前页面所有数据并准备进行渲染,这个时候Hypernova Client开始发送到Hypernova Serner的请求进行请求渲染,HypernovaSerner进行渲染,通过Hypernova渲染编辑加入渲染的结果,在客户端,JS会继续进行客户端渲染来实现渐进增强。顶层Hypernova通过不同环境知性不同的代码,使得同一套代码能够跑在不同的环境,能够让你在一个组建里面提前判断好Serner需要获取数据和Runner的地方。

在Serner端就会直接调用,在Clinet就是要重新去获取,同时它多种HypernovaReact进一步包裹组建,通过配置在不同环境跑不同逻辑。恩多种HypernovaWrapper配合,适合不同的业务场景。

Hypernova同时还有多种文件的获取方式,首先仅仅通过静态文件来获取组件,就是直接将Hypernova内部成为Commonjs组件,也可以直接通过Require额函数直接传入组件名称,直接通过PromiseFetch获取远端组件。

为什么这两年Strikingly使用Hypernova,我们只要在入口组件的地方进行包裹,在不同的环境当中。大家看到官网,首先像是Link都是要重新引入的,在不伤害组件的情况下直接使用。我的演讲到这里差不多结束了,大家有什么问题?

提问:我发觉它有Vue的函数。
张钊:它是有多种获取方式,为什么需要VUA获取脚本,如果Fetch脚本,它并不能直接把React(音),有点像是V8里面,首先是把整个文件上下包裹成函数放到里面去跑,这个就是Hypernova使用的地方,但是我们不止使用这一种方式获取这个组件,你明白我的意思吗?我们有多种方式获取这个组件,不一定要通过这个方式。你说的VUM(音)只是其中一个Case的结果。
提问:你们是避免那个Case?
张钊:只是那个VAM(音)的情况,我们是通过Promise  Fetch。
提问:它永远不会释放它的内存?
张钊:你说的VM跑的地方,它是在Foucfion(音)。你也是用Hypernova框架吗?
提问:不是的。

提问:关于服务器端的渲染有什么好处?渲染是有什么过程?
张钊:是渲染效果,它的SEO是非常重要的,无论是爬虫还是什么的都是有这么一段在里面。其次的话就是React  deep区,算是加快了它的速度。

提问:是不是服务端渲染有SEO优化好处?
张钊:如果单纯的只是一个DOM,那通过组件的话就是重新跑了一遍,如果服务端渲染的话,那重新再跑DOM的时候,那算法就会生效。
提问:百万级别的请求,我想听一下你的分享?
张钊:首先我们在开发过程中会有很多其他方面的问题,比如说像一些Loder,我今天主要分享的是这种形式,这两年是炒的比较火,一个是16K,一个是3K,但是他们的这种思想,Hypernova同构思想,而不是应用在级别上面。

(全文结束)