作者:云音乐前端技术团队
来源:https://juejin.im/post/5d25cdefe51d4510835e0329
GMTC@2019于06.20在北京举办,关注前端,移动,AI应用等多个技术领域,本人(编者注:本文作者为陈光通)以一个学习者的身份参与了本次会议,在这里简单介绍一些本次的见闻以及感想。
会议涉及的技术方向包含前端工程化,性能优化,Node,编程语言等14个主题,由于时间有限,我在参会前确定了自己感兴趣的场次与时间,并在时间表上做好了标记。
NodeJS场包括基础设施的完善,开发运维体系,Serverless,复杂应用的框架与开发模式等方面的探讨。目前,NodeJS在各个大厂中大致存在以下几种应用方式:
SSR,提升首屏体验。
作为服务端与前端之间的中间层,也就是所谓的BFF。这样的开发模式无疑是更加舒适的,服务端同学可以更加专注自己的领域模型,而无需太过于关心视图的变化,而前端同学也可以自由组装视图层的数据,不需要事事都求问服务端。
全栈,由前端同学自行开发一些内部的工具系统,甚至C端服务。
不得不说,NodeJS打破了前端与服务端的边界,对前端同学来说,如何维护好自己的NodeJS服务?如何与服务器打交道?如何应对海量的请求以及服务端错误排查?成为了前端同学不得不面对的一些问题。
来自腾讯云开发团队,主张打破开发,测试与运维的边界,提出了DevOps,简单来说就是开发也必须具备运维的能力,其中比较印象比较深刻的有如下2点:
1.基础设施的管理:传统的云主机由于雪花服务器,时间侵蚀,集群漂移等原因,存在各种服务不一致的风险,也难以进行自动化管理。针对这些问题,作者提出了基础设施即代码的概念,也就是基础设施的搭建转换成了配置文件的编写,通过配置文件来保证高度统一,具体落地可以分以下几点:
Docker:以Linux容器的形式对操作系统上的进程进行隔离,通过一份dockfile配置文件即可快速在系统上生成服务所需容器,而服务的一致性完全交给了dockfile来决定。
k8s:基于容器的集群管理平台,帮助我们进行容量的规划,管理,监控。
动态网关:快速完成API的注册,并提供统一的流量控制,筛选,熔断等手段。
2.日志监控:日志格式必须遵循when,what,how,where等几个基本准则。针对复杂链路的日志,可以通过在请求头部增加traceId的形式进行记录,方便全链路问题的定位。
整体下来感觉腾讯云团队的基础设施还是比较完善的,但分享更多是基于大方向,流程方面的介绍,没有太多技术细节透露,不过不得不承认演讲者的思路非常清晰,哪怕是之前没有Node运维的经验的同学,应该也能清楚地认识到各个基础设施,流程存在的必要性以及一些简单的运维技巧。
阿里封装的Midway框架,主要解决的是如何在Node应用越来越复杂的情况下保持代码良好的可维护性,印象比较深的有如下几点:
引入的Java开发中 Ioc(控制反转) 的概念,通过装饰器与xml的定义,在应用启动时生成实例,从而直接注入到Class里。
通过大范围使用ts的interface定义来约束项目数据模型的规范,以模块的形式划分目录结构。
作者在使用上抽离了核心逻辑与框架适配逻辑,通过针对egg,koa,express开发适配层,保证无缝嵌入各个不同的业务场景。
当Node应用变得越来越复杂时,我们不得不向传统服务端去借鉴一些思路,从而减轻应用的复杂度,以便面对更广阔的场景。
不得不说,Flutter在本次大会中还是占据了相当多的篇幅,来自Google的研究员董韬也向我们介绍了Flutter未来的一些规划:Flutter for web的多平台愿景,状态管理方案的建设,IDE上的改进。
个人感觉Flutter在跨端问题上的解决思路还是非常好的,全新定义的渲染引擎让一套代码在不同平台上依然能保持高度一致以及接近原生的体验,真正做到一次写,到处跑。代价就是引入了Dart这样一套全新的语言,然而Dart单线程的运行方式,基于Eventloop实现的异步机制,让它看上去和JS极为相似,相信熟悉JS的前端开发直接上手Dart也不会遭遇很大阻碍。
相对而言,Flutter for web似乎就不是那么让人看好了,它的原理是通过Dart2js将Dart语言编译成JS进行运行,将Flutter的Widget转换成浏览器可理解的Html,Css,canvas,具体流程如下图所示。考虑到浏览器的版本复杂多样,这个过程不可避免会出现一致性的缺失。官方也建议Flutter for web可以作为App在web端的预览版本,而核心的功能还是在App中进行开发。
状态管理方面,社区提供了名为Provider的状态管理库,被官方所采纳,这也从侧面反映了Dart语言目前在生态上还是有待完善的,放弃JS意味着就放弃了NPM丰富的第三方库,这也是我们想要入坑Flutter所必须考虑的。
Flutter在渲染上虽然有独到之处,但失去了动态下发能力让App的更新也变得困难,每次的更新都依赖发版,对于频繁更新的复杂App来说是难以接受的。
美团对此的解决思路利用ios与android动态更新JS脚本的能力,将App中的动态下发模块分为逻辑层与渲染层2部分:
逻辑层:通过JScore运行JS脚本,生成类似于Virtual Dom的对象
渲染层:以流的形式将该对象输入C++引擎,将其转换成Flutter的Widget,通过Flutter引擎进行渲染。
这套方案既保证了Flutter的渲染性能,又能保证动态下发的能力,由于不提供PPT下载,我按照自己的理解画了下大致思路。
类似的方案在微信小程序中的分享中也有提到,可见如何实现Flutter的动态下发还是大家比较关注的话题,但两者在实现上都对Flutter官方库进行了一定程度的改造,实现成本比较大,这似乎是在催促Flutter官方提供更合理的动态下发方案。
UC团队针对信息流内容页秒开的实践,核心是利用Native的能力进行渲染和资源缓存。流程上在Webview列表初始化的时候进行详情页资源的预加载,同时针对视图内的信息流列表进行内容页的预渲染,从而在用户点击详情页的时候可以直接从内存中读出HTML,达到闪开的效果。作者将这种渲染方式命名为NSR(Native Side Render),用以对比之前的SSR(Server Side Render)与CSR(Client Side Render)。
本人在团队中也实践过离线包的思路,但针对HTML的渲染,之前考虑过SSR与构建预渲染,都存在一定的缺陷。
SSR:强依赖Node服务的稳定性,当页面流量较大时,前端不得不建立起比较完善的Node运维设施。
构建预渲染:构建的时候提前渲染好模版,但只能渲染HTML骨架,因为这个阶段即使模拟用户访问拿到了数据,也和真实用户访问时的数据存在差异。
从这个角度看NSR(Native Side Render)倒是一种全新的思路,它将渲染的损耗分摊到了客户端,从而保证渲染不会受高流量访问的影响。但由于它强依赖客户端的能力,如何让这个能力更加通用,让每个Webview都可以定制自己预渲染的时机,这可能是大范围实践这套方案需要解决的问题。
B站的视频体验进化之路:整体听下来感觉还是在解决资源加载顺序的合理分配,简单来说就是让用户最关注的内容前置加载。另外分享者还提到了通过MPEG-DASH对视频流播放进行优化,但由于之前对web端的视频播放不太熟悉,这场就没有太多印象深刻的点。
Event Loop、Future与Isolate - 单线程模型下的Dart异步编程模式:Dart语法课的感觉,分享者介绍了Dart的单线程模型以及通过Future(类似JS的Promise)来实现异步。
首次参与这样的会议,总体来说,不论是当前的一些趋势走向,还是各个大厂的实践思路,都还是带给我不少的收获与启发。
建议大家在参与会议之前针对自己挑选的议题做一些简单的调研和预习,避免在演讲时陷入一脸懵逼的状态(比如我这次在听midway框架的分享时,由于不太清楚其诞生的背景,全程就有点迷)。
最大的遗憾是没能去跟讲师多做沟通,个人感觉分享的内容再怎么精彩,能带来的收获终归还是有限的,能与技术大牛现场直接沟通技术细节才是参与大会最大的优势,可惜这次没能好好利用。
热 文 推 荐
☞ 分享狼叔关于《大前端工程化的实践与思考》
☞ 搭建一个 nodejs 脚手架
☞ 传说中图片防盗链的爱恨情仇
☞ CSS的一些你可能不知道的强大技巧
☞ 为什么视频网站的视频链接地址是blob?
你也“在看”吗?