添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

能力说明:

了解变量作用域、Java类的结构,能够创建带main方法可执行的java应用,从命令行运行java程序;能够使用Java基本数据类型、运算符和控制结构、数组、循环结构书写和运行简单的Java程序。

获取记录:

2019-11-26 大学/社区-用户参加考试 2019-11-26 【Java学习路线】Java语言基础自测考试 - 初级难度 大学/社区用户通过技能测试 诚如很多大V所讲,确实是2020年,前端圈带来具有突破意义的内容或框架不多,很多人也不会再有2013年到2017间日日新的框架大战局面,也不会有Node全栈之争,也不会因为React-Native、Weex、Flutter这类跨端而欣喜若狂。 我能看到的是今天前端已趋于稳定,在深水区探索,比如蚂蚁金服的x6,在图形可视化方面做的就是非常好,比如淘宝的midway-faas,在Serverless领域确实有它独特的定位。比如语雀,钉钉文档,在线Excel等等,也都不是可以轻松可以搞定的。 我很开心的看到,混乱之后,大家都能在深水区里进行探索。2019年阿里经济体前端委员会四大技术方向:第一搭建服务,第二是 Serverless,第三是智能化,第四是 IDE。2020年阿里经济体前端委员的突破方向是互动技术、跨端技术、智能化。而中后台、数据可视化、Node.js(Serverless)、工程体系(安全生产)都变成了基础技术方向。这大概是能够代表前端技术走向的。 我个人也走过类似的路,2017年加入阿里,将PHP替换为Node.js,随后搞了开源项目egg-react-ssr,然后在2019年加入前端委员会,负责Serverless-side render方向。在2020年,转岗到淘系前端,负责前端智能化相关开发。我其实是非常看好Serverless的,Serverless这种稳步推进的必然是前端新基建,未来玩2到5年问题不大。对我而言,前端智能化的诱惑更大,能够站到产研链路是思考问题,这才是我梦寐以求的机会。 我之前的想法是搞一次Node Party讲讲这些2021年前端趋势预测。在线直播,不知道是否有人感兴趣。先把我的这些思考写出来,希望能够对大家判断2021年前端趋势有所帮助。 http import 会大行其道 其实就是Deno创造的方式,Deno被评为2020最佳开源贡献也是实至名归的。 import cheerio from "https://dev.jspm.io/npm:cheerio/index.js"; 把cjs转esm都交给CDN类的服务来做更合适。事实上,pika.dev/skypack.dev/http://jspm.io 都已经做了这件事儿。 Node.js马上跟上,相关PR早已在路上,此项必火。 参见文章《2021再看Deno(关于CDN for JavaScript modules的思考)》 https://mp.weixin.qq.com/s/EzmNQ_oqxUuPQFfZYJWDzA 逻辑编排,更加面向开发者 已收到很多imove类似项目。解决逻辑可变和不直观的问题。 以函数为粒度,继而通过运用配置类的操作,将逻辑可视化,配置化。用法极为简单。参见 https://github.com/imgcook/imove 智能UI精细化 首先服务端搜索瓶颈已经到了天花板,端智能和端UI的探索,一定是增量上提升业务指标的。) 参见文章《智能UI:面向未来的UI开发技术》 参见文章《CBU智能UI落地最佳实践》 智能化 PRD 2 Code(P2C) 站在产研链路审视研发效率问题。站在D2C(设计稿转代码)之上,引入PD产品经理标注方式提升出码,进一步做到无人工,真正智能化。(招人做此项目) 下面2020年D2前端大会上ppt分享的一页,PD标注业务含义讲的还是比较清楚的。 参见文章《前端智能化实践— P2C 从需求文档生成代码 | D2 分享视频+文章》 不会 Python,前端也能搞机器学习 https://github.com/alibaba/pipcook ,基于pipline思路抽象的AI基础框架,让AI落地更简单。 参见文章《前端机器学习的利器,更快的 Pipcook 1.2》 一些我关注的开源项目 midway-hooks 最好用最潮的Serverless同构框架,没有之一。开源地址: https://github.com/midwayjs/hooks imove 逻辑编排工具,开发是有快感的。基于阿里开源的x6和formrender,简单易用。 已开源,https://github.com/imgcook/imove 前面讲过过,这里就不在赘述。 ykfe/ssr 基于Serverless的端渲染方案。支持多个Faas环境。同时支持csr和ssr无缝降级的方案。基于之前成熟的egg-react-ssr,去掉Eggjs,改成midway-faas,天然一套支持跨运营商。 已开源,开源地址 https://github.com/ykfe/ssr airpack 阿里内部的支持http import和cjs转esm的高效构建工具,据说已经在筹备开源工作了。看到一个性能压测,airpack大约是webpack5的20倍左右。 不确定的是 react server component 仍需要时间去了解。 Winter 和甄子聊的前端智能化 年度最佳关于前端智能化的视频。 【Web前端会客厅】和甄子老师一起聊淘宝前端智能化(上) https://www.bilibili.com/video/BV14k4y117Px 【Web前端会客厅】和甄子老师一起聊淘宝前端智能化(下) https://www.bilibili.com/video/BV1Mv411y7mU 2020年各大厂应该都在困惑,老项目为提升业务指标发愁,新项目在为研发提效发愁。很多既得利益者,吃着所剩不多的红利,一方面担心被替换,舍不得放弃,一方面又不敢做改变。我的观点是服务端算法(包括搜索推荐)今天已经触及了天花板,再提升一个点都会比之前更难。传统前端基建也面临一样的问题,比如node,搭建,ui框架,对于下一代升级想法,大概也是缺少想法和目标的。 创新是需要勇气的,眼界不够的人不能做到,能力不足的人不能做到。前端和AI结合的跨技术融合项目是存在非常大的机遇和挑战的。甄子以一人之力,扛起前端智能化大旗是非常不容易的。目前imgcook在设计稿转代码领域已经取得阶段性结果,但我们还有如下探索。 智能UI,目前已经能够看到增量的点。头条也做了类似的事儿。 P2C,围绕业务标注,实现产研提效,已验证。 Pipcook会进一步简化ai开发,只要有数据就能训练模型,真的是有手就行。 Design+,设计资产管理。 像airpack、http import、imove、midway-hooks、ykfe/ssr这些其实都会成为前端新基建。 总结一下,笔者认为前端智能化是2021年最有前途的方向。 很多人都以为前端智能化对ai和算法要求极高,其实这个看法是片面的。在前端智能化团队里有3种事儿可以做:1)业务,2)工程,3)算法。其中工程和业务是不需要算法的,对于新人也是会给缓冲期的,可以先做擅长的事儿,同时跟着团队向ai算法方面学习。 我经历过的阶段: 熟悉imgcook,这是d2c领域。覆盖了 2020 年双 11 会场 90%+ 的模块开发,出码可用率达到 79.26%,且需求吞吐量提升 1.5~2 倍,给前端研发带来实质性的提效。因为我是双十一PM,这个我是相当知道。 接手P2C,建立pd标注体系。这个过程是很困难的,但也是很有成长的。其实,更多的我是一个产品的角色。站在D2C的肩膀上,站在用户视角(PD),保证项目方向不歪。对于pd能做什么,该怎么做,如何快速落地业务,我是有很多思考和成长的。 搞定API,以前都是先选数据源然后确定字段,这是很麻烦的,PD是无法接受的,如果api有100个,每个api有10个字段,pd就疯了。我们的做法是先选字段,然后再确定具体接口,这种逆向思维,在这种项目里是非常适用的。 继续深化C端解决方案,站在淘系业务和技术都很成熟的前提下,提升业务数据,又能兼顾技术创新,大概不会有比这还胆大包天且令人激动的目标了。 这个团队是一个复合型团队。除了有卓风,妙净等老阿里前端大佬外,还有算法、设计、AI底层、UI等各个方面专家。 这是一个很潮、包容、技术范的前端智能化团队。欢迎感兴趣的同学一起交流前端智能化。 点击查看视频 大家好,我是来自阿里巴巴集团 ICBU 互动端技术团队的当轩,很荣幸能在第十五届 D2 大会上和大家做一次分享 ,我此次分享的主题是《跨端的另一种思路》。 我在开发端应用的时候,常常怀念 Web 的天然跨平台能力和开发效率。然而在开发 Web 应用时又会苦恼没有端应用那么好的性能和体验。所以就常常在想,有没有一种技术方案,像 Web 一样可以便捷的开发、在所有平台都能运行,同时又有很好的性能和体验。 当时最有名的一句宣传语我相信大家都有印象 -- Write Once, Run EveryWhere ,一次编写,到处运行。 然而理想很饱满,现实很骨感,不同的跨端方案层出不穷,但是都难以达到我们最终理想中的效果。 举例来说: Web 作为天然的跨端方案,在研发效率上非常不错,然后性能和体验的优化难度都非常高 React-Native 类的方案,性能上要比 Web 好了不少,然后多端一致性和研发效率则较低 Flutter 在 App 上的性能和一致性不错,但是在差异比较大的 Web 端性能就非常糟糕了,也无法满足 Web SEO 等诉求 之所以理想和现实存在这种差距,是因为跨端的方案本身在带来收益的同时也意味着在某些方面会增加一定的成本。 例如我们期望用同一套代码覆盖所有平台的同时,又希望研发的自由度和表达能力不要受到限制,然而这种方案只能使用不同平台表达力的子集。最典型的场景就是小程序的跨端方案,静态转译的小程序跨端方案往往通过限制开发者的表达能力来实现一套代码跨多端。 既然现实中的方案在带来收益的同时同样带来成本,我们就不能一味的追求 Write Once, Run EveryWhere我们的实际场景做出取舍。于是我们就提出另外一种成本更低的思路:逻辑跨端。 今天以我们 Alibaba.com 的交易场景为例,分为 Android/iOS/M 站/PC 网页几个端。 几端的 UI 交互并不完全一致,但具有相同的业务逻辑,同时 APP 端对于性能和体验上有更高的要求。我们在效率上最直观的问题在于,一个哪怕非常简单的业务需求的上线,都需要经过多端开发同学的资源协调和相互依赖,消耗在沟通上的成本非常高。 由于 Android/iOS 端对于性能体验的要求高,加上这两端的 UI 和交互基本一致,我们考虑用 Flutter 来作为主要的技术选型。然而在 Native 和 Web 之间,Flutter 并没有成熟的跨端方案,前面我们提到过 Flutter for Web 的性能基本是不可用状态。 通过 JavaScript 容器 + Yoga 做类似于 React-Native 的方案我们也考虑过,然而其带来的建设成本和抽象代价在这种场景下是否合适是存疑的,因为 PC 和 App 的交互完全不同,通过引入 Yoga 类的方案反而会让两端的开发都束手束脚。除此之外,我们也担心 JavaScript 容器的引入在端上带来更高的优化成本。 于是我们就提出了另外一种思路:有没有可能仅针对业务逻辑做跨端共享,这样我们不需要对容器侧进行太大的改造,也不用担心引入新的优化成本,同时也能做到跨端共享代码。从而让前端同学去单独 hold 业务侧的需求成为一个可能的方案。 那么对于这样一种方案我们会有几个问题: 采取什么语言 如何分离逻辑和 UI 差异逻辑怎么写 第一个问题是采取什么语言,其实 Dart 就是一个现成的选项,因为 Dart 从一开始就是为 Web 设计的语言,甚至在 Flutter 出现前曾经一度在 Chrome 中有默认 VM 实现。虽然后来放弃了在浏览器中的发展,但是 Dart => JavaScript 仍然是一个成熟的技术。 同时因为我们的前端同学其实对于 Dart 仍然不是那么的熟悉,另外 Dart 的类型系统在很多时候并不能满足动态类型的诉求,以至于到处都是 dynamic。例如说基础的联合类型:string | number 这样的类型都无法直接支持,所以我们也在探索从 TypeScript 转译到 Dart 的方案。 通过 TypeScript 提供的能力,我们可以直接把一份 TS 的代码从源码解析到 AST,而后通过遍历 AST 生成对应的 Dart 代码。同时其中通过 getTypeChecker.getTypeAtLocation 等 API 获取到 AST 对应的 TS 类型。然后通过把 TS 类型转换成对应的 Dart 类型。对于不支持的类型降级到 dynamic ,把原有的完整类型信息输出到对应的注释里。 第二个问题是如何有效的分离逻辑和 UI,其实我们都知道如果只是单纯的把纯函数作为一个独立模块给抽离出来并不困难。然而逻辑中必然不仅仅是单纯的输入得到输出的纯模块,还有很多涉及到组件生命周期、渲染、状态变化等副作用(side effect)。如果我们需要在 Flutter 和 Web 间复用逻辑,我们就需要定义一份类似的接口。 我们可以先看看 Flutter 和 Web(我们这里采用的是 React)究竟存在多大差异,这里是 Flutter 和 React 构建组件的一个简单对比。其实我们知道,在代码组织方式上,Flutter 和 React 是非常相似的,事实上他们背后的的状态更新 => 触发 Diff => 重新渲染的逻辑也基本一致。所以说最理想的情况下,我们能直接用同样的逻辑抽象方式共同来书写逻辑,这样可以避免在不同场景下的接口对接方式和心智负担。 那么,有什么合适的方案可以用于分离逻辑和 UI 呢。其实对于很多前端同学来说,可能都了解 React 16 推出的 React Hooks,我们可以在这里看到相比 React 15 的 Class API 的一个区别。 看上去好像除了代码量变小外似乎问题不大?但其实如果我们把这个组件拆成两个函数,就能明显看出差别了。 没错,React Hooks 最大的作用不在于单纯的少写代码,而是让我们可以以非常低的成本把逻辑从 UI 或者其他逻辑中抽离出来,并且进行再组合。也就是说其实 Hooks 就是这么一个现成的逻辑拆分方案,大家也广泛接受其理念和 API。那么,有没有可能让 Hooks 的逻辑在 Flutter 上也能使用呢? 前面我们提到,Flutter 构建组件的方式以及运行原理都和 React 十分的相似,那么我们其实只要理解了 React 中 Hooks 工作的原理,就能在 Flutter 中再实现一遍。Hooks 可以简单理解为 闭包 + 数组(实际上在 React 中是链表)。以 useState 为例,Hooks 和普通函数最大的差异在于其可以在多次 render 调用中保持状态,实际上就是通过在闭包中保留状态,同时通过每次重新 render 时重置计数,从而依赖执行顺序还原出具体的状态。 那么到了 Flutter 中,我们就可以实现一个 HooksWidget ,在触发渲染时重置计数,同时把当前组件存储到闭包中,从而让 Hooks 能够根据计数找到对应的状态,并且知道应该去触发那个组件的重渲染。 最后一点就是对于差异化逻辑的书写,Dart 从 x.x 版本就引入了 condtional import 的能力,让我们可以根据不同的环境(Flutter 和 Web 引入不同的包)。于是我们可以在不同的包中书写接口相同,但底层逻辑不同的类,从而实现差异化逻辑。 同时在 Web 端,我们可以通过 Dart 官方提供的 js 包,轻松的和浏览器中的 JavaScript 原有能力进行交互。于是我们可以通过这样的一层胶水层,让我们在 Flutter 端的逻辑走我们上面写的 Hooks 能力,而在 Web 端则直接调用 React 的 Hooks。 最后我们能实现的一个效果,就是用同一份逻辑代码来表达 Flutter 和 Web 端的业务逻辑,并且作为我们非常熟悉的 Hooks,引入到 UI 上并且直接绑定。 同时借助 SourceMap,我们在 Devtools 里也能进行调试。 由于我们在渲染上并不强制差异很大的 Web 和 Flutter 保持统一,所以在性能上可以针对不同平台的特性做出优化,比 Flutter for Web 的性能表现更好。 点击查看视频 这个 DEMO 仅代表这个场景下的一个性能对比,并不代表所有场景下的方案性能都如上所示,事实上针对不同的方案我们也可以再采取不同的优化措施去改进。之所以放这个 DEMO,主要是为了解释这种方案在不经过太大投入的情况下,也能达到理想的性能。 最后我们再做一个大概的总结: Write Once 是一个理想目标,Write Logic Once 在部分场景下能更好的解决我们的问题。 介绍的方案仅适合重逻辑的场景,对于重 UI 表现场景不适用。我们需要根据场景做出对应的选择取舍。 对于写一份逻辑,无论是 Dart 还是 TS,仍然存在一定的抽象泄露问题,对于一些复杂问题的排查仍依赖开发者的经验 点击查看视频 大家好,我是辰啸,来自阿里icbu互动与端技术团队,今天给大家分享的主题是前端故障演练的探索与实践。 前端可用性的困局在于,一个看起来很体面的页面,有吸引力的视觉,友好的交互,但你不知道背后到底是什么情况。让我想起有一次走进某个机房,机柜上码着各种高端机器,一片祥和。但是走到背后,线头交错,你永远也不知道拔了这一根影响到的是哪几台机器,一旦出现问题,某些情况下连恢复都伴随着风险。 而作为发生在客户端上的问题,先天上存在着感知相对弱一些的缺陷。别人家的事情肯定是不如自己家发生的事情容易观察到的。 有这样明显的问题,但与此相悖的是,前端安全生产水位远远满足不了当前的诉求,发展上颇显迟钝。这背后反应的问题主要有3个: 前端从业者对可用性的心智意识还是没能跟上前端领域自身的发展,对这块的重视度不够。 相关的生态伙伴也没有能广泛地参与进来。大部分企业或开源社区的的质量保障基础设施的建设热点都与前端关联度不高。 背后最核心的因素是没有一种常态化的度量能力,让大家能看清当前的水位,并形成一种推动力,促使大家去完善可用性的能力建设。 这也是我们尝试探索前端故障演练的核心思路来源。 整体而言这还是一个比较新的领域,今天更多地是分享一些我们在探索过程中的思考和感悟,会介绍我们的整体方法论混沌工程,过程中遇到的核心技术挑战,并结合一个演练实战让大家更有体感。其中有一部分思考路径上的产出,也可以在别的领域得到广泛使用,其意义超出了前端故障演练本身,希望能给到大家一些启发。 什么是混沌工程?Netflix在2012年发布了Chaos Monkey,向业界介绍了这个思想。引述一位业界先驱的话,混沌工程是一种深思熟虑的,经过计划来揭露系统弱点的试验。简单来说,就是将异常扰动注入已经呈现稳态的系统中,观测系统因此而产生的变化并作出对策,使今后系统面对同类异常扰动的变化delta在空间和时间维度上尽可能的小。 混沌工程不是一次性的试验,通过验证、改进和再试验,形成一种往复性的提升机制。它在设计上强调了5大基本要素,在后面的介绍中会为大家再展开这一部分的讨论。 故障演练就是混沌工程的实现方式之一。 以往阿里内部的实践中,已经有比较成熟的故障演练体系了。但当时的故障演练关注的主要是诸如线程池满,数据库连接慢,断网断电,磁盘满坏慢等问题。概括来看,就是主要验证企业的在自己的物理设施范围之内,是否可以应对突发情况,对外提供持续可用的互联网服务能力。我们把它概括为在岸持续可用。那么前端故障演练有哪些不同? 如果我们把BFF、Serverless等领域归结为这一类的后端演练,把话题聚焦到纯前端,我们会发现,实际前端的故障演练关注的代码、资源等数据,都是在离开企业的物理设施,来到客户端上以后才开始运作。 因此前端故障演练的本质就转变为与此相对的概念即离岸持续可用。我们需要关注的是代码的生产过程是否能防御缺陷的混入,也关注故障发生时系统的发现能力和组织的响应能力。 举几个例子,我们通过演练可以去验证CodeReview是否严肃,自动化用例的漏检和误检率处于什么水平,兼容性、国际化、性能问题的预防和发现能力表现如何,或者去评估前端的监控覆盖率、告警触达率以及人员的应急响应效率等等。 在这样的思考之下,我们开始着手准备打造一个前端故障演练体系。这边也给大家分享一下我们当时遇到的一些核心挑战 演练的切面视角 我们可以对刚才大家看到的前端需要关注的生产和消费过程再做细分,我这里简单划为4部分,也就是研发、工程、发现和响应4个需要验证的切面。因为前端的生产和消费链路整体是线性的,在前置切面引入的缺陷,会流经后续的切面。举例来说,研发环节不慎写的故障代码,会走过构建发布,在客户端上执行,会验证到系统的发现能力和组织的响应能力。也就是故障的注入具有贯通性。 在设计故障注入能力时需要考虑到这种贯通性,刚才的举的例子就可以抽象为源码变异注入这种能力。当然,如果我们对某种注入能力做特殊的设计,也能做到让它的影响面限制在某个固定切面。比如CR变异注入,我们通过使变异的diff只在运行时零时产生而不实际产生落库的代码,做到了避免污染后续的切面。在这样的整体设计之下,我们会具备一个由一批贯通性的注入能力以及一批基础注入能力组成的立体注入体系。 一个注入能力影响的切面越多,验证的链路越完整,但实施成本越高。业务应该根据自己需要验证的环节选择实施成本最低的注入方式。因为篇幅所限,无法一一介绍每种注入能力的实现,我这里就举一个例子。 一天,小陈的老板说,又要大促了,需求很多,上得又仓促,有点问题在所难免,但还是希望有比较好的处理表现。小陈觉得,当下团队业务的主要问题是: 监控接入情况不好 监控项覆盖不全 告警设置有问题 这种情况下,小陈考虑针对发现和响应两个切面做演练能力设计,这对应的就是上图贯通性的静态资源劫持能力。 对照混沌工程的5大要素,首先应该具备一个稳态假设。 这里的稳态也就是各类能代表当前业务能力的关键指标的集合,并且他们在一个固定的业务周期里处于相对稳定的状态。现在大家或多或少也有自己的一些监控体系,系统监控关注物理设施的运行状况,业务监控关注业务指标的变化,而端侧监控通常在端上以主动上报的方式记录客户端上的关注点,也是前端可用性领域核心关注的一种监控类型。找到了稳态就可以制定一个假设,以小陈团队的某个xx管家业务为例,如果把主js搞挂,那么同比来看,xx管家首页js error数/率会飙升,并且首页主功能模块曝光率会骤跌。 于是一个静态资源劫持的注入方式雏形就诞生了。蓝军小陈把有问题的主js发到cdn上,页面引用了这个js,引起故障,错误日志上报至监控平台触发告警,由红军来跟进处理。 但这个雏形存在着几个致命的问题: 如何使影响范围可控? 如果做个演练动不动就要搞个故障出来,很可能得不偿失。这个话题在混沌工程中可以归纳为最小化爆炸半径。我的个人看法是,前端目前安全生产水位暂时无法支持任何形式的生产环境有损演练,其收益风险比过低。 有一部分同学表示,那如果仿照灰度策略,控制比例,让极小部分的用户受影响,是不是解决这问题了?但是这样会遇到一个新的问题。 如何达到触发监控告警的量级? 控制比例到极低,固然可以使影响范围也控制到极低,但多数以绝对值为触发方式的监控项将同时失去作用,也就起不到演练的作用了。 那如果换个思路。独立出一套环境来演练,我们自己去模仿用户访问网站来触发故障,再放大一下倍数呢? 问题是,多数业务对用户的角色、权限有明确划分,有些故障点的触发具有一定业务逻辑,比如需要通过一系列操作才能执行到相应的功能。亦即: 如何仿真用户的线上访问? 如何触发具有一定业务逻辑的故障点? 让我们看一下这些问题如何解决。 前端安全环境 首先,为了保障业务的安全可控,我们确实需要一套与线上隔离的环境。资源故障不注入到线上的cdn,参与演练的客户端的资源请求都被劫持到drill cdn;为了使数据交互不会产生脏数据,数据请求都被劫持到drill server数据服务,当然这里数据服务是否有更轻量的实现方式后文会提到,这里我们先记录一下。这样一来,演练整体与线上能形成物理隔离,达到对业务的无损演练。整个参与演练的客户端,drill cdn以及数据服务三部分我们可以称之为三位一体的前端安全环境。 在实现上,以PC场景为例,我们深圳团队落地了名为f2etest的webdriver云调度体系,依赖云端的虚拟机,及每机并发的复数个浏览器实例,实现了客户端数量上的弹性物理放大。假设有20台机器,每台起10个浏览器,我们可以并发的客户端数就达到了200。由这些浏览器发起对待演练页面的访问,相应的资源请求则通过ip代理方式,劫持到演练用cdn源站上。这个源站上实现了流量转发、资源版本控制、网络状态模拟、错误资源存储等能力,足以模仿绝大部分资源请求响应的可能遇到的情况。这套f2etest也可以承载功能验证,UI自动化等任务,已经上云,欢迎大家试用。 右下角Hub Plan是为了解决我们上文中提及的用户和业务逻辑仿真以及数据服务的轻量实现而存在的,在下下页PPT中为大家介绍。 运行时,因缺陷注入导致的页面故障,在有监控部署过的情况下,会产生日志上报。通过Whistle修改上报请求中与监控平台达成的协议部分,如上报次数、采样率、通道标志位等,使日志得以被监控平台采信并达到触发告警的量级。 在下面这张PPT中也可以得到展示。 蓝军的缺陷不再直接注入线上,而是注入前端安全环境,并通过内置的弹性物理放大,触发故障上报日志。为了保证大流量业务的使用,我们设计了双重的放大机制,在安全环境外通过与平台的上报协议锚定,包括反降噪协议和逻辑放大协议,保证量级满足。逻辑放大倍数N应取安全环境中参与上报的客户端数与页面正常线上PV比值的倒数。 通过前端安全环境我们做好了最小化爆炸半径,以及触发监控量级的准备。接下去要解决的就是用户仿真、业务逻辑和数据服务的问题。 这里思考这样一件事,过去我们在尝试ui自动化领域的实践中,认为保持业务的功能性逻辑f不变时,若用户数据x和用户行为y也不变,则应得到不变的页面反馈R,包括显示、交互等等。我们反面来看这个思考,如果保持用户数据x和用户行为y不变,R发生了变化,则都可以归因为f发生了变化。所以我们可以把用户数据、行为和反馈都存下来,通过回放的方式去触发相应的逻辑,一旦与原先的反馈产生不同或者说故障,都可以说是因为现在的页面逻辑有缺陷注入导致。这套机制能解决了我们上述提及的3个问题。 我如果去考虑传统UI自动化方案,也就是书写用例的方式来做。会有几个老大难问题。 编写成本:编写用例时间长 时效性:业务逻辑更新后,通常需要一个比较长的周期才能更新用例 覆盖率:依赖人工分析,部分逻辑分支和边界条件非常难以覆盖 最后我们寻找到的钥匙是流量即用例,也就是上文提及的Hub Plan 在我们实现的这套机制中,将经授权许可的用户行为、资源以及原生api等数据通过serviceworker统一上报。行为经过数据聚合和清洗后得到经过精简的、但能覆盖页面绝大部分业务逻辑的核心用例,并存储起来。资源等其他数据也类似处理。当演练调度执行器要求回放时,将用户行为用例交给f2etest调度webdriver进行执行,针对执行过程中发起的请求,由service worker和whistle拦截后以之前存储的资源作为返回。整体形成了一个沙盒。 这是用户行为用例和回放沙盒的截图示意。这些都由统一的演练调度设施管理。实际演练运行过程中演练发起和参与者都不需要关注这些,这套设施会无感执行,此处只做演示。 之前我们提及到一个轻量的数据服务实现方式,通过Hub这一点也得到了解决。我们不需要去重新建设一个隔离的后端服务环境,那样做需要梳理的上下游依赖关系极其恐怖。取而代之的,我们将用户请求到的html、其他响应和原生API返回结果等数据也作为资源存储下来。当回放开始,浏览器对html的请求通过whistle拦截,返回的页面上包含了当时采集到的其他数据,这些数据被写到全局变量中;这样做的好处是显著提高了回放性能,避免了频繁的数据交互。此外页面上还被注入了一个请求匹配SDK,当前域的service worker,和其他下发的自定义拦截策略。当页面需要请求时service worker会根据拦截策略进行拦截,通过SDK寻找全局变量中相匹配的结果并返回结果。 最后整体上,一个静态资源劫持的注入能力流程就如图所示。 蓝军发起演练后,通过演练平台下发策略,在安全环境中调度起大量客户端实例,由这些客户端发起对待演练页面的访问。指定的静态资源请求会被劫持到高度定制的drill cdn模拟源站上,这个模拟源站可以返回任意指定的响应状态,包括但不限于资源加载失败、超时,甚至返回内含指定错误代码的JS。这些响应状态返回到客户端后,造成相应的故障。若监控部署准确,则会有告警通知到受演练的红军,进一步验证红军响应动作。若监控部署不当甚至未部署监控,则本次演练结果相当于红军直接失败。 我们通过监控体系,安全环境,流量回放,支持到了稳态假设,最小化爆炸半径,生产仿真和多样化事件这4个混沌工程的核心要点,并且策略之间有重叠配合。另一个自动化持续我们也在逐步探索中,当下呢先抛出一些我们的思考。 我们尝试通过总结过往故障、常见故障、其他业务故障甚至过往不达标的演练,推导出一个具有高质量的剧本池,其中的剧本各自运用了不同类型的注入方式,来验证各自切面的能力。通过循环往复的演练,我们能得到一块业务的总体得分,通常预防、发现、响应这几部分形成一张雷达图,便于我们针对薄弱环节挑选剧本反复演练。那么怎么做到自动化呢?我们预计会尝试在money test的领域探索,通过对稳态系统的破坏性注入尝试,发掘引起稳态变化剧烈的几次尝试,对应系统的薄弱环节,自动生成具体的演练方案,形成剧本,扩展剧本池,很好地解决了剧本需要人为补充的问题。 了解了演练部分设计之后,让我们用一个实际的例子来描述下如何进行一次成功的演练。 一次演练必须有定义明确的演练计划,小陈挑选了团队中一个名为某管家首页的业务,意图验证监控覆盖率、告警有效性及人员响应效率 。注入方式就是刚才介绍的静态资源劫持,且对故障注入后的现象做了两个核心的稳态假设: 首页JS Error数/率显著上升 首页主功能曝光PV显著降低 在方案配置过程中,演练平台按照小陈指定的演练目标,已将静态资源劫持作为推荐注入方式前排展示。在具体 参数配置上,小陈决定将一段包含“未声明的变量调用”的错误代码注入到XX管家首页的主js,使主js执行抛出未捕获异常,以此达成使XX管家首页主功能模块丢失导致空白的演练预期。 当注入正式开始后,很快相关监控就有了错误日志数的急剧飙升。11:30 告警项达到触发阈值,监控平台推出告警邮件。 在这次演练中,红军小张较快地注意到了响应的告警邮件,并随即依照消防群中的消息提示,加入演练故障处理群进行故障跟进。11:39 小张定位到index.js中有一个名为drill的未声明变量被调用,导致抛出Uncaught ReferenceError: drill is not defined。蓝军引导小张上传响应截图证明至演练平台后,本次演练结束,注入主动退出,并开始安排复盘。 复盘过程重点围绕Checklist中的各项问题展开,并评估得到一个最终的红军防御得分。本次演练中,小张最后的得分是发现70分,响应85分。 特别值得一提的是,在发现能力这一项中,小张第一时间收到了监控平台的告警邮件,理应得到一个高分。但实际复盘过程中,XX管家关于JS Error数/率的告警项配置阈值过低,长期处于过灵敏的状态,告警邮件的推送相当频繁,已经造成了明显的疲劳效应。小张之所以第一时间注意到告警邮件,是因为当天他正在查看并尝试调整相关的配置,存在一定的运气成分。 在响应能力这一项中,小张在响应故障的流程上仍有一定的不熟悉,也酌情扣了一些分数。 要展望未来,需要先看前端故障演练带来的价值。 上文提过,业务域通过自我系统和组织的演练,可以充分验证业务域安全生产能力。但在更大的组织视角来看,这种验证能力往验收的方向发生了转化。一家企业可以对旗下的各个业务的业务的安全生产水位做准确的评估,并以明确的指标来验收。 在安全生产能力的视角来看,演练体系和保障策略矛与盾的关系。随着保障策略的提升,演练体系需要进一步补强注入能力或应对新的技术场景,追加新的注入能力;同时,随着演练体系的注入强度的提升,保障策略也需要更多的积累,才能经受住演练的考验。最终在螺旋式上升的过程中,业务能从过往重大故障的抵御入手,一步步进化到未知中小故障的抵御这个领域。 此外,在组织视角来看,前端故障演将带来了安全生产能力的常态化度量,并进一步补充了前端安全生产领域的抓手。这将撬动开发者、业务安全生产负责人及相应的保障团队的积极性,使他们在前端安全生产这个命题下创造更多的产出。我们可以预见,其中有一部分人的角色可能发生一定的变化,甚至产生“混沌工程师”这样的角色,帮助业务寻找所有可能的薄弱环节并制定混沌实验方案。当然混沌工程是可能并不局限于前端,更可能的情况下,他会是一种具备全栈素养、拥有全局视野,兼具深度业务理解的角色。这也是我们期待发生的变化。 第十五届 D2 前端技术论坛 PPT 集合已放出,马上获取 关注「Alibaba F2E」 回复 「PPT」一键获取大会完整PPT

点击查看视频 大家好,我是来自阿里巴巴淘系技术部的墨辉。今天分享主题是《如何建设灰度跨端监控》。 监控,安全生产的第一战线,线上问题的发现能力以及如何快速定位问题是监控的核心能力。前端跨端方案不断在演进,覆盖了web、weex、小程序等多种跨端方案场景。今天的主题从背景介绍、技术方案、线上案例、总结 4个维度来介绍灰度跨端监控。 首先介绍下跨端的背景,打开一个H5或者pc的页面,从传统前端监控视角去看,我们一般只会关注页面运行过程的异常监控,比如 JSError、接口异常、性能等这些指标。 今天,我们业务运行在很多不同的跨端的方案,比如 weex、小程序、rn、flutter等。从跨端监控视角看,需要做到全链路的监控。比如容器启动异常、页面加载白屏、页面执行过程导致crash等问题的监控。 回到安全生产的背景,我们统计了淘系前端财年故障,我们发现线上问题 80% 是变更引起的以及故障平均修复时长超过了 300 分钟,我们来分析下具体原因: 线上变更引起故障,大部分是没有被监控发现,根据上图分析下监控没有被发现的原因。从趋势图看出,在10点左右有个发布节点,日志有个小幅度的增长,增长过程没有触发报警,原因主要包含两个: 大盘日志的增长并不明显 缺少细分的维度来区分日志增长的来源 上面我们提到了,平均修复时间超过了300分钟,一个完整的流程流程包含两个阶段 开发阶段,从需求评审、需求开发以及测试验证 发布阶段,开发完成之后,发布过程会有个渐渐放量的过程,内部灰度 -> 外部灰度,最后完整上线 如果一个问题完整上线才发现,会带来问题修复周期长和影响范围广的问题。要解决这些问题,需要在灰度发布过程来提前发现问题。 灰度监控是要解决发布过程的监控,核心要解决三个问题: 不同的跨端容器(weex、小程序等)怎么建设灰度监控 灰度报警和普通报警的差异是什么 灰度发布过程的监控,如何帮助业务更好定位问题 下面介绍下整体技术方案。 技术方案分为四个部分: 灰度发布:发布分为两种,一种是类似小程序这种,打包成zip包发布上线;一种是常规页面发布,静态资源发布到CDN 日志采集:页面运行过程需要采集监控的指标,比如js执行报错、接口异常等指标上报 数据处理:数据上报完成之后,需要对数据清洗和字段处理 灰度监控:基于处理后的数据结果,完成灰度监控的建设 上面提到,两种发布方式,首先看下静态资源发布,比如weex或者web这种场景,一般在cdn层做灰度控制。如果命中,访问的是灰度版本。未命中,访问的是线上版本。 ZIP打包一般分为两种场景,具体如下: 小程序场景,打包成ZIP包发布上线 WEB离线场景,做资源加载的优化,会将静态资源打包成离线ZIP包做发布上线 对于ZIP还是非ZIP发布场景,当前版本和线上版本需要从三个字段维度来区分: 版本号,用来确认当前日志是在哪个版本发生的 是否命中灰度,用来区分当前版本是不是灰度中的版本 当前环境,用来区分日志的来源环境 端外采集,一般是web场景,受限于浏览器,需要通过全局变量的方式来获取。可以在脚手架初始化过程注入到模板并服务端渲染对变量赋值,通过采集SDK读取变量获取灰度标识信息,具体集成方式如下: <meta name="page-tag" content="env=spe,grey=true,release=0.0.1" /> 容器采集,通过扩展response header信息来获取。拉取资源的时候,可以直接读取资源的response信息来获取灰度标识信息,具体集成方式如下: grey: 'true' env: 'spe' release: '0.0.1' date: 'Fri, 11 Dec 2020 13:12:04 GMT' content-type: 'text/html; charset=utf-8' ..... 数据处理过程,主要包含对脏日志清洗、数据字段规范、数据字段解析、数据分类存储等,具体如下: 获取原始日志,不同的跨端容器日志统一上报到TT平台。TT平台是流式数据处理平台,通过在TT平台订阅消息,拿到上报的原始日志 实时日志处理,基于Blink台完成,Blink是流式实时计算平台,主要是做日志清洗以及把日志转成规范格式日志 数据存储,将清洗后的日志存储到SLS,基于SLS日志存储服务,可以对日志进行实时查询和分析 数据应用,基于node层,做实时日志查询、轮询报警等应用能力 安全生产背景分析发现小幅度日志增长,缺少细分的维度来区分日志增长的来源。现在日志包含了版本号、环境、是否命中灰度维度信息,通过这些维度区分出新增错误日志和日志的增长比例,来打造灰度报警和灰度实时监控能力。 灰度报警是在node层启动一个进程做轮询任务,拉取页面发布列表数据,对比页面的线上版本日志和灰度版本日志。基于新增日志和日志的增长比例的报警策略来触发报警。 灰度实时监控目标是帮助业务更快和直观的发现问题,需要将核心数据更直观的透出在数据图表上,核心指标数据包含: 灰度比例,灰度命中占整体流量的比例。通过线上的采集pv和灰度版本的采集pv来计算出灰度比例 详细日志状态,比如JSError指标,通过灰度版本的日志和线上的日志做相似度算法比较,可以对日志聚合分类,计算出新增的错误类型和错误增长比例 实时监控效果如上图所示,通过两部分来看这个图表: 日志走势,绿色的线可以区分出灰度命中占整体流量的比例,红色和蓝色的线可以区分灰度版本和线上版本日志总量的比例 日志分布,对日志做了两种状态标识,新增日志状态和日志增长的比例。通过日志的变化趋势状态,可以直观的判断灰度版本是否符合预期 介绍一个具体案例,一次新需求迭代,流量灰度5%左右的时候,发现一个报错日志增长了接近5倍,通过及时回滚避免的线上一次故障。 做下技术方案总结,灰度监控分为四个过程: 灰度发布,对于WEB、小程序、WEEX等灰度发布能力的覆盖 指标采集,浏览器采集通过读取模板变量的方式,容器采集通过读取response header信息获取灰度标识 监控指标,覆盖全链路监控指标,日志上报过程中携带灰度版本信息并转成规范日志格式 灰度应用,通过灰度发布的信息维度做日志分析,来打造灰度报警和灰度实时监控能力 点击查看视频 我是来自阿里巴巴文娱事业群的芃苏,目前在大麦做前端开发。很高兴能够在多样化专场中,给大家带来《10万级大型场馆背后的绘选座技术》这个主题。题目名字比较长,大家也可能会感觉比较陌生。没有关系,接下来我会从以下四个部分展开介绍: 前置的行业信息、业务链路的背景信息。 针对“10万”,我会对绘座、选座两个关节环节拆开来讲,从问题的分析,到性能、数据上一些思考和解法。 未来的一些展望,关于WebGL、WebAssembly的一些看法。 其实我接触这技术方向,也是最近两年的事情。2018年初加入阿里后,先后在影业、大麦做B类的产品,一直面向商家、企业,为他们提供日常经营的能力和相关服务。这其中会有很多围绕票务展开的技术能力,绘选座就是其中一个。当然除了这个技术方向,我也像很多同学一样,在持续关注中后台的工程能力和效能提升上的沉淀。 说到票务行业,喜欢出行旅游的小伙伴,当你坐上世界最大的民航飞机A380,大概座位有861 个;喜欢看电影的小伙伴,如果你走到一个 30排 x 30列的 IMAX大厅,座位数也就 900 个。那么,如果….. 如果当我们要去看演唱会,或者是看大型的体育赛事、开闭幕式,需要走到一个巨大的场馆中。拿大家熟知的鸟巢体育馆为例,固定座位有8万多个,如果是安排临时座位可以达到11万。这样的场景,就存在于演出行业中。 全国大概有5000多个面向剧院演出、演唱会和体育赛事的场馆,在2019年,有近5000万的人次走进这些大大小小的场馆,去体验现场娱乐的魅力。这也产生了一个超过200亿 GMV的巨大市场。在这个行业中,大麦服务过2019年的男子篮球世界杯、武汉世界军人运动会,也将为2022年的亚运会提供票务服务,同时大家熟悉的开心麻花和摩登天空,也是我们服务的对象。 从商家后台到消费端,每一个项目需要先对座位图进行绘制,基于座位还要匹配上对应的票档、销售属性,最终在线下可以由售票员进行售出,或是大家熟悉的,通过像大麦这样的票务平台进行在线的选座下单。那么对这10万级超大规模座位的绘选,如何去呈现,又有哪些问题的思考和解法呢? 10万绘座 编辑器能力,提效是核心。 绘制,首先它是一个编辑器的能力,既然要编辑,大家都希望能够快速、准确,提效也就成了使用场景中的核心诉求。我找了三个比较典型的问题,当做绘座编辑器问题的切口: 编辑器开发是否用我们开发其他业务页面的思路也可以呢?比如,我们是否同样需要考虑组件化?当然,这是基本的抽象,比较容易想到,但在编辑器这个场景中做组件会有些不同。另外,耦合什么、解耦什么,业务数据和视图之间的关系如何? 我们目前还是集中的在使用Canvas,因为核心是平面2D的场景。有意思的事情是,我们遇到过Canvas擦除擦不干净的情况,也有因为重绘导致卡顿的问题。 像鸟巢这种椭圆形的场馆,肯定会有带弧度的区域,我们在这样的看台区域里怎么绘座呢? 接下来我们依次来看看技术细节,先看一下功能场景,有一个直观的体感。 这个界面是商家后台的操作界面,正要在一个svg底图上去绘制座位。左下角的弹窗是添加座位,其中会有座位属性、座位号、排号、以及座位的递增规律等设置。在我们针对 10万场馆绘座这个场景下,有一点很重要:一个场馆有多个看台(也就是大家看到的区块),每一次绘制操作时,我们都是针对某单个焦点看台,其它的区域则是 Canvas快照(如右下角所示,是多个看台、密集座位渲染的一个状态呈现)。 “10万”的问题,在绘座这个场景就有了两个解法上的拆解: 业务中,单看台座位通常不会超过3500个,我们不用时刻面对“10万”去解题; 即便需要视图中展示,也可以提供Canvas快照。 如上所述,整个过程包含了svg底图、canvas快照等图形信息。那么我就来从视图组件化的层面聊一聊,它设计上和日常普通后台页面实现上的差异。 大家现在看到的这个四层结构,并非是绘选座能力最初的样子。当时的业务实现可能是扁平化的,强耦合的。这个结果的产生,代码的历史债有一个从低到高、再通过结构化设计降低的过程。客观的合理性需要从优化改进中得出。同时,我们需要把细节处理上的成熟经验延续下来。 第一层,关于原子和组件。大家能看到这个编辑器有多种能力:比如基本的座位显示,操作上的圈选、排选、块选、套索,还有后面将介绍到的变形工具,这些要被抽象。 第二层,图层,我们的页面实现,不再扁平,不同的前端属性内容,我们在不同的分层去实现,比如HTML layer、Canvas Layer,svg Layer,GridLayer等,分层后可以堆叠多层,也意味着当业务属性有差异、不需要的时候,也可以仅注入所需要的图层,不会有冗余。 前面讲到的图层,都会在容器中去做注册,也是我们对整个内容的初始化过程,其中还包括插件的注入、手势和滚动事件队列的注册。 最终,呈现到使用者眼前的业务视图,即包含了上述的所有能力。 说完了基本的分层设计,我们来看下第二个问题,也就是这么多座位在绘制过程中,我们怎么做批量的操作? 最初,每个座位在批量移动是,都是独立的去从Canvas画布上抹除,然后在新的画布位置上重绘,图例中 6x6 的36个座位,也就意味着36个独立单位要完成重绘,如果是面对(我前面讲到的)单个看台 3500 个座位,那就有点恐怖了,fps超不过 20,会有比较明显的顿挫感。电影要做到24fps,才能欺骗肉眼、消除视觉延迟,游戏中可能需要做到30-40fps以上才可以、因为需要更高的即时反馈,比如射击游戏或者是多人在线RPG游戏。但是游戏中会有动态模糊等3D渲染技术做视觉辅助,我们目前面对的2D视图会直观的体现到是否线性顺滑上,60fps更是要求输入相应具备40-50ms的响应效率。所以有了“临时块”复制的概念,从代码语义化的命名上我们称之为 “temp-canvas-layer”,其实每一次批量的拖动,就变成1对1的canvas重绘,不再是从n到n。 除了批量复制,还有就是我们提到的变形问题,每个看台的区域大小不同,边界也可能不规则,这需要我们编辑器有针对批量座位的变形能力。“区块”的操作,在这个场景下又出现了两个新的问题: 因为要考虑恢复还原的问题,记录的块级信息,我们如果想从0度变成30度,再变成60度,需要先从30度恢复成0度,再从0度变化为60度,这个过程细节是有些令人尴尬的。 约束还体现在了其它方面,所有的信息都是单个完整块级的,当面对多个块、或者是块的局部,都会被限制。 所以基于此,新方案中,开始计算每个座位自己的斜率比,让每个座位根据自己斜率比生成的轨道去进行移动变形。其中关于弧度变形里用到了二阶贝塞尔曲线,算是应用数学和图形学中的基本操作。 我们能看到多种变形能力已经基本具备,间距、弧度、倾斜这些都不成问题了,那还能做的更好么?当然可以,我们还可以一键实现变形。 基本已经可以满足业务的日常需求了,再往前走,可能就需要整个座位的录入动作全部智能化,具备座位图识别的能力,而操作人员仅需要做微调编辑。这个是我们未来努力的一个方向。 10万选座 对数据的思考,性能瓶颈的突破。 选座的问题和绘座截然不同。其中涉及的10万级数据场景,在这里我们需要正面面对。 首先,座位被绘制完,要售卖交易,一定具备多种属性,大家平时从演出的票纸信息上一定可以看到许多。这个对渲染性能的诉求是巨大的,但10万的数据信息一次要求我们请求完、渲染加载完,理想化的还要秒开,显然这个问题还需要再被拆解,不能一根筋的硬刚。这里面有非常多的突破,是可以和服务端同学一起来思考完成的。 我们对数据本身要做一个区分,即静态的座位信息,和动态的属性标签信息。有一些信息我们可以本地缓存,有一些数据可以实时更新。 第二点,我们前面提到的所有信息,包括座位地图、座位绘制,这些都是要加密保证安全性的,他们都属于商家的资产安全范畴。大麦对座位底图也有专门的保护技术,这里不展开,还是回到数据问题上。 大家平时每天接触的 JSON 数据格式,其实好处非常多,比如语义可读性强,或者是在Node这样的Web Server中也可以无阻传递。但这两点都不是我们需要的,实话说,可读性强也和安全这个诉求背道相驰。诸多问题让我们考虑到了一种新的结构化数据:来自Google的Protocol Buffer。对比 JSON ,大幅提升了加密的效率,也对于 JSON 处理不好的 int floats 数据类型有了更好的支持。因为业务属性复杂,对服务间的数据传递,跨不同语言框架用工具生成时,基于proto结构也更加方便。 整个数据拆分组合方式都比较清晰了,我们也做了非常多的数据比对,对于一个原始 2.5MB的座位数据进行Proto编码后,再进行无损压缩,体积比之前缩小了27%,在业务数据校验时,解压加上反序列化为对象的时间缩小了47%。 前面说了很多前端和服务端之间的数据连接。当数据来当前端时,我们每一个操作事件其实都不是直接作用在视图上的,中间会有一层DataProxy的设计,这种设计在很多的技术方向上都有应用。基本的目的是为了把我们业务属性的数据和分层结构、组件插件的能力解耦掉,因为底层原子能力都是原生JS和Canvas,有了这一层,我们其实也不再关心业务上的差异、语言框架React还是Vue的问题,对未来的能力迁移和复用,会更加有益。右图的代码示例里,展示了如何添加、删除、还原一个座位数据,以及如何更新一个或多个座位的缓存数据。 接下来,我们看下渲染性能。在绘座环节讲到了单看台的聚焦,其实选座有借鉴类似的思路,但不像绘图、我们可以增加一些限制,比如你画完一个区域、才能操作另一个区域。选座的时候,用户应该是随心所欲的。 基本的选座链路上,首屏加载完、聚焦单看台,这时我们会考虑分区懒加载的问题,因为时刻要准备好用户对于焦点看台周边看台的操作,一旦用户大幅度的跨越看台做了操作,回到之前操作过的分区,还会有重绘的动作。整体的耗时,使用Chrome Performance性能分析工具,可以分析看出整个的操作链路大概需要近10秒的时间。 其实解法的话,我简单说下其中三个重要的突破口: 是我们底层的原子组件和插件本身,在实例化过程中有很大的提升空间,做了对应的优化。 Service Worker,这个技术大家都知道,但是可能场景受限、使用并不普遍。当同步加载一个焦点看台周边的多个看台时,因为线程池能力的丰富,可以同步对数据的请求加载、座位初始化带来大幅的性能提升。 加载后的东西我们全部 Cache住,性能瓶颈的突破,也让我们对已加载过的区域不再需要重绘。 整个总链路的耗时缩短了 70%,基本可以做到 3-4s完成从首屏到单看台、到周边区域、再回到原看台的所有操作,每一步操作做到秒级响应。 在首次加载的环节,这么多座位的渲染,Canvas对CPU的压力实只是一方面,即便Chrome会自动开启少量的GPU加速,但瓶颈有一方面还来自于canvas画布尺寸的上线。所以我们对整个画布做了Grid块级的切分,这为我们多个体验性能提升动作带来了突破性的变化。其实依然是一种拆分的策略。 下图中,大家可以看到在首次分区加载B看台2000个座位时,密密麻麻的效果,我们现在来看一下分区加载的技术细节。 实际上10万级大型场馆,大多数情况下视窗里都不止有一个看台,每个看台千百个座位,那么我们在懒加载时,会多计算1.2倍的视窗范围,也正是这样的余量的预处理,让体验上面带来了大幅的提升。 关于视窗,这里还有一个比较有意思的,就是鹰眼图。 鹰眼图就是选座页面右上角的“缩略图”,需要将黄色可视范围热区里的所有看台边界进行计算,就有了上面这么多绿色的框线。计算之后,我们需要等比的缩放至鹰眼图中,用来辅助用户判断自己当前所在的场馆位置。代码细节里面展示了滚动时,我们是如何转换坐标点位置,对宽高重新进行位置定位、并重绘的。 未来的展望 智能、VR、WebGL & 更多可能性 目前很多的工作是围绕基础能力沉淀建设展开的,希望能够赋能影演现场娱乐行业,去打造一个世界级的绘选座技术。 从开发者能力来讲,目前虽然并非开源项目,但依然从基础的版本管理,再对分层、插件的生态在持续做建设。我们也和交互设计同学一直紧密连接,对于插件生态和图形工具,去做通用的能力建设。文娱的B端C端产品业务,一直都希望能够助力到行业的数字化、智能化建设,在今天我们分享的主题中,绘座和票务属性中还都有很多智能化场景可以去探索。 对于前端同学来说,还有更多可以期待的: 比如VR,我们在去年其实已经在C端产品中落地,观众在选座时,还能够模拟看到实际的观看效果、对于座位选座有更直观的体感。2020年业界也推出了 WebXR,这方面的能力和硬件连接的更加紧密。 另一个就是 WebGL 方面的探索。比如在绘座和选座的时候,大家其实很希望知道自己在操作的是什么楼层的、更清晰的分层边界。能够立体的去看到。其实Canvas和WebGL已经不是近两年的产物了,也有非常多新的标准协议将取代原有的技术总承,如Canvas 2d,取代WebGL2.0的新方案等。 最后,WebAssembly其实也是突破性能瓶颈、在思考方式上的“重新出发”。面向多端、跨业务属性能力复用,使用离机器更近的语言,或Rust这样的高级语言,去重塑底层能力的边界,也能够具备module imported 能力的标准,都在慢慢浮出水面。 相信在未来,绘选座技术方向会有更多扎实的能力沉淀和输出、对业务场景上有更强力的支撑。也欢迎所有对这个技术方向感兴趣的小伙伴线下交流技术。 第十五届 D2 前端技术论坛 PPT 集合已放出,马上获取 关注「Alibaba F2E」 回复 「PPT」一键获取大会完整PPT

点击查看视频 大家好,我是景庄,来自阿里巴巴-盒马-体验技术部。我要分享的主题是 “盒马中后台跨端方案探索”,很高兴有机会与大家分享我在盒马,在中后台跨端,这个方向上的一些思考与工作进展。 开始前,我们首先来看一下,业界在移动化办公与多平台设计上的一些趋势。随着无线网络和云计算等基础设施的成熟,移动设备呈现爆发式增长。已经有越来越多的企业级产品开始拥抱多平台设计,移动化办公的概念已经深入人心。 华为在 2019 年发布了鸿蒙操作系统,希望借助鸿蒙系统打造以人为核心,万物互联的流畅体验。鸿蒙设备支持多终端的能力共享;应用只需一次开发,就可以多端部署;让用户能够实现跨设备和场景的一致交互和智能协同。 苹果早在 iOS 8 上就发布了一个称为 Hand-Off 的功能,通过 Hand-Off 功能,用户可以在苹果设备间实现跨设备的任务协同,例如用户可以直接在 Macbook 编辑的文档里,选择插入将刚刚使用 iPhone 拍摄的照片。 在企业应用领域,SAP 的 SaaS 产品支持跨平台使用。SAP 构建了一套智能化的多端设计体系 Fiori,可以低成本的面向多种类型的设备设计、开发、交付现代企业应用,但遗憾的是,它的方案比较封闭,并没有开放给外部使用。 同样,在实体零售数字化的背景下,盒马面临的是全新的 to B 体验命题。盒马尝试在人货场数字化的基础上,面向消费者,提供精准的人货匹配与全新的消费体验;面向作业者,则是构建全新的数字化流程,借助于多类型的智能化作业设备,为员工在多样化的业务场景下提供简单高效的作业体验。因此,我们需要重新思考和定义中后台的体验边界。 在盒马,我们面临的是更加多元化的中后台场景,既包括总部营运管理,门店经营管理,还包括配送作业,仓储作业等等。在这些多元化的作业场景中,得益于数字化作业体系的建设,员工可以借助,多类型的智能作业设备的各项能力,来辅助完成工作,例如大屏,打印,通知,定位等等。所以,我们认为新型作业场景下,作业人员将更多的依赖多类型的智能设备的协同,辅助完成作业任务。 盒马多端作业任务的主要载体是盒马工作台,盒马的各类作业角色围绕工作台来展开工作。因此盒马工作台就是一个庞大的新零售操作系统,面向不同的角色提供不同的能力,例如仓储管理,物流管理,CRM等等。依托于多端工作台,体验技术团队需要做的就是让各类作业角色简单高效一致的完成作业任务。 因此,我们首先要解决的是,如何面向多端工作台选择设计研发交付方案。通常有两种选择,要么是面向多端分别提供独立的方案,要么是多端统一方案。对于多端多套方案而言,无需考虑多端的差异化,但会导致开发维护成本高,交付效率低;对于多端统一方案而言,需要解决多端的差异化适配,但在此基础上可以获得一致的开发体验,并且交付效率高。考虑到业务上普遍的跨端协同作业需求,以及开发者常常需要同时负责多端的开发。我们选择的是多端统一的设计研发交付方案,从而为工作台用户提供简单高效一致的跨端作业体验。 对于建设多端统一的方案,我们需要解决三大问题 首先是,如何用一套设计系统支持差异化的设备与场景 其次是,如何用一套组件架构支持组件的跨端复用 最后是,如何用一套应用架构支持应用的跨端联动 从而形成,一码多端,多端体验一致的中后台跨端体验解决方案。 下面,具体来看一下我们是如何思考和解决这些问题的。 问题1:如何用一套设计系统系统支持差异化的设备与场景 首先来看第一个问题,如何用一套设计系统支持差异化的设备与场景。 传统设计系统大多解决单一设备的体验需求,跨设备的设计系统方案往往是独立的,例如国内社区主要的中后台开源设计系统AntD 和 Fusion, 都分别提供了独立的 PC 和 Mobile 的设计系统方案,并且不同的端通常由不同的设计开发团队支持,在 Design Token 的命名和组件 API 设计方面都存在较大的差异。导致跨端应用开发成本高,跨设备体验难以统一。 这种面向单一设备提供设计系统的方案,带来了跨端体验分裂。随着新型作业设备的出现,就需要不断的投入额外的设计开发资源,一方面带来了多端设计体系的分裂,另一方面导致开发投入大幅提高,并且难以保障跨端一致的用户体验。因此,我们认为中后台场景需要有统一的跨端设计系统方案。 此外,传统设计系统通常只考虑单一场景下的用户体验,不考虑环境的影响。但在盒马,还有门店档口,配送站,大仓等多样化的作业场景,不同作业场景在空间、光线、湿度、使用者姿势方面存在较大差异,统一的标准化 UI 已经不能满足用户在差异化环境下的作业体验诉求。因此我们认为,设计系统还需要综合考虑作业场景下的环境因素的影响,以改善不同作业场景下的实际作业体验。 我们来看一个盒马门店营运作业中的多端体验问题的例子。在门店作业中,营运 Pad 和 餐饮 Pos 是两个主要的作业设备,两者屏幕尺寸均为 11 寸,分辨率均为 1920 * 1080,均为手势操作。对于跨端设计系统而言,我们可以依据屏幕的尺寸和交互方式来确定不同设备中界面元素的大小,但是,我们发现,在实际的作业场景中,餐饮 Pos 的界面元素往往比营运Pad大出很多。那么,是什么导致了这种系统界面的设计差异。 我们不妨来分析一下原因:营运 Pad 一般在门店作业中为手持移动操作,作业视距通常在 50-60cm,主要的作业用途是经营管理和数据看板。而餐饮 Pos 一般则为静止摆放,不可移动,小二为站立姿势操作,作业视距通常为 70-80cm,主要作业用途为餐饮结算等。在这种情况中,餐饮 Pos 上往往会需要更大的可操作区域,以便进行更舒适的操作。所以,跨端设计系统需要综合考虑到实际的作业姿态,作业视距,和作业意图。 我们再来看一个配送站叫号屏在不同空间环境下的体验问题的例子。叫号屏在配送站中用于展示配送的队列信息,配送员根据叫号信息领取包裹进行配送。通常叫号屏的最佳阅读视距为 1.2m - 3.6m,但盒马有 200+ 的门店配送站,在光线条件和可读范围上存在一定的差异,很多配送站无法满足标准视距的要求,导致相同 UI 在不同空间环境下的信息的传达效率和用户体验存在差异;所以,我们需要具体分析一下空间环境对用户体验的影响。 我们可以选择两个配送站点进行具体的空间环境差异分析。例如亲橙里店配送站,其空间为狭长型,正常视距为 1.2m - 4m,地下室无窗,环境偏暗;星光大道店配送站为四方形,正常视距为 1m - 3m,有窗,光线条件正常。那么,我们是否可以基于视距范围和光线条件,为不同类型的配送站提供差异化的 UI 方案,具体包括可调整的布局,可调整的栅格尺寸,可调整的字号序列,可调整的色彩模式等。所以我们认为设计系统需要能够基于差异化的空间环境因素进行适配调整。 综合上面两个例子,我们可以从场景环境中解构环境变量。具体包括:设备类型差异,例如屏幕尺寸、使用视距等;作业类型的差异,例如信息密度,反馈模式等;使用环境的差异,例如光照湿度等;以及系统类型的差异。进而我们可以基于环境变量推导和计算设计变量,通过设计变量映射视图变化。加公式这样,我们就可以建立基于环境变量的 Design Tokens 计算流程。这个计算过程其实就是对设计师的经验的数字化,并通过拟合公式化的设计规则函数来计算 Design Tokens 在不同设备或场景下的具体值。在此基础上,我们开发了跨端 Design Token 的配置与生成系统,用于面向具体的设备和场景做验证和优化。用户可以输入设备类型、屏幕尺寸、使用视距、信息密度等等参数来生成整个设计系统的 Design Tokens 值,还可以便捷的预览跨端组件的变化。基于这套跨端设计的思考路径,我们面向盒马中后台构建了全场景的跨端设计系统。它包括基于环境变量的 Design Token 计算逻辑;支持面向不同场景下的设备输出主题包;并面向应用层提供高对比模式,宽松模式,弱光模式等等设计系统模式。从而建立差异化场景和设备上的一致用户体验基础。 问题2:如何用一套组件架构支持跨端复用 第二个问题是,如何用一套组件架构支持跨端复用。 我们认为中后台跨端场景面临的是更加复杂的组件适配问题。对于移动端跨端场景而言,通常解决的是多类型的移动设备的跨端适配问题,需要面对的是多尺寸的手机屏幕,系统主要是跨 iOS 和 Android,在设备能力上也通常较为相近。但对于中后台的跨端场景而言,面对的是更加多样化的作业设备,屏幕尺寸的差异化范围更大,从 1.5 寸的 watch 到 55 寸的 tv 屏都有,系统平台更加多样化,设备能力难以对齐。为此,在建立了统一的跨端设计系统的基础上,我们还需要解决的是如何面向多类型作业设备,提供更加可扩展可复用的跨端组件方案。 跨端组件还需要解决差异化设备的交互适配问题。传统中后台场景以键鼠设备为主,但在盒马,触摸类设备已成为线下场景中的主要作业设备,例如我们前面提到的营运 Pad 和 餐饮 Pos 等。此时,我们就需要考虑组件在不同设备上的交互适配问题,例如选择器组件,在传统的键鼠设备上通常是局部区域的下拉弹层,使用鼠标点选;而在触摸设备上,则会采用全局弹层,支持用户进行手势滑动操作。因此,跨端组件需要解决面向设备的交互方式的自适应问题。 我们尝试对组件实现进行分层拆解。通常可以拆分为三个部分:视图样式层,用来提供组件的视图结构与外观样式;行为逻辑层,处理用户行为,例如鼠标键盘手势事件等等;状态逻辑层,管理组件内部的状态,通常是多端一致的,不涉及到跨端的适配问题。因此我们认为,组件跨端的重点应该是在复用状态逻辑基础上,实现视图样式与行为逻辑的跨端可用。 对于跨端组件的实现方案而言。通常大部分的组件实现都是以视图为中心,在视图代码中同时耦合状态管理和行为管理的代码逻辑,当功能变的复杂,并且需要处理跨端多重事件机制时,组件实现中就会耦合大量的事件处理代码,以及多重的视图判断逻辑,这个时候,组件的可扩展性和可维护性就会受到挑战。此时,我们可以将状态管理和行为管理逻辑中视图逻辑中解耦出来,建立以模型为中心的组件实现方案。 对于面向模型的跨端组件实现方案,我们可以通过拆解组件实现中的视图代码,行为逻辑代码,状态管理代码来解耦组件跨端实现的复杂度,在复用状态管理代码的基础上,进一步扩展视图代码和行为管理代码的跨端表达能力。例如图中的 Select 组件,我们通过将其拆分为多个独立的 Hooks,来重新组合实现组件的跨端逻辑;最终形成行为驱动状态,状态映射多端视图的组件实现方案。我们可以具体来看一下面向模型的跨端选择器组件的实现。useStyleProps 为样式 Hook,用来计算和返回样式相关的属性值;useSelectState 为状态 Hook,用来管理组件的内部状态;useDevice 为设备 Hook,用来进行设备类型的探测;useSelect 为行为 Hook,用来处理行为,计算视图层的属性值;最终组件返回响应式视图。这样,我们就可以通过分层 Hooks 的组合来构建可扩展可维护的跨端组件集。 在确定了面向模型的组件实现方案的基础上,我们还需要更加轻量灵活的响应式视图方案。传统的视图代码,通常以值为中心进行样式实现,并且需要编写复杂的媒体查询代码。为此我们在 HTML Elements 基础上扩展了 System Elements, 用来提供原子化的视图层跨端表达能力。之所以叫 System Elements,是因为它遵循了社区的 System UI 规范进行样式命名空间的定义。System Elements 以 design token 为中心,提供了标准化的样式属性集,内置支持 Design Token 传值,还可以便捷的声明元素的响应式变化。 并且这套响应式视图方案还可以支持按需生成 CSS 代码,与传统的全量生成 CSS 代码相比,没有类名覆盖与优先级顾虑,这种原子化 CSS 的方案为应用层代码提供了更多的优化空间。 考虑到与应用层结合,组件层提供了基于 React Context 的组件跨端自适应方案 -- SystemProvider。SystemProvider 由几部分构成,分别是:用于支持主题自定义的 ThemeProvider,用于支持设备上下文感知和获取的 DeviceProvider,用于实现色彩模式切换的 ColorModeProvider 构成。借助于 SystemProvider,应用层可以快捷的控制内部组件的跨端表现。 简单总结下跨端组件方案,我们认为可复用的组件实现 = 视图 + 行为 + 状态。在视图方案上,提供了System elements 响应式视图方案;在行为方案,封装了 usePress 等屏蔽端的事件差异的行为 Hooks。在状态管理方案上,封装了 useListSate 等支持跨组件复用的状态管理 Hooks。在此基础上去构建一套代码,多端可用的跨端组件方案。 问题3:如何用一套应用架构实现设备间的跨端联动 最后一个问题是,如何用一套应用架构实现设备间的跨端联动。 在盒马的新型作业场景下,越来越多的需求,需要建立应用的跨端联动体验。例如对于门店小二而言,既需要在 PC 上进行数据录入,任务管理等;也需要通过手机进行移动审批,发起即时消息;还需要通过 RF 进行商品拣货,调拨,盘点等。所以对于这些跨设备的作业任务,不仅需要支持应用的跨端运行,还需要支持应用状态的跨端联动。 我们来看一个盒马门店巡检数字化的例子。对于传统的巡检流程而言,通常依赖人工检查,借助纸质清单逐条排查问题,例如商品陈列和员工操作规范等等,最后进行统一录入汇总。对于数字化巡检而言,巡检员可以在手机上即时接收任务,并通过手机摄像头对问题进行拍照验证;批量录入则可以切换回 PC ,同步手机应用的表单状态继续录入,这样可以极大提升巡检效率。所以,我们认为新型作业场景需要建立应用的跨端联动作业体验。 因此,基于业务上的诉求,我们构建了多端复用与跨端联动的应用架构。对有跨端需求的应用而言,其差异主要是在视图层上,多端视图依赖的业务数据模型通常是相同的。因此,可以将应用分为 应用容器层、数据模型层、跨端视图层 三层。应用容器层提供统一的容器 API,屏蔽底层差异;数据模型层包括业务数据服务和应用状态管理,并支持应用状态的远程持久化;跨端视图层则用来面向不同端提供差异化视图。总结而言,跨端应用方案提供了 应用视图的跨端可用,应用数据模型的跨端复用,和应用状态的跨端同步。对于应用的跨端联动而言,数据模型层需要支持跨端复用与状态的跨端同步,可以借助具体的代码片段进行解释,图中 service 文件为多端共享的数据服务定义;store 文件为应用状态定义,可以进行数据服务的访问与状态的修改;还可以通过 App.sync 进行应用状态的远程持久化,而不再依赖于具体的业务后端去做应用的草稿态保存,从而支持多端视图的跨端联动。跨端应用还需要支持跨设备的路由切换方式适配,提供与设备匹配的页面切换交互。以点击列表项打开详情视图为例,在 PC 页面上,通常采取的是侧滑打开详情页;而在手机上,受屏幕尺寸限制,通常为堆叠打开详情页面。对此,应用框架支持开发者通过响应式数组的方式快捷声明跨设备的视图切换方式,开发者可以通过响应式数组的方式快捷定义跨设备的路由切换方式;数组的第一个元素对应最小断点设备使用堆叠视图,数组的第二个元素则对应下一阶段断点开始使用侧滑视图。 我们不妨通过一个演示片段,对跨端组件和应用的方案做个一个简单的总结。跨端组件支持按照不同的设备类型进行 UI 和交互的自适应,跨端应用则可以支持跨设备的页面级交互的自适应。 盒马中后台跨端体验解决方案内部的产品名为 ReX Design For OS,我们来回顾下产品的里程碑,我们最早在 18 年的 9 月推出了 1.0 版本,当时面向多端提供多套方案;此后,我们便开始考虑多端融合的一体化方案,在 20 年的 6 月发布了 2.0 版本,跨端组件支持 PC/Pad/Pos/Phone,以及跨端应用和容器方案;为了给中后台跨端作业场景提供极致作业体验,我们已经在着手打造全新升级跨端体验解决方案,并预计在 21 年 3 月发布,包括一码多端的组件和应用方案,以及完善的配套能力。 最后,我们通过一张图快速回顾下盒马中后台的跨端体验解决方案。主要包括 基于环境因子生成 Design Token 的设计系统部分;实现视图、行为、模型分层的跨端组件部分;以及多端视图共享数据模型和支持状态远程持久化的跨端应用部分。还包括工程基建,多端容器,消息中心,状态同步中心,和多端体验大脑等配套设施。 对了,最后还一件事!我们计划在 21 年 6 月,将盒马中后台一码多端的核心方案对外开源。 非常感谢大家的聆听,大家可以可以扫码加入微信群,进行进一步的交流,并关注盒马 ReX Design 后续的进展。 第十五届 D2 前端技术论坛 PPT 集合已放出,马上获取 关注「Alibaba F2E」 回复 「PPT」一键获取大会完整PPT

点击查看视频 大家好,我是零弌,来自蚂蚁集团体验技术部。在蚂蚁工作了三年,负责内部 nodejs 框架 chair 以及 nodejs 版本中间件的实现。在蚂蚁内部 nodejs 主要是用来开发一些 BFF 应用,中台产品和一些小工具。 BFF 应用的主要目的是为了让后端可以更好的为前端服务,在微服务架构下,后端能力会更偏向原子化,如果前端直接使用的话会比较难受,比如说一个页面需要访问多个接口,每个接口又会返回很多前端用不到的字段,又比如说在提交一个表单时,会有复杂的流程,涉及到前置检查,数据拼接,如果在前端直接提交不仅不安全也会很复杂。所以聚合层在微服务架构下非常重要。然而聚合接口会非常多,也会有很频繁的修改,让后端来写会有很高的沟通和联调成本,既然是前端需要使用的接口让前端自己来开发是效率最高的方式了。 中台产品会是一些全栈应用,比如说西湖区最好用的云端知识库语雀,就是一个由 nodejs 开发的中台产品。中台产品主要是提供完整的解决方案,chair 在蚂蚁为前端开发者提供了完整能力,从数据到接口都有完整的功能实现。 在蚂蚁,前端开发者也会使用 chair 去开发一些小工具,比如接口测试平台,压测管理等等,这些小工具往往都是来自于日常工作的创意,实现以后效果都很好,帮助大家都解决了实际的问题。 在蚂蚁工作的三年里,支持了各种各样应用的研发流程,发现除了写代码之外开发者还要关心很多线上的运维问题,这部分的问题非常消耗开发者的精力,一是前端开发者往往对服务器相关的操作不熟悉,二是线上问题往往都很突发,任何时间点都可能出问题,导致开发者的体验不好。因此我们看到了这样的问题,就想通过引入 serverless 的方式来解决。今天和大家分享一下我们的演进路线和具体的实施方案。 BFF 研发/运维成本 在蚂蚁 Chair的研发门槛还是很高的,新入门的同学往往是云里雾里的开始上手,可能本地调用的通的接口在部署之后又不通了。这个问题来自于蚂蚁的架构复杂度,首先简单的介绍一下蚂蚁的三地五中心架构,能做到异地多活是因为在中间件层有非常复杂的路由逻辑。路由逻辑是由蚂蚁特色的单元化方式LDC来约定的,LDC和普通的单元化不同的是 LDC中的单元有不同的类型,比如说全局唯一单元,同城只读单元,普通单元。在前端开发者中彻底理解这套结构和路由逻辑的同学非常少。 除了接口的调用之外,业务的可用性非常重要,除了主流程之外,还需要设计非常多的兜底方案。这些方案里就会使用到很多的中间件,比如说异步操作要通过消息来发送,运维开关要通过动态配置来推送,减少下游调用量、加快接口返回速度需要使用到缓存。这些中间件都是由蚂蚁自研,和社区方案不完全相同,不完全相同就带来了高昂的理解和学习成本。 前端主要开发一些产品和活动,会涉及到不同的投放方式,比如说支付宝端内 h5,小程序,淘宝端内h5,普通浏览器中访问的h5。在支付宝端内都会走无线网关,淘宝和普通浏览器中会走HTTP。除了外部的方案,我们还会开发一些比如说缓存的定时同步,消息订阅后的处理。这些研发模式均不相同,学习成本就会高。 距 Chair 应用的首次提交,已经过去了七年。经过这段时间的发展,已经出现了非常多的 BFF 应用,早期的 BFF 应用已经发展到了非常大的规模,对外的接口数最多的已经有 500+ 了,整个应用的的代码量也非常多,导致应用的维护成本很高。并且一个 bff 应用会涉及到多个团队参与开发,环境独占、发布撞车问题屡见不鲜。造成了开发期的效能下降。 BFF 大量研发工作都是为了活动所服务的,在活动的研发过程中就会涉及到前端页面、组件以及接口聚合的开发,在 BFF 的时期需要在两个独立的应用中进行开发,研发体验上不自然,让人感觉分裂。两个应用也会涉及到两个应用的独立发布,流程上也会更长。 现在蚂蚁线上的 BFF 应用很少有下线的操作,主要原因是一个 BFF 应用中承载了很多的功能,产品、活动的代码混杂在一起,无法梳理。这就造成了项目中无用的代码会越来越多,也使得项目的维护成本居高不下。 在研发完成后,需要对应用进行运维,保证业务持续稳定的提供服务。首先,可观测性非常的重要,如何对线上的服务情况心中有数,就需要有监控的支持。业务指标是开发者最关心的,成功率是否有下跌、接口响应时间是否正常、有没有异常出现,这些是最基本的监控。除了业务指标之外,系统的运行情况也是非常需要关注的,CPU是否有飙高的情况,内存有没有稳定在一定的水位还是有缓慢的上涨,是必须要关注的,这个影响到业务能不能持续稳定的提供服务。 在每个活动上线前,容量是最需要关注的事情,业务方首先提供了需要的业务指标,开发者要对系统不断的进行压测、扩容以确定应用可以满足业务方的要求。在满足了业务需求之后,还需要配置限流,保护下游应用不会因为容量问题而挂掉。压测过程是一件非常麻烦的事情,需要准备压测数据,在业务低谷进行全链路压测,耗时耗力,据统计一个新活动上线,一般都需要两天的时间来进行压测。 除了监控、容量有时还需要对线上应用进行人工的运维,除了可以自动处理的容器替换之外,线上出现了oom,core dump都需要进行人工的分析,确定问题引发的原因是什么,应该如何处理。还有可能线上的容器出现了 hang 住的情况,是需要进行人工的替换。 一个 BFF的上线流程主要就分为准备工作,编码,上线,运维。应用和资源的申请是比较复杂的,需要架构师和 sre进行审批,审批过程需要进行材料准备,不断沟通,才能顺利的完成审批。如果我们想要把大应用拆小,申请流程就非常有必要优化。活动是一个非常高频的场景,如果每个活动都需要应用和资源的申请,那可能大部分的时间都消耗在了这两步上, 系分、编码、验证、应用上线这几步都是必不可少的。如果不改需求的话,这几步应该都会很顺利,不涉及到反复的重复劳动和返工。但是系分、编码的门槛会比较高,首先需要设计出高可用的流程,在非核心链路上都需要兜底设计、核心页面挂了也需要保证业务主流程不挂,其次编码阶段也需要对框架、中间件比较熟悉才能少踩坑,快速的完成工作。我们需要优化的就是简化编码流程、降低上手门槛。 从压测开始就比较机械性了,每个应用需要进行的操作都是类似的,重复性很高,做起来会很枯燥,同时又很耗费精力,这样就导致开发者的幸福度不高。对于serverless的场景,运维操作能砍就砍,理想中的情况是完全不需要运维。 Function 开发 因此,我们经过对于 BFF 研发流程的思考,提出了 SFF 的理念,即 serverless for frontend,希望通过 serverless 的思路为前端研发者提效。立下了两个目标,轻研发、免运维。 而现在 serverless 的代名词几乎就是 function,我们会以 function 的形式为开发者提供崭新的编程界面。 首先我们看一下原有应用的接入层,涉及到很多的场景。比如说外部访问的会有 HTTP、无线网关,内部会有 RPC 调用、消息、集群调度,每一种不同的场景都会有不太相同的编程界面和参数。截图中举了两个例子,一个 HTTP controller,一个集群调度,两者的差距挺大的,http 场景下需要关心 HTTP path,method 参数的位置。集群调度场景需要关心调度类型、频率、参数。 虽然这种方式有非常高的灵活性,可以完全的使用各个场景下所有的特性,比如说 HTTP 可以决定是否是流式响应,把参数放在 query header 或者 body。但是在企业内部,往往不需要这么高的灵活性、内部一般都会总结出一套范式来决定什么场景下一般会采用什么样的方式。因此这么高的灵活性在绝大部分场景下可能都是一个负担。 我们需要的是一个更简化的编码方式,只需要关心业务逻辑,代码是如何编写的,而不用去管业务是以什么样的形式被触发的。 我们来看一下简化后的编程界面是什么样的。首先我们提供了一个配置文件,用来配置项目中提供了哪些 function,function 的名字是什么,可以被什么样的协议触发。这样开发者就完全不用关心协议的细节,比如说 http path 是什么样的,极大的减少了协议的学习成本,可以完全只专注于业务本身。同时一套代码可以使用在多种协议的接入场景中,本来每个场景都需要进行一次适配,有几个协议就要写几套代码,function 的模式下就可以节省下了很多的开发成本,如果需要新增一个协议的接入,只需要在配置文件中新增一个配置即可。 对于代码来说,采用了开发者最熟悉的 function 模式,对比 class 会涉及到类构造,状态的管理,方法调用三步。我们希望开发尽可能的简单,并且无状态,所以会采用最简单的 function。调用上下文,比如说当前用户,访问的 trace 会通过第一个参数 ctx 传递给开发者,这个 ctx 和 koa、egg 的 ctx 均不相同。Koa 的 ctx 是 http 上下文,而 function 的 ctx 是纯粹的业务上下文,不涉及到 http 信息,也不提供 http 相关的操作,这就保证了我们协议的扩展性。协议的细节不会泄漏给开发者,协议也就可以无限的扩展。Egg 的 ctx 扩展性非常的强,框架、插件、业务代码都可以对 ctx 进行扩展,导致了 ctx 非常的庞大和复杂,而 function 的 ctx 上有哪些接口是固定的,由框架来限制,如果有扩展的需求需要对框架进行修改。在总结了蚂蚁的 BFF 开发之后,对于框架的扩展需求其实非常的低,主要都是业务代码的复用。关于这个不在本场分享展开。 如果函数还涉及到其余的参数,会通过 function 其余的参数进行传入,这是最符合开发者直觉的。 BFF 模式下前后端分离的模式在 SFF 中又合并了回来。前后端分离最大的意义是明确前后端的边界,提升前后端各自的研发效率。但是在 BFF 模式下,前后端本来就是同一个人在开发的,在这种场景下,在同一个项目中进行开发自然是效率最高的方式。我们在 SFF 中提供了新前后端研发模式,和 Egg 不同的是去除了模版相关,保留了前端项目的独立性,让前端即可以由 CDN 来托管又可以由 Function 自己托管。就可以适配不同的场景,比如说 2c 的服务,有非常高的访问量,由 CDN 来托管是很合理的。对内的服务,访问量低、并且需要私密性,由 function 自身来托管也是很合理的。 云端一体也不是简单的把两个项目放在同一个仓库里就好了。如果只是把一个前端应用和一个 BFF 应用放在一起,那完全没有意义。我们做了很多的工作来削弱前端应用和BFF 应用的边界,比如在命令行工作中不用特别的区分前端和 bff,dev,test 都只需要执行一个命令即可。在研发流程中也只会感知到一个应用。 在 Function 的开发中,我们提到了希望开发者不关心协议的细节,相对应的我们自然不希望在前端的开发中还需要感知协议的细节。因此我们提供了 OneAPI 的客户端,OneAPI 适配了蚂蚁所有的协议,只需要知道系统、方法就可以进行调用。不用关心是 HTTP 还是 RPC 接口,完全统一了接口的调用方式。 如果前端还是要调用 fetch 或者 jsbridge 来实现和后端的交互,这样前后端的边界就还是在,思路要在 react 和 bff 中不停的切换,我们希望尽可能降低前后端的研发差异、降低上下文切换的成本。OneAPI 提供了很好的解决方案,我们会自动的对 function 的代码进行静态分析,生成 OneAPI 客户端。在前端只需要简单的调用一个方法,即可实现一个 function 的调用,在编码过程中是感知了方法调用而不是 http 请求。OneAPI 就像一座桥,帮助我们跨过前后端边界了。 在 BFF 模式中,一个巨石 BFF 应用完全就是承担了太多,会有很多的活动汇集在一个 BFF 应用中,这个会导致很多的问题。我们来看一下把应用拆小,这些问题是怎么迎刃而解的。 在大应用模式下多个活动并发时,限流就会比较混乱,需要计算所有活动值之和,有时每个活动的限流累计之和甚至会超过应用集群的总体限流值。同时由于没有资源隔离,多个活动直接也可能造成互相影响,比如说单个活动中存在死循环或者内存泄漏的问题,就会影响到其他的活动。如果把应用拆小,每个活动都有自己的 function,每个 function 只需计算自己的限流值。同时应用之间天然就是隔离的,不会有应用之间互相影响的问题,提高了稳定性。 在巨石 BFF 应用中,会有各种各样已经下线的活动代码,程序员是一种很懒的物种,几乎没人会去主动的删除项目中的历史代码,这就导致了历史的代码越堆越多,如果有新的活动又引用了老活动的代码,那是再也没有办法删除了。而小应用就会很清理,活动下线之后,对应的 function 代码就可以下线了。一个项目中不会存在很多无用的代码的问题。 一个 BFF 应用参与的团队很有很多,同时发布的活动也会有很多,如果正好有个活动正在发布、灰度,那其他的活动就被阻塞没有办法上线了,并且发布、灰度的流程会很长、可能有半天到一天,非常影响研发效率。如果是一个小应用,流程都是独立的,自然不会有这样的问题。 在我们的 sff 初期,仅解决了轻研发的问题,再看一下蚂蚁 BFF 打怪升级图,该有的运维操作一样没少。仅仅的轻研发还不足以称之为 serverless,我们还需要解决运维问题。 我认为的 serverless 是这样的。无机器预算,在现有基于容器体系下,上线需要申请资源,扩容需要申请资源,实际在线上运行的容器,有太多超低水位的容器在运行,并且资源占用了开发者太多的精力。如果我们可以做到即用即走,空闲的应用释放资源,需要使用时再进行扩容。实现按量计费,用了多少资源就开出多少的账单,就可以为开发者解决这样的问题。 在应用空闲时把资源回收,也有非常高的收益,不仅资源可以得到复用,开发者也不用再关心系统的运行状况,CPU 高了,内存涨了,下一次新的 function 也不会受到影响。没有一直在线的容器自然不需要运维操作了,开发者真正需要关心的应该是业务才对。 高密度部署 以无机器预算和 No Server 为目标,我们研发了一套高密度部署架构,提供了更轻、更快的运行时。 高密度部署架构会分三个部分为大家介绍: 高密度部署,是为了实现高资源利用率,降低线上容器水位低的问题。 二层调度,是为了进行实时调度,实现即用即走的目标。 极速启动,即用即走意味着极快的启动速度,我们希望在 500ms 内完成应用的启动过程 首先我们来看一下高密度部署,高密度指的是什么?这里的密度是指在相同大小的资源下,部署更多的应用。容器部署模式下,一个应用是以 4C8G 的规格来部署,高密度部署模式下,一个应用是以 0.5C512M 的规格在部署。左右两幅图对应的是相同大小的资源,可以很明显的看到高密度部署的模式下密度高了非常之多。 整体的数据是 16:128,这意味着以相同资源,至少可以部署八倍的应用。这里为什么说至少,是因为我们还有即用即走的特性,意味着我们可以将空闲的应用回收,把回收回来资源让给有需要的应用,就可以服务更多的应用。 我们再来看一下为什么高密度部署可以做到更高的资源利用率。一个应用的开销是 0.5C256M,那我们在 4C8G 的规格在就是一个非常低的资源利用率,但是如果我们的规格是 0.5C512M,资源利用率就一下提升起来了。 高密度部署也就是以超小的规格来进行部署,实现资源利用率的提升。 但是如果直接使用小规格容器来部署会有一些额外的问题。首先因为容器的数量翻了倍数倍, K8S 集群承受的压力将会大上数倍,调度将会变得困难,对于集群中的各组件来说同样会有压力。其次容器并不是仅仅意味着计算资源,还有网络、磁盘的资源。举个例子,在大规模集群下,IP 资源都会紧张,再翻数倍就有可能导致 IP 无法分配。同时对于 kubelet 也会有同样的问题,更多的容器意味着更高的压力。 除了小规格容器之外,容器本身还存在一些问题。在蚂蚁这种复杂环境下,K8S 中有太多的组件要参与调度过程,所以容器调度是一个很慢的操作,完全无法满足我们在 500ms 之内完成启动的需求。其次容器本身启动速度也是很慢的,一个 hello world 的容器启动就要 500ms 以上了,完全没有其他的时间可以留给应用启动。因此我们需要一种更轻更快的调度和启动方式。 Alinode Cloud 恰好提供了一种轻量级的资源调度。alinode cloud fork 进程时可以指定进程可以使用的计算资源,并且 alinode 会负责空闲进程的回收,降低了进程调度的成本。那留给我们的工作也就是进行进程级别的调度,当有一个 function 请求需要服务时,我们找到一个空闲的容器,拉起一个 function 进程即可。 这是 Alinode Cloud 的架构图,由一个主进程和一堆沙盒进程组成。沙盒进程也就是 Function 进程,限定了计算资源,主进程会负责额外的管理工作,文件、网络、ipc 线程池,沙盒管理、流量管理等等。调度器也会直接和主进程交互,来拉起所需的 function。 我们再来看一下二层调度指的是什么,一层调度又是什么?一层调度也就是 K8S 集群的调度,调度出来的结果也就是容器,而二层调度是指在容器内再进行调度,对 function 进程进行管理。这样的模式就可以避免对 k8s 集群造成过多的压力,原来是多少容器,现在还是多少容器,不会有额外的调度压力。除了进程更多之外,也没有更多的资源消耗了。 在我们的架构中,网关收到一个请求之后就会进行一次实时的调度,和容器内的调度器进行通信,拉起 function,将请求转发给 function。 网关不会去感知 function 进程是否存活,仅感知 function 最近调度到的容器。同时网关也会感知容器的资源,能不能拉起更多的 function 进程。因此网关的调度策略就会非常简单,首先查询 function 最近调度过的容器,如果找不到或者该容器无额外的计算资源就会随机找一台有空闲资源的容器进行调度。 而容器内的调度器也很简单,收到一个调度请求后,如果 function 进程还存活则直接返回该进程,如果不存在则和 alinode cloud 进行交互,拉起一个新进程。并且无需进行资源回收,alinode 会负责进行空闲资源的回收,容器内调度器可以感知到这个行为。 有了高密度部署和二层调度之后还没有达到一个生产可用的程度,function 的底层仍然是一个 egg 应用。一般启动速度在 3 到 5 秒之间,这个时间太慢了,会造成 function 的第一个请求完全无法正常响应,用户体验极糟。我们需要在 500ms 内完成启动过程,才能让用户体验勉强接受。 Egg 提供了启动数据指标使我们可以来分析一下启动过程中的性能问题是存在在哪。这里贴出了两个很典型的数据,一个是文件加载,另一个是中间件启动。 Egg 是一个基于约定的框架,在启动过程中会对文件目录进行大量的扫描,来确定文件是否存在并对文件进行加载。Load Config 就是对配置文件的加载,会涉及到框架、插件和应用的配置文件的加载。这里可以看到速度很慢,占用了 400 多毫秒。 中间件的启动过程非常复杂,会涉及到文件读取,网络 IO,中间件与中间件之间还会有互相的依赖。这里的 tr 是蚂蚁的 rpc 中间件。是一个非常典型的例子。rpc 的启动依赖了注册中心,注册中心启动涉及到了本地容灾文件的读取,远程注册中心的建练。rpc 启动的时候需要去注册中心订阅 rpc id,等待注册中心进行推送,获取到推送后再和 rpc 服务建立连接。这个过程非常的漫长。 我们来分析一下为什么文件加载会慢,因为加载过程中会有文件 IO,需要进行目录扫描和文件读取,其实这些文件在服务端都是固定的,我们可以进行优化。其次文件读取完成之后需要交给 V8 进行编译,编译也会消耗很多的 CPU 时间。V8 提供了带缓存的编译接口,并且 node 对其进行了封装,因此我们也可以对编译过程进行优化。 Alinode Cloud 提供了一套 require cache 方案,在启动期间可以 dump 读取文件的热点,并且缓存 js 的编译结果。这封缓存文件就可以在多个环境之间复用。我们劫持了 node 的 require 过程,如果缓存存在则直接从缓存里读取文件、并且使用编译缓存进行 js 的编译。加上了 require cache 之后,效果非常的明显,一个需要 3s 才能启动的 function 直接就加速到了 800ms。 我们再来看一下中间件的问题,中间件的启动过程非常的复杂,有非常重的逻辑,并且互相直接还有依赖,需要顺序的启动。同时中间件服务并不是这么稳定,下游的抖动会很影响应用的启动过程,使得应用的启动速度无法得到保障。看起来只要中间件存在我们的启动速度就无法快起来。 我们从 service mesh 的方案获得了启发,可以把所有的 rpc 客户端放到一个 sidecar 里面去,让这个 sidecar 可以提前启动好,不占用 function 的启动时间。这样 function 的启动过程就完全可控了,只涉及到了 function 自己的启动过程,不会有额外的影响,可以稳定的保持在一个固定的表现上。同时我们把中间件搬到独立的进程之后,还有额外的收获,中间件客户端是内存开销大户,把这些客户端搬走之后 function 进程的内存有了非常明显的下降。 聊完高密度部署,二层调度,极速启动几个关键技术点,下面来为大家分享一下我们系统整理的架构,这个系统是如何 run 起来的。 网关是直接对接流量的,因此稳定性非常重要,在网关的设计上完全没有外部依赖。首先网关没有持久化存储,不会有数据库连接问题,第二不依赖下游系统,不会因为下游系统的故障导致系统不可用。部署控制面和注册中心推送的信息均会进行本地容灾,完全满足高可用需求。所以网关可以几乎无限的进行水平扩容,不会因为容量问题而导致不可用。当有容量上的需求是完全可以对网关进行扩容。 同时网关需要有极高的性能,在网络上多了一跳,要尽可能的减少对与响应时间的影响,因此网关在处理请求时都是流式处理,不需要使用大量的内存来记录请求体和响应体,因此内存的开销很低。并且请求处理时仅进行 header 的解析,解析 body 是非常消耗 cpu 的操作,网关所需要的只是 function 的路由信息,例如请求对应哪个 function,因此 header 中的信息就足够了,以此来减少 cpu 的消耗。 网关中触发器,路由,LB 是网关的请求主流程。在触发器中,会将不同协议的请求统一的转换为一个 OneAPI 请求,以便网关内部以及 function 对其进行处理。在路由阶段,需要将一个请求定位到一个 function 中去,进行请求到 function 的路由。 function 的路由逻辑会有多种实现,比如说 function 的灰度发布,需要将 1% 的流量转发到新的 function 中去。或者 function 的 AB 测试,根据客户端的某个字端请求到对应版本的 function 代码中去。这些路由信息会通过部署控制面来进行管理,通过动态配置下发的方式推送到网关上。 到了 LB 阶段也就是需要进行实际的容器路由了。这里也就是刚刚提到的二层调度的具体实现,找到最近调度过的容器或者空闲的容器。 容器架构会比网关架构复杂很多。首先是 function 调度器,需要维护调度过的 function 进程的状态,function 进程是否仍然存活、或者已经被 alinode 销毁这是非常关键的数据。当有一个新的 function 请求到达时,就需要判断 function 进程是否存活,存活的情况就可以进行复用,如果 function 进程已经被销毁,那么就需要拉起一个新的 function 进程。 中间件部分涉及到到对框架的修改,中间件的方法不在是一个普通的 js 方法调用。在 function 中的中间件方法仅仅是一个代理方法,实际的中间件执行是在 eggsidecar 进程中。首先我们需要抽象出一套协议用来进行中间件调用的序列化和返回的序列化,需要支持异常情况的处理,并且还要保证分布式链路上下文的延续,不能切换到 egg sidecar 模式之后就把原来的分布式链路不可用了。然后我们需要实现一套客户端和服务端可以在 function 进程和 egg sidecar 进程中进行通信,需要考虑各种边缘场景下的可用,比如说某个进程异常退出了,响应超时等等。最后我们要将框架内中间件的方法统一的代理到 egg sidecar 进程。 Alinode Cloud 中的沙盒进程是实际的 function 运行进程,他们需要严格的计算资源控制来确保不会相互影响,比如说有个 function 是个调皮的邻居,会逐渐占用大量的内存,如果不加以限制会把整个服务器的内存资源耗尽。所以资源隔离是非常重要的特性,事关整个集群的稳定性,如果一个带有严重内存泄漏的 function 会从一个容器开始慢慢的拖垮整个集群。 我们来完整的看一下一个 function 请求链路。首先每个请求都会先通过网关,触发器来进行协议的统一化,路由实现了 function 的多版本控制,LB 实现了二层调度,用一句话来描述就是将一个请求定位了哪个容器上用哪一份代码来运行。到了容器之后,通过触发器解析出网关提供的信息,使用的代码包是什么,具体的请求是什么。 可以看到整个链路中不再有容器了,开发者就不用在关心容器的 cpu 内存怎么样啦。开发者完全和容器、操作系统解耦了,不用关心 function 的运行环境,专注于 function 的结果即可。并且 function 处于空闲时即可回收,剩下的事情也完全不用开发者操作,一些轻微的内存泄漏完全可以不用再处理了。在集群容量充足的情况下,开发者也无需关心压测、容量问题,只需要配置对应的 function 限流值,在流量上涨阶段自然的会进行扩容,在高峰过去之后,空闲的 function 也会进行回收,最大程度的利用了空闲的资源。实现了我心目中的 serverless,无机器预算、在一个应用上线时不用操心资源,后付费即可。No Server,开发者完全不用接触到服务器相关的事情,用完即走。 在此我们就可以把 蚂蚁 BFF 打怪升级图进化为 蚂蚁 SFF 打怪升级图,众所周知在计算机领域优化一个问题的最好方法就是绕过这个问题。在 SFF 的场景下,我们绕过了资源申请、压测、扩容、限流、服务器运维这些步骤,开发者就完全不用再关心运维问题,解决了大量的重复劳动,极大的提升了研发效能,提升了开发者的工作幸福感。 跨入 BFF 时代的时候,一部分前端开发者掌握了后端开发的能力,解决了聚合层到底属于谁的问题,极大的提升了前端开发者的研发效率扩展了研发边界,开创了属于 nodejs 的 BFF 时代。经过这些年的发展,这些 BFF 系统的维护成本越来越高,让很多前端开发者望而却步,拉低了对于 node 开发的兴趣,逐渐的前端开发者开始分裂成了纯前端开发者,BFF 开发者,新的边界又出现了,这意味着研发效能会逐渐的下降。而我认为 serverless 正是解决这个问题的好办法,nodejs 让前端开发者有了编写服务端程序的能力,serverless 有希望让每个前端开发者都可以零门槛的写起来,只有写的人多了,生态才会健康飞速的向前发展。 第十五届 D2 前端技术论坛 PPT 集合已放出,马上获取 关注「Alibaba F2E」 回复 「PPT」一键获取大会完整PPT

狼叔(上图左),Node.js 技术布道者,Node 全栈公众号运营者,曾就职于去哪儿、新浪、网秦,做过前端、后端、数据分析,是一名全栈技术的实践者。已出版《狼书(卷1) 更了不起的 Node.js》《狼书(卷2) Node.js Web 应用开发》。入职阿里的三年时间,主要是在优酷 PC/H5 端从 0 到 1 的落地 Node.js 全栈,使用 SSR 对 Web 页面进行优化和重构,建设 SSR 应用的容灾、发布、灰度等能力,是集团内第一大 QPS 的 SSR 应用。在支撑好业务的同时,与组内同学一起孵化出开源框架 egg-react-ssr。2020 年到淘宝技术部,开启前端智能化的旅程,目前负责 P2C,和卓风是搭档。 卓风(上图右),入职阿里的八年时间,主要是在淘宝负责天猫、聚划算大促及日常营销业务产品的落地,曾负责面向天猫、淘宝、聚划算等商家的搭建产品建设和淘系智能 UI 体系建设和业务落地,相关产品和体系已陆续在向集团落地。近 1 年投身到前端智能化领域,致力于 Service to Code 体系建设,推动服务端智能出码的落地,目前相关体系具备一定雏形,在团队内业务范围进行闭环试验。 今天的主题我们会以 4 个维度进行展开,会详细介绍 P2C 这个产品概念的来龙去脉以及我们解决问题的思路,欢迎各位上车。 因为今天的话题是延续去年甄焱鲲(甄子)在 D2 的前端智能化实践的分享,所以在讲我们的话题之前,还是先介绍阿里前端智能化实践的整体布局情况是怎样的。如下这张大图,可以按三部分进行理解: 底层是以 Pipcook 为代表的“前端算法框架层”,其目的是通过它让前端工程师具备了踏入算法工程师门槛的可能,这点非常类似于 Node.js 对于前端工程师的作用,目前 Pipcook 已经发布到 v1.3 版本,开源社区也非常活跃,欢迎自取使用; 中层“研发能力层”是面向前端提升研发效率的产品工具,并且对这边提效的能力我们进行了抽象,分为 D2C(Design to Code)、P2C(PRD to Code)、S2C、和 C2C 等,今天我们要重点讲的就是前两者; 而顶层是应用底层、中层前端智能化能力服务的上层业务产品,在过去三年里我们前端智能化的产品能力已经覆盖集团 17+ 个 BU(Business Unit) 70%+ 的前端,当然这个数字不算太新,新的数字在不断上升。 提到 D2C,我们先回顾下应用 D2C 能力的 Imgcook 产品今日的发展现状,从下图可以看到 Imgcook 的发展数字比较可观,且应用覆盖了 2020 年双 11 会场 90%+ 的模块开发,出码可用率达到 79.26%,且需求吞吐量提升 1.5~2 倍,给前端研发带来实质性的提效。 然而,提效并不等于完全替代前端人工开发,从 79% 的数字上我们看到还有 21% 的出码率没有达到,且 79% 这个数字在 2019 到 2020 年一直上浮不大,所以仿佛 D2C 走到了上升瓶颈阶段。 但经过我们的调研发现,事实并不是 D2C 的能力达到极限,而是从 Design 视觉稿中挖掘的出码信息达到了极限,剩余的 21% 的出码信息,我们发现要从产研链路的上游 产品经理(PD,Product Designer)的 PRD (Product Requirement Document)中才能拿到。 所以我们将输入向上游链路扩展到 PRD 这一环,而 PD 生产的 PRD 又兼顾到前端下游链路后端的出码;同时前后端的出码界限一直以来并没有那么清晰(很多前端的代码其实也可以放置在后端 BFF(Backend for Frontend) 层,比如初始数据的字段加工),所以我们将输出也扩展到下游链路后端这里。 因为我们将输入输出在产研链路上向上下游链路进行了扩展,所以理论上我们所做的工作也发生了本质的变化,由原来的 设计即代码(D2C)转变为 需求即代码(P2C)、需求即生产,将多种产研角色纳入到我们的产研工作台当中,形成多角色的在线协同,通过这次跨界,理论上会带来的出码率的进一步提升。 所以这就是 P2C(PRD to Code)的由来。我们期望借助 P2C 能进一步的提升产研的交付速度,期望能给 PD 提供端到端的产品交付能力,期望间接提升 PD 的业务 KPI 辅助业务增长。所以,可以看到相对 D2C,P2C 的目标用户发生了本质性的变化(由设计师、开发者转变成了 PD),基于这个点,我们对 P2C 的产品设计理念做了如下三方面的约束: 首先,要继续基于设计稿,这部分的出码率已达到 79%,这边的出码信息对 P2C 依然有用,所以这部分不能舍弃,同时,PD 基于设计稿来完成 PRD 会更佳方便直接。 其次,将 PD 原来书写 PRD 的工作转变成基于设计稿来标注业务信息的工作,一方面这样操作对 PD 来说更直接,另一方面这样的操作对 PD 的工作负担也相对较少。 最后,我们要确保 PD 的标注信息能够出码,要做到“需求即代码”,不能出码的输入信息,意味着不会进一步提升出码率,这就失去了 D2C → P2C 升级的意义。 基于设计稿已不用再过多介绍,应用 D2C 能力的 Imgcook 已经是一个很好的例子。那么“标注”和“出码”要具体怎么设计?接下来就会依次进行介绍。 首先介绍 P2C 的标注,想要知道标注怎样设计,必须预先知道 PD 是怎样一类人,他们的工作方式是怎样的。 从 PD 的日常的工作调研发现,PD 是一类聪明、有想法有意思却又非标的工作群体,他们没有很多可标准化的工作具象内容,平时消耗在产研链路上的沟通比较多、新老产品经验传承也是断层的、书写的 PRD 文档也没有具象标准、五花八门所以书写的 PRD 下游角色也不怎么看,书写这样的 PRD 对 PD 来说本身已是一种负担和痛苦。 PD是非常擅长产品业务上定义的(比如什么叫“买贵必赔”、什么叫“冰点价”),这是除了 PD 以外其他角色不具备的能力,比如设计师,能在设计稿中表达的业务信息非常有限。 所以,P2C 标注的工作,就是要贴合 PD 的痛点和角色特点来进行设计,我们期望通过以下四点来帮助 PD 完成产品需求的定义。 第一步,我们期望 PD 在上传 Sketch 设计稿之后,P2C 会借助 D2C 的能力马上对设计稿进行第一步的解析,生成结构化可视化的在线标注画布,供 PD 进行第二步的操作; 第二步,我们期望 PD 在第一步的视觉画布基础上,进行业务信息的标注,完成业务逻辑的准确定义; 第三步,我们期望 P2C 能够提供给 PD 一种直观且轻量化的标注设计工具,辅助 PD 能快速完成类似多态等复杂业务逻辑信息的录入; 第四步,我们期望 P2C 能够提供给 PD 一种所见即所得的能力,通过预览的交互形态间接来确认产品背后的数据源信息,这就衔接到服务端的数据接口设计,下会会再讲到。 最后,经过所有的一个个步骤,本质上我们期望给 PD 提供一种非常贴合他手工标注的业务逻辑组织方式,期望 PD 的每一次标注都映射到背后的一个逻辑单元方便 PD 进行快速标注,而逻辑单元又能确保出码,这就是“逻辑点”概念的由来,尽管对 PD 是透明的,却对 P2C 非常有用。 所以,经过上面步骤对 P2C 产品的探索,我们也更加清晰了 P2C 的产品定位。概括一下如下图所示,P2C 要在 D2C 的基础上兼顾业务含义的定义和出码量的绝对提升,这就是 P2C 的产品使命。 所以 P2C 的整个标注体系,就是如下的这套结构设计,基于设计稿的 Canvas 画布,提供给 PD 基于逻辑点的标注操作面板,非常直观、方便地辅助 PD 对产品需求的定义。 那么在这里有人会问,没什么不给 PD 一个 PRD 的文档编辑器来对需求进行录入呢? 这样的方案我们尝试过,甚至尝试过不止一个方案,但过去的失败都告诉我们 100% 采用纯的自然语言来描述需求,对 PD 虽然可行,但对出码却不可行,至少当下 NL2Code 这个学术业界难题还没有非常好的攻克掉,所以这对 P2C 不利,而且纯的自然语言描述并不如这种基于设计稿的标注对 PD 来说操作更直接、更简洁,所以当下这套标注的产品设计,也是我们经历种种失败后选择的一条非常贴合 PD 且可行的一条道路。 那么 PD 究竟怎样标注?操作方式是什么样的? 以下两张图就是 P2C 里对标注这一产品能力的具体设计思路,可供大家参考。 背后使用的是一套上卷下钻的交互设计理念,同时对于 PD 如果从 P2C 推荐的标注点(逻辑点)列表中找不到他所需的标注点的话,P2C 还给其提供的自定义的工单链路,方便其完成需求的定义。工单的背后是借助人工、机器学习来对 PD 定义的需求进行出码定义和训练,下文会再介绍。 所以从 PD 是视角来看完整的需求迭代动线就如下图所示(图中的 S2C 赋能可以理解为 P2C 背后的智能化出码能力,下文就会重点提到),需求从创建到标注到产出一份完整的可供预览和汇报的 PRD 文档和预览 Demo,再到视觉稿的更新升级如何借助以图搜图(即以图搜存量标注信息)进行存量基础上的迭代,完整地展示了需求迭代的整个过程。 而第二张图就是以真实的产品需求为例,完成这整个产品迭代过程背后的一些具体技术过程,如“布局识别”、“各种逻辑点的识别”等等。 从上图我们基本看到了逻辑点的获取途径有三种,具体如下图所示: 第一种是 D2C 视觉识别这一步骤中从视觉稿中获取到的逻辑点信息,比如从“N 件 N 折”、“商品白底图”“淘抢购坑位”等这样的视觉表达挖掘到的逻辑点信息; 第二种是从 PD 的组织结构信息、产品背景信息中挖掘到的一些需求基本信息,比如“淘抢购频道”、“大促会场”等,这部分信息可以辅助 P2C 确定业务领域,缩小逻辑点的推荐分范围; 第三种是从 PD 直接在需求工作台的视觉稿画布上标注的业务逻辑信息,比如“无门槛的定义”、“冰点价的定义”等,这部分信息可直接作为视觉稿的补偿信息,方便 P2C 挖掘更多出码所必需的业务逻辑信息。 总得来看,有这三部分的信息即可确定全量的逻辑点,同时通过这些丰富的逻辑点一步一步地指引标注,通过标注自动更新逻辑点,最后通过选择的逻辑点和标注信息出码。 说到这里,大家可以看到逻辑点和标注之间是有关系的(上文也提到逻辑点就是为了贴合标注使用的),标注信息的颗粒度也直接决定逻辑点出码的可能性效果,简单来说,粗略一点的标注,比如像用自然语言来标注,对于逻辑点的出码效果不是太理想(当然我们也在研究这部分的能力);详细一点的标注,比如像 KV 表单,对于逻辑点的出码效果肯定是最好的,但对 PD 来说太具有挑战了,在让 PD 做完型填空,工作方式既死板又不灵活,PD 很不喜欢这种工作方式。 所以,PD 喜欢的理想标注状态就是 0 标注(即在产品需求迭代过程中,对于存量已标注过的信息不要再重复标注,甚至可以做到跨产品的标注复用),这就是标注的未来发展走向,通过 P2C 的智能化手段来逼近这个目标;与此同时,借助逻辑点与标注的映射关系,能实现 0 标注,意味着首先要实现存量逻辑点迭代的 0 研发(即在产品需求迭代过程中,借助智能化能力对于存量逻辑点可以通过细微地变种形成迭代所需的新逻辑点,甚至也做到跨产品、跨技术的逻辑点复用和生成),才能对 0 标注提供可能性。 所以,从 0 标注、0 研发的角度来看 P2C 产品从现在到未来的发展路径,基本符合下面的发展规律(如下图所示): 阶段一,就是当下借助 Sketch 视觉稿和 Sketch 标注信息生成代码的过程; 阶段二,是将 PD 角色的完整生命周期的工作内容搬到线上需求工作台当中,同时打通产研完整的产研链路,形成一定程度在线协同,完成需求的交付过程; 阶段三,是大量借助 AI 提供大量可替代人工重复标注和出码的服务可能,节省产研链路上的人力的重复性开销,形成一定自动化程度上的需求交付过程; 阶段四,是在前面基础上,拥有大量历史标注、出码数据的基础上,将 AI 的能力进一步提升,从而达到视觉稿/PRD 的上传即出码过程,即需求即代码的交付过程。当然,这是后话。 上文讲完“标注”的产品设计过程,那么接下来再重点介绍下“出码”的产品设计过程。 讲出码之前,还是要先关注下 D2C 目前版本中运用逻辑点来进行出码的实现过程。 如下图所示(图中的视频可从文章顶部的直播视频中查阅到),借助视觉稿插件我们对视觉稿做了一定程度额外标注,导出之后给到 Imgcook 工作台,然后开发者需要在 Imgcook 的逻辑库当中录入视觉稿中存在的逻辑点信息,逻辑点信息包含逻辑点的识别和表达两部分,从而实现在设计稿导入到 Imgcook 工作台之时,马上可以识别到视觉稿中可能存在的逻辑点。 上面过程就是 D2C 借助逻辑点来实现出码的完整过程,可以看到面向的用户角色是开发者,而这点就是与 P2C 的本质区别,P2C 面向的是 PD,所以不可能让 PD 进行逻辑点的预先定义和应用。 然而不论 D2C,还是 P2C,在出码的实现链路设计上都是可以抽象为“逻辑意图的识别”和“逻辑意图的表达”两部分的,即从识别获取到“逻辑意图”(逻辑点),再基于“逻辑意图”表达成为真正的逻辑代码。 但 P2C 相比 D2C,它要升级点恰恰也是“识别”和“表达”的这两个过程: “识别”要升级,原因是 D2C 原来的识别器是离散的,能识别的信息都是单模态的,比如不会把 UI 上的文本、布局、UI 样式、上下左右的信息、业务上下文等信息综合作为算法模型(Model)的输入,导致传统识别器能预测的语义信息的准确程度有限,外加上今天 PD 角色标注信息的引入,所以势必要对“识别”的算法模型进行根本性地升级,形成多模态的语义识别模型才可提升预测语义的准确率,从而更加精准地命中逻辑意图的语义靶点。 “表达”要升级,原因是 D2C 面向的是开发者,而 P2C 面向的是 PD,所以原来在 D2C 场景中开发者使用特别爽的数据源绑定、字段/事件绑定,对于 PD 来说就不人道了,否则就变成了 PD 在替开发者在编程,这是一种工作量转移的投机取巧,不是 P2C 的设计初心。另外,PD 标注的业务逻辑信息,他是不关心也不清楚具体是由前端开发者实现的,还是由后端开放者实现的。所以,总得来看,对“表达”的升级,就重点体现在对数据生成、事件绑定和逻辑函数块 OP 的表达器升级上,数据生成是为了避免 PD 要预先像开发者一样选择一个服务端数据源,我们采用借助语义识别出来字段语义自动关联或生成服务端数据源;事件绑定概念会隐藏避免 PD 感知,以免出现 PD 像开发者一样定义事件的绑定过程;函数块 OP 的升级,是因为 PD 定义的业务逻辑,除了含有前端的逻辑代码生成以外,还有生成服务端 BFF 层甚至更深层次的逻辑代码。 以上这些就是要在“出码”链路上对原来 D2C 逻辑点的识别、表达进行升级的来龙去脉。 那么新版的逻辑点在上游标注和下游数据/代码之间是怎样交互的? 具体过程可以如下图所示,简单来说就是借助上文提到的标注信息,找到可能存在的逻辑点,逻辑点背后又分前端逻辑点和后端数据逻辑点,附带 PD 标注的逻辑点约束信息,就可以真正出码了。 所以,概括一下,出码链路从 D2C 到 P2C,升级的主要内容就是下图中橙色到紫色和深紫色的部分:橙色部分是原来的 D2C 出码链路;紫色和深紫色是当下 P2C 的出码链路,而且深紫色部分中可以看到有服务端出码部署的功能节点,比如 FaaS 代码部署。这里也顺带提一下,P2C 在服务端的部署是进行冗余部署的,因为算法提供给 PD 的逻辑点推荐信息很大程度上存在近似解,所以只用多套解进行冗余部署 PD 才可以借助预览效果进行最终所需效果的甄别。 上文讲到识别的升级,那么接下来就简单介绍下逻辑点识别的算法设计方案,以供大家进一步理解这一步升级的重要意义。 具体如下图所示,借助多模信息的输入,进行综合型的语义理解,提升语义识别的准确率。 比如,以右图“¥4999 ”为例,当将该文本和围绕该文本上下左右的周边信息,以及文字字号、颜色、长度、粗细等信息作为算法模型的输入,通过对其中信息的 embedding、降维、尺度归一化等操作之后,获取到一些语义特征的 label 信息,从而确定“¥4999 ”的最终语义为“618 大促商品活动价”。 上文讲到出码链路上逻辑点升级的设计和实现过程,那么接下来再介绍下在 P2C 产品领域内,对逻辑点的未来阶段规划是怎样的,以便大家能进一步了解到,原来逻辑点的设计就是对未来 0 研发打基础的出发点。 具体如下图所示: 在 P2C 产品的起步阶段,PD 来到 P2C 需求工作台上的标注和背后的逻辑点信息,都是通过人肉的方式录入和供给的,这个过程我们认为是 Step1 阶段,目的是在为 Step2 积累算法样本; 当 PD 在 P2C 需求工作台上迭代起需求之后,平台上沉淀的历史数据中的标注和逻辑点数据就会存在内在的映射关系,这部分数据会作为训练样本回流给算法模型,进一步提升算法模型识别和表达的准确率,从而整体降低标注的人工成本和出码的开发人工成本,这个过程我们认为是 Step2 阶段; 紧接着,随着 Step2 阶段的不断发展、积累和模型的演进,P2C 的需求工作台就具备了 AI 标注和自动化出码的能力,这就是我们前面畅想的 0 标注、0 研发阶段,这个过程我们认为是 Step3 阶段。 理想是美好的,也给大家看看现实的具体例子,以下是我们生产当中的一些 Demo 案例,右侧是我们在人工给算法准备样本及算法预测效果的 Demo 案例(案例中数据我们做了去敏);左侧是逻辑点的中文输入,输出就是逻辑点的代码,同时这也是我们在攻坚的研究课题—— NL2Code。 但 NL2Code 的学术研究,我们也在起步阶段,背后涉及数理逻辑、机器学习、软件工程、语言学、信息论等学科知识也比较多,门槛很高,且这个领域在学术界的研究也非常有限,解决方案能用到工程当中的也几乎少见,目前我们在各国内外各大顶级高校进行产学研的深度合作,期望在 NL2Code 领域真正产出一些根本性的进展,可服务工程生产,为 P2C 带来更深层次的效率提升。 当然,我们在学术上的产出一些阶段性地通过学术 Paper 向外传递给大家,期望带来整个前端工业的智能化。 最后,我们讲一下 P2C 的产品展望。 讲展望之前,还是先回顾下我们今天的所讲内容。 今天我们最先介绍 P2C 是怎么来的,然后介绍了 P2C 当中两个非常重要的产品环节的产品设计,一个是“标注”,另一个是“逻辑点”,借助“标注”我们收集到完整的需求信息,借助“逻辑点”我们找到需求出码的中间桥梁,借助对“标注”和“逻辑点”的“数据采集”我们找到训练“需求意图-服务出码”模型的基础数据,借助这个模型我们完成了整个需求即代码的交付过程。 同时我们也介绍到,P2C 是站在 D2C 肩膀上成长出来的产品,所以原来 D2C 的产品能力并没有浪费,而均作为 P2C 的基础基建。当然,让前端在 P2C 应用算法,也十分依赖底层 Pipcook 提供给前端的算法框架能力,所以,P2C 的建设也十分要感谢 D2C 和 Pipcook 能力的布局和建设。 最后,展望一下 P2C。P2C 的能力今年在业务当中在边落地边打磨当中,计划明年的 4 月份提供一个对 PD 更加友好的体验式交付平台,计划明年 10 月份可以对外公测。 最后,大家如有什么疑问,都可以在下面的群里进行交流。同时也欢迎大家使用我们的产品、参与我们产品社区的建设。另外,我们持续保持对外招聘,非常欢迎同道中人加入我们,一起共建前端的未来产品。 谢谢大家!谢谢 D2! 更多内容,参考 Imgcook Product:https://imgcook.com Imgcook Github:https://github.com/imgcook Pipcook Github:https://github.com/alibaba/pipcook IUI 2021 Paper - Auto-Icon: An Automated Code Generation Tool for Icon Designs Assisting In UI Development: https://www.yuque.com/docs/share/ec67f566-60c6-4cb4-967f-118829b7e63b?# 阿里巴巴前端智能化掘金社区: https://juejin.cn/user/1626932942211464

重磅下载!来自阿里巴巴双11的云原生大规模落地指南

复制该链接到浏览器完成下载或分享:https://developer.aliyun.com/topic/download?id=1055 11 月 11 日零点零分 26 秒,天猫双 11 的订单创建峰值就达到 58.3 万笔/秒,阿里云又一次扛住全球最大规模流量洪峰。与此前不同的是,继去年天猫双 11 核心系统上云后,阿里巴巴基于数字原生商业操作系统,实现了全面云原生化,底层技术升级带来了澎湃动力和极致效能。 如今,企业上云已经成为一种必然趋势。与此同时,作为诞生于云计算时代的新技术理念,云原生让企业用云的方式发生着从“上云”到“云上”的转化。速度下载《云原生大规模应用落地指南》,从技术体系升级、到技术能力突破、再到双11云原生实践,看最全面的阿里巴巴双11云原生技术实践经验。 独家下载《云原生大规模应用落地指南》 推荐嘉宾寄语 程立 阿里合伙人、阿里巴巴集团首席技术官 “2020年双 11 的主题是「云原生」,是在「云上」实现核心系统全面云原生化的的第一年。我们看到,云的定义在不断变化,它成为了商业领域数字化的底座和基础,不再单指传统云计算了,而是将未来的方向指向云原生。某种程度上,恰恰是因为云原生,我们才能从过去的束缚中解放出来。不迈出这一步,我们的综合能力很维迎来下一次突破。” 蒋江伟 阿里云高级研究员、阿里云基础产品事业部负责人 “云原生让企业用云的方式发生着从‘上云’到‘云上’的转化。通过云原生,企业可以最大化使用云的能力,聚焦于自身业务发展,开发者也可以基于云原生的技术和产品,提升开发效率,并将精力更多地聚焦于业务逻辑的实现。云原生正在成为新基建落地的重要抓手。只有提前拥抱基础设施,才不会被时代淘汰。” 丁宇 阿里云研究员、阿里云云原生应用平台负责人 “云原生已经成为云计算的再升级,通过重塑整个软件生命周期,成为释放云价值的最短路径,加速企业数字化创新。我们将今年在阿里巴巴双 11核心系统全面云原生化过程中积累的经验沉淀成为这本电子书,希望帮助更多企业和研发人员去更好地做新技术的尝试、迭代和落地。” 精彩抢先看 阿里云原生中间件首次实现自研、开源、商用“三位一体”,技术飞轮效应显现 阿里云在探索中一直存在的苦恼,是内部的自研体系、商业化的产品技术与开源的项目,三方的技术路线一直没有机会融为一体。然而,就在今年阿里云提出了“三位一体”理念,即将“自研技术”、“开源项目”、“商业产品”形成统一的技术体系,最大化技术的价值。>>点击查看更多 以 Kubernetes 为代表的容器技术,已成为云计算的新界面 可以说,以 Kubernetes 为代表的容器技术正成为云计算新界面。容器提供了应用分发和交付标准,将应用与底层运行环境进行解耦。Kubernetes 作为资源调度和编排的标准,屏蔽底层架构差异性,帮助应用平滑运行在不同基础设施上。CNCF Kubernetes 的一致性认证,进一步确保不同云厂商 Kubernetes 实现的兼容性,这也让更多的企业愿意采用容器技术来构建云时代的应用基础设施。>>点击查看更多 Serverless 如何落地?揭秘阿里核心业务大规模落地实现 2020 年,新冠肺炎疫情催化数字化生活方式渐成常态。在企业积极进行数字化转型、全面提升效率的今天,几乎无人否认背负“降本增效”使命诞生的 Serverless 即将成为云时代新的计算范式。>>点击查看更多 更多精彩内容,请前往电子书页面下载获得。 藏经阁系列电子书 阿里云开发者社区——藏经阁系列电子书,汇聚了一线大厂的技术沉淀精华,爆款不断。点击链接获取海量免费电子书:https://developer.aliyun.com/ebook

手把手教你开发互动游戏,看 EVA 互动技术体系在金币小镇的实践

作者|驭剑 今年金币庄园迎来了一次改版,改版后的金币小镇给用户带来了更丰富的视觉风格和全新的玩法。EVA体系是我们团队在互动业务多年探索的基础上产出的,它是一套上手快、开发效率高、能力完善的互动研发体系。EVA体系能大幅提升研发效率,小镇快速改版上线就是一个很好的范例。本文将介绍EVA体系是如何在小镇项目中实践以及一些个人的总结。 如下图就是金币小镇的首页界面,它包含了上方的游戏区域和下方的商业化部分,今天主要介绍上方的游戏区域。 2.5D 简介 小镇的游戏方案采用了 2D Isometric(等轴测或者等距)的方案来实现,2D Isometric一般被简单称为2.5D。2.5D 是指一种在2D游戏中制造出3D效果的显示方法,这种方案更多的是对于视觉设计的规范,视觉按照一定的规范来设计素材,游戏开发同学基于素材来做放置拼接素材来搭建场景。 2.5D游戏素材【左侧】,拼接后的效果【右侧】(注:图片素材来源kenney网站) 细心看就会发现上方右侧图片地面上有一个个平行四边形的格子,素材就是基于这一个个格子作为基线来摆放拼接的,这就是我们经常说的Tiled Map(瓦片地图)。Tiled Map是使用一些小单元(瓷砖)来拼成一副大地图的游戏做法,Tiled Map可以通过Tiled Map Editor这类工具来搭建。 小镇用的就是用的上方的方案,下图就是小镇游戏区域的Tiled Map视觉示意图,其中数字代表的是每个建筑的点位。 小镇游戏分层 小镇项目整体涉及建筑部分逻辑相对比较单一(渲染和升级替换资源),整体逻辑集中在领金币和多人的助力合力业务玩法部分。针对这种互动游戏中碰到的普遍情况,既有Canvas又有DOM+CSS,我们一般使用混合开发的开发方式。 小镇项目中会将游戏区分为三层,具体分层如下: Background层负责游戏场景的背景图片,Scene层(游戏引擎开发)负责建筑的排列渲染,Hud层负责业务逻辑的展示,利用传统DOM和CSS的排版优势,更能跟上业务的节奏。 小镇开发的基本工作链路如下:通过EVA Store的一站式上传、预览、代码导出流程后就能交付游戏引擎的资源了,然后将交付后资源使用EVA编辑器搭建场景后输出场景数据,最终将场景数据交由EVAJS渲染游戏场景,业务UI层使用DOM+CSS开发。 基于上方的三层分层后,Scene层渲染使用到EVAJS游戏引擎,EVAJS采用了ECS的设计模式作为底层架构,EVAJS ECS设计如下:了解Unity的同学一定对这个不陌生,EVAJS提供了全套对于EVA Store丰富素材System、Component的支持。 我们举例要渲染一个龙骨动画,这时候我们需要创建一个实体,然后将龙骨动画(Dragonbones)组件添加到实体上,最终龙骨动画渲染系统来管理相关的龙骨动画组件。伪代码如下: import { Game, GameObject, resource, RESOURCE_TYPE } from '@ali/eva.js'; import { RendererSystem } from '@ali/eva-plugin-renderer'; import { DragonBone, DragonBoneSystem } from '@ali/eva-plugin-renderer-dragonbone'; const game = new Game({ systems: [ new RendererSystem({ canvas: document.getElementById('canvas'), width: 324, height: 240, transparent: true, // System: DragonBone系统 new DragonBoneSystem() // Entiy:游戏对象 const dragonbone = new GameObject('dragonbone', { position: { x: 162, y: 240 // Component: Dragonbone组件 const dragonboneCom = new DragonBone({ resource: 'dragonbone', armatureName: 'B-1-9-3-2x2' // 将Component添加到Entiy const animation = dragonbone.addComponent(dragonboneCom); animation.play('newAnimation'); 互动素材准备 我们了解了如何使用EVAJS渲染一个龙骨动画到场景中,小镇中每个建筑对应的是一个龙骨动画,小镇中随着用户等级提升龙骨动画素材个数会达到120个以上,这时候这么多的素材要如何管理呢? 互动中的素材管理面临如下三个问题: 素材格式众多:面对图片素材、模型素材、动效素材、音视频这么多个素材格式,每个素材格式又可能包含多个资源文件,如果我们采用单独上传到CDN,对于引擎使用和后期的维护都是相当困难的。 如何最优化素材:不同格式的素材在上传后如何才能最优的跑在引擎上,如何让设计师同学即时预览到素材效果? 多人协作:在协作流程中,如何让不同角色的人协作起来 针对上面三个问题,EVA Store给出了很好的一站式解决方案: 1、EVA Store支持的如下众多格式,并且这些互动素材的协议标准是由经济体互动小组统一制定的,这就意味这些沉淀在平台上的素材资源可以放心的使用。2、针对每种不同的素材格式,EVA Store都有相对应的算法进行优化,如帧动画的图片合成压缩、龙骨动画(DragonBone)的顶点优化、雪碧图最小内存占用压缩等,这些操作可以保证素材达到最优化的效果,同时上传后给提供了即时预览方便设计同学查看效果,如下 3、由于游戏有好多章节,每个章节有对应各自建筑的素材,借助EVA Store我们可以将每个章节设置一个项目并且设置权限方便不同角色之间的分工协作。同时EVA Store的代码预览和在线实时编辑功能也能帮助前端定位资源问题: 素材管理的事情EVA Store很好的帮我解决了,接下来就是如何将这些素材按照视觉稿样子放置龙骨动画后生成场景数据,上面我们提到了tiled Map Editor工具能帮助我们搭建场景,但是现阶段要和我们的EVA体系进行整合还是需要费点力气: 小镇中建筑使用的龙骨动画,这个很难在tiled Map Editor中实现所见即所得的效果,同时在面对后期更多的素材资源格式也不能很好适应。 前端要基于视觉稿中的点位来放置建筑,类似于数格子后将建筑放上去,这是一个比较枯燥费时的事。 需要产出基于我们EVA规范的数据地图文件,方便后期二次开发。 我们做了个简单的编辑工具来解决上述问题(EVA Design已经在开发中): 1、我们提供了基于EVA Store素材格式导入(未来打通个人权限下的素材,选择项目素材后导入资源面板)2、采用将视觉稿叠加在搭建场景下方层来协助我们将素材资源放置在对应的点位即可3、支持导出json格式保存到EVA Store,我们制定了基于这类2.5D游戏场景格式,如下格式: "mapConfig": { "width": 30, "height": 30, "tileWidth": 108, "tileHeight": 54 "layers": [ "layerName": "buildings", "align": [-0.5, -1], "data": [ [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], // 1这个数字又对应的下方objects数组中index为1的元素( 即:building1 建筑) [0,0,0,0,0,0,0,0,0,0,0,0, 1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] "layerOrder": 0, // 对应上方数组中的index "objects": [ { "resourceKey": "building1" } // 对应上方的objects中的resourceKey, building1描述的是个龙骨动画 "resources": { "building1": { "name": "building1", "type": "DRAGONBONE", "src": { "image": { "type": "png", "url": "https://gw.alicdn.com/tfs/TB1A85jLEz1gK0jSZLeXXb9kVXa-256-256.png" "tex": { "type": "json", "url": "https://pages.tmall.com/wow/eva/f9b692a8e8b90fb695caf9a5fedf12ee.json" "ske": { "type": "json", "url": "https://pages.tmall.com/wow/eva/7ec54ea534ef1c121bdefb04636dee7e.json" 很多人可能会问,直接使用视觉稿中的定位来放置不是更简单吗? 其实搞这么复杂的二维矩阵有它一定的优势:1、建筑之间是深度的,存在相互遮挡关系,越是靠近屏幕顶部的物体应当越早地被画出来,我们现在只要按顺序遍历二维数组就能做到这点,不需要开发过程中人为指定 2、导出地图想当于将整个地图划分成一个个格子,我们可以通过移动格子来方便定位 3、方便实现移动对象的移动碰撞操作, 我们通过是否是道路瓦片来生成一份可行走的地图,如下伪代码: // 0:可移动 1:障碍 const walkable = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0], [1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0], [1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1], [0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0], [1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0], [1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1], [0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 可行走的地图数组产出后,我们就可以使用寻路算法(如AStarFinder)来实现角色从一个点移动到另一个点的寻路效果了。 EVAJS支持完善的插件机制,我们可以很简单的基于EVAJS的Plugin脚手架来开发插件,场景渲染中我们需要将上方产出的json格式渲染成建筑群。我们需要将一个个的点位转换成画布上的x,y值,这些x,y值就是Component中的纯数据表现,Componet伪代码如下: * 创建一个isometric的sprite精灵 * isoSprite相对于传统的sprite的Position是通过x和y根据tileWidth和tileHeight排布的 * isoSprite还具有sortable的,所以需要设置zIndex * @extends Eva.Component * @param {number} x - 在二维矩阵中第几列 * @param {number} y - 在二维矩阵中的第几行 * @param {number} tileWidth - 瓦片宽度,计算isoX,isoY使用 * @param {number} tileHeight - 瓦片高度,计算isoX,isoY使用 class IsoSprite extends Component { static componentName = 'IsoSprite'; _depth: number = 0; isoX: number; isoY: number; init(params: IIsoSprite) { const { x, y, tileWidth, tileHeight } = params; this.isoX = (x - y) * tileWidth / 2; this.isoY = (x + y) * tileHeight / 2; // 尽量拉开每个面片的层级,为了方便后期插入元素时设置层级 this._depth = 10 * (x + y); this.addComponents(); addComponents() { this.gameObject.addComponent( new Render({ zIndex: this._depth, this.gameObject.transform.position = { x: this.isoX, y: this.isoY, setZorder(depth: number) { this._depth = depth; System通过装饰器监听它所关心的Component,这里面我们监听的是上方的IsoSprite,当IsoSprite的_depth更变时就会触发System相关操作 @decorators.componentObserver({ IsoSprite: ["_depth"], Render: ["zIndex"], class TileSystem extends System { static systemName: string = 'TileSystem'; init(params: TileSystemParams) { this.placeTile(); createComponentByType(resourceName: number, spriteName?: string) { // 通过不同的资源类型生成不同的资源实例 * 通过map放置点位 * @param layer 地图点位 * @param mapConfig 地图信息 placeTile(layer, mapConfig) { const { tileWidth, tileHeight } = mapConfig; const { data, align, layerName, objects } = layer; for (let y = 0; y < data.length; y++) { for (let x = 0; x < data[y].length; x++) { // 基于不同的资源类型放置不同的资源 this.createComponentByType() update() { const changes = this.componentObserver.clear(); for (const change of changes) { if (change.type === "ADD") { // do something tiles add if (change.type === "CHANGE") { // do something tiles change if(change.type === 'REMOVE') { // do something tiles remove 上方开发的Component组件中有一个_depth(深度)变量,这个深度就类似CSS的zIndex,如下图的主建筑①的zIndex会高于遮挡住建筑②,由于建筑①占用了很多位置,这时会导致建筑②的一大半部分被挡住导致很难点中。游戏中我们会设置模型的hitArea来设定它的可点区域,我们使用右侧小工具来生成hitArea数据,我们设定主建筑的可点区域为如上形状,这样就能避免在点击到主建筑空白区域也触发事件,这样就可以规避了遮挡问题。 游戏和DOM交互 混合开发方式中游戏和DOM层由于分层了后,两个层之间的交互一般采用的消息事件来进行调度,消息事件机制是游戏开发中比较常见的解耦工具,为了规范事件调度机制,方便多人协作中事件发送监听的无缝衔接,我们采用EVA Base中的 MX(一套数据流转和事件通讯的方案)作为事件和数据中枢。如下代码演示了如何通过消息事件机制来实现游戏区和HUD层的交互: /** Eva Game */ import {Event} from '@ali/eva-plugin-render'; const evt = dragonboneGameObject.addComponent(new Event()) evt.on('tap', (e) => { // 点击游戏建筑 mx.event.emit('ClickOnGameBuilding', { ev: e /** HUD */ function HUD(props) { useEffect(() => { mx.event.on('ClickOnGameBuilding', e => { console.log('show game building tooltip') }, []); return <div></div> 可访问性优化 值得庆幸的是,我们在金币小镇上全链路是对Web可访问性做了优化。对于过渡依赖于读屏幕软件,比如iOS的“VoiceOver”, Android的“TalkBack”,可以顺畅的在小镇玩耍: 点击查看视频 金币小镇中针对Web可访问性方面(也称之为无障碍)的优化主要两个部分:游戏区域和非游戏区域。在这里我们主要和大家一起探讨游戏区域的可访问性是如何进行优化的。就是上图红色框中的部分:这个区域是金币小镇的游戏化区域,也是用户进来互动的区域,比如点击建筑物有相应的提示介绍,进点按钮会进入到相应的二级页面或者说拉引任务系统之类等等。 就从这个区域开始吧!如果你是Web开发者,通过浏览器调试工具查看这个区域,可以看到 <canvas> 和其他一些HTML标签(比如 <div> )组合在一起:采用浏览器调试工具的分层工具来查看将会更清晰一些:前面提到过,开发游戏区域前端主要采用的是Rax EVA进行开发的,游戏区域的可访问性优化都集中在 Hud 层:在整个游戏区域点击每个建筑物都会有相应的提示信息,或者有弹窗以及跳转等交互: 点击查看视频 对于Hud中的图标按钮,这个问题不大,他们就是纯DOM:比较麻烦的是 点击游戏区域建筑物的交互 。为了让这个交互能和屏幕阅读器这样的辅助技术有一个较好的通讯,我们采用了 Canvas和DOM分离的操作。即:在Hud层内置了和游戏区域相匹配的点击锚点 , 比如下图中小圆圈所示:这些锚点并不会影响我们整个UI效果,我们使用CSS做了一些处理,正常情况下他们都是一个 2px x 2px 的透明矩形,但在开启屏幕阅读器下面,锚点得到焦点时会有相应的焦点样式:锚点的DOM结构大致像下面这样: <!-- 提示框未显式,用户未点击锚点对应的建筑物 --> <div class="home__inresultant--force"> <div class="tooltip__anchor" role="button" tabindex="-1" aria-expanded="false"> <span class="sr-only">氧氧温室</span> </div> </div> <!-- 提示框显式,用户点击锚点对应的建筑物 --> <div class="home__inresultant--force"> <div class="tooltip__anchor" role="button" tabindex="-1" aria-expanded="true" aria-describedby="a11y__inresultant--force"> <span class="sr-only">氧氧温室</span> </div> </div> 比如上面示例的锚点,它有对应的提示框: <div> <div class="tooltips tooltip__inresultant--force " role="alert" tabindex="-1" id="a11y__inresultant--force" > <svg focusable="false" aria-hidden="true" width="216" height="118.4375" > <!-- 提示框UI,使用SVG构建 --> </svg> <div class="tooltips__content"> <div class="tooltip__inresultant--force--content"> <!-- 提示框内容 --> </div> </div> </div> </div> 不管是在锚点还是提示框的DOM元素上,我们都看到了ARIA相关的特性,比如 角色 、 属性 和 状态 : 角色 :在锚点的 div 使用了 role="button" 告诉屏幕阅读器,它是一个按钮;在提示框的 div 使用了 role="alert" 告诉屏幕阅读器,它是一个警告框(或提示框) 属性 :在锚点的 div 使用了 aria-describedby 属性绑定提示框的 id 值,让他们有一个绑定关系 状态 :在锚点的 div 使用了 aria-expanded 来告诉屏幕阅读器提示框的状态,如果提示框未显示,该属性的值为 false 表示提示框是折叠状态,反之为 true ,表示提示框是展示状态,屏幕阅读器可以读出提示框的相应信息 有关于ARIA更多的介绍这里就不展开了,如果你对这方面知识感兴趣的话,可以阅读下面这些资料: WAI-ARIA Authoring Practices 1.1 https://www.chengrang.com/a11y/aria-practices/aria-practices.html#tabpanel Accessible Rich Internet Applications (WAI-ARIA) 1.2 https://rawgit.com/w3c/aria/master/ ARIA – 100 Days of A11y https://100daysofa11y.com/tag/aria/ WAI-ARIA - an introduction to Accessible Rich Internet Applications / Patrick H. Lauke https://patrickhlauke.github.io/aria/presentation/ tabindex, Keyboard Focus and Some ARIA in Screen Readers | Articles | Accessible Culture http://accessibleculture.org/articles/2010/05/tabindex/ Why, How, and When to Use Semantic HTML and ARIA | CSS-Tricks https://css-tricks.com/why-how-and-when-to-use-semantic-html-and-aria/ 我们从ARIA的世界中回来。 在锚点和提示框上除了使用ARIA之外,还使用了一些其他对屏幕阅读器友好的特性,比如使用 tabindex 来给非聚焦元素设置焦点;比如在不需要被屏幕阅读器识别(朗读出来)的元素上显式设置 aria-hidden="true" ; 比如使用CSS让文本只让屏幕阅读器可以识别: .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); clip-path: inset(100%); white-space: nowrap; border-width: 0; 由于这样的场景在整个游戏区的使用频率非常的高,加上UI个性化较强(Tooltips尖角各异),因此我们封闭了一个svg-tooltip的组件,在封装这个组件的时候,我们把无障碍相关的特性内置进去。在使用的时候只需要像下面这样即可: <SvgToolTip className="tooltip__growth-wrap" a11yId="a11y__lock" a11yRole="tooltip" visible={true} trigger="none" content={growthContent} closeOutSide={false} {...NormalToolTip} onVisibleChange={v => onToolTipVisibleChange(v, config.petName)}> <div className="tooltip-anchor" style={calPosStyle(toolTipsPos)} role="button" tabIndex={-1}> <span className="sr-only">{skin.name}</span> </div> </SvgToolTip> 在调用SvgToolTip时,需要给该组件透传a11yId这个props,并且与触发SvgToolTip元素的aria-describedby绑定在一起。即aria-describedby的值和a11yId值等同。 另外有一个细节需要注意的就是,Tooltips提示框有两种不同的交互类型,一种是无需任何交互,一进入页面提示框就展示;另外一种就是带有交互,用户点击建筑物之后提示框展示,经过几秒或用户点击另外的地方,该提示框会隐藏。因此在设置 a11yRole 时要选择不同的值: 提示框不需要任何交互显示的,给 a11yRole 传一个 tooltip 值 提示框需要点击才显示的,给 a11yRole 传一个 alert 值 这样在编译出来的代码,就是像我们上面所说的一样。 SVG 的使用 在项目中我们使用了很多不规则尖角的气泡样式,为了兼顾优雅和通用性,我们使用了SVG来实现toolTip的外框,并且开发相对应的工具来解决更复杂的气泡样式。具体文章可以移步《用SVG实现一个优雅的提示框》。 动态弹窗方案之 EVA Ware 受制于苹果对于动态化H5游戏审核策略的限制,我们的项目需要跟随IOS手淘的节奏来集成代码到包中,这样一来大大降低了H5动态能力。面对业务中大量的玩法策略需要由弹窗来承接,我们接入了一套经历过大促考验的弹窗规模化解决方案,简单来说就是拉取弹窗表现层的DSL,在客户端来渲染并且基于弹窗管理器来管理各个弹窗的生命周期, 具体方案可以移步《互动生产力进化之路 | 618 淘系前端技术分享》。 CSS不规则形状的蒙层: 领淘金币按钮上的扫光效果使用的css不规则蒙层 适度使用APNG: APNG在手淘中表现已经非常不错了,项目中部分动效我们使用了APNG,在配置和修改的便利度来说远胜于一般动效。 第十五届 D2 前端技术论坛的 D2 SPACE 也是使用 EVA 来开发的,由淘系互动团队倾情支持。欢迎大家使用 EVA 体系来开发互动项目,我们团队的目标是【人人可开发,处处有互动】。如果你对 工程/搭建/低代码研发方向 或者 WebGL/图形渲染/特效方向 等感兴趣,欢迎微信联系/钉钉进群一起交流。 关注「Alibaba F2E」把握阿里巴巴前端新动向

PPT 来啦!第十五届 D2 线上直播圆满结束~

作者 | D2 前端技术论坛 12 月 19 - 20 日,第十五届 D2 前端技术论坛首次以线上直播的形式,在优酷直播间与三千多开发者云端相见。 本次大会一共有 21 个主题演讲,包含 3 个国外主题和 18 个国内主题。 目前国外主题资料还在整理中,其余场次都提供了 PPT 哟! 一键获取所有 PPT 扫描下方二维码,关注 Alibaba F2E 微信公众号,回复「PPT」 即可获得第十五届 D2 前端技术论坛的所有 PPT 文件。公众号后续也会推送 D2 部分视频,以及讲师分享的文章,敬请留意! (PS:直播间弹幕中奖的同学,优酷客服会在5-7个工作日内主动联系哦,请大家耐心等待。公众号周边中奖的同学请在12月31日之前尽快填写收货地址,我们会在1月初为大家送出各种周边哦,感谢大家的参与。) 那接下来就让我们一起回顾下本次 D2 的所有主题演讲吧~ 12 月 19 日分享 重构 RxJS 架构:我们如何让其更小、更快 来自 RXJS 作(da)者(lao) Ben Lesh 的分享,大佬直接 live coding, 现场重构 RXJS 架构! u1s1, 大佬的健身成果也真是赞啊! 盒马中后台跨端方案探索 来自盒马的前端技术专家景庄为大家带来的分享,他们团队探索了中后台跨端方案,并在盒马门店巡检数字化业务圆满落地,一起来听听他们的经验吧~ 以全球 Web 角度谈前端性能的更新与趋势 来自 Google 资深 Web 技术专家 全球 Palances 从 Web 的角度,谈前端性能的更新与趋势,包括 Google 如何定义及收集性能数据,又是如何针对这些数据进行优化的。 跨端的另一种思路 阿里巴巴国际事业部前端技术专家当轩分享的是《跨端的另一种思路》——Write Once 是一个理想目标,Write Logic Once 在部分场景下能更好的解决我们的问题。 钉钉表格 — 从 0 到 1 打造在线 Excel 来自钉钉文档团队的前端技术专家叶斋,详细地介绍了他们团队从 0 到 1 打造在线 Excel 的经验~ 基于 WebAssembly 的 IoT应用架构实践 聊到 IoT, 那就不得不提天猫精灵啦! 天猫精灵的 IoT 架构实践是基于 WebAssembly 实现的,一起听听前端技术专家渊之和我们分享他们的实践。 10 万级大型场馆背后的绘选座技术 芃苏是来自阿里影业的前端技术专家,他们团队在研发超大型场馆座位绘制及选取技术时遇到了种种难题,但都一一克服,并沉淀为各种技术方案~一起来学习吧。 从中台的前端走向前端的中台 有赞在前端技术沉淀上颇有建树,我们有幸邀请到了有赞前端团队负责人廖恺和我们分享他们从中台的前端走向前端的中台的历程。 媒体智能-淘宝直播流媒体互动实践 阿里巴巴高级前端技术专家林晚为我们分享了淘宝媒体智能的实践,看看他们是如何做淘宝直播流媒体互动方案的。 深入剖析海量数据场景下的用户行为分析方案 啦啦啦~让我们欢迎本次 D2 最可爱的讲师小姐姐——来自阿里云的沅沅,跟随她一起深入剖析海量数据场景下的用户行为分析 前端智能化实践—P2C 从需求文档生成代码 D2 特制压轴节目——狼羊相声来啦~来自淘宝前端智能化团队的狼叔和卓风搭档,与我们分享他们在前端智能化领域的实践,看看他们如何实现 P2C 从需求支撑到智能生成。 12 月 20 日分享 揭秘 TC39: ES2020 和 ES2021 TC39 成员、Node.js 的核心协作者 Ujjwal 来到 D2, 为我们揭秘 TC39 中 ES2020 和 ES2021 的相关特性,并鼓励我们一起参与其中~ 前端故障演练的探索与实践 阿里巴巴前端技术专家辰啸带来的是安全生产的话题,与我们分享他们在前端故障演练方面的探索和实践。 腾讯文档高效质量交付 来自鹅厂的测试开发工程师吴涛为我们带来高效质量交付分享,一起看看腾讯文档是如何做自动化测试的~ 如何建设跨端灰度监控 跨端这个话题从去年火到了今年,那跨端监控如何做呢? 让我们跟随阿里巴巴前端技术专家墨辉,看看跨端灰度监控是如何建设的~ 打造更稳定的 SERVERLESS 业务 阿里 Serverless 业务落地规模比去年同期增长 10 倍,承接的流量比同期翻了 6 倍。今年双 11 首次在核心业务接受流量考验。 那么如何打造更稳定的 Serverless 业务呢?听听阿里巴巴高级前端技术专家 - 张挺的介绍。 SSR 在双十一会场的落地实践 将 SSR 落地到 双十一会场活动页面的具体实践,用户体验体感最大最快 114%。实施过程中具体会有什么问题,有什么样的方法论的?听听阿里巴巴前端技术专家霸剑的分享。 Node.js - What's next? 想要了解 Node.js 接下来会有什么样的发展吗?如新特性?重要更新?亦或者技术上乃至组织上的关键举措? Node.js 技术委员会(Node.js Technical Steering Committee)主席 Michael Dawson 和你聊聊 Node.js 前沿进展。 serverless在前端部署领域的实践 字节内部为前端实现了一套 Serverless 部署架构,可以便捷地实现普通页面、微前端应用、SSR 以及 BFF 部署,目前接入项目已经有 4000+,CSR 日访问量 2亿+ / QPS 3000+,最高支撑过 1w+ QPS 的活动,SSR QPS 最高 4000+。 字节跳动头条号业务负责人凌艺宾为你带来 Serverless 在字节跳动前端部署方面的应用带来一些新的思考和方案。 高密度部署实践 蚂蚁集团前端技术专家、蚂蚁内部 Egg.js/chair 核心开发者零弌从 BFF 研发难题入手,分析蚂蚁是如何通过 Function 化实现轻研发体验,以及如何设计 serverless 架构以实现高密度部署的。最为本届 D2 两天的最后一个演讲,猝不及防的分享了大量干货,大家可以围观 PPT 进一步认真学习哦。 关注「Alibaba F2E」把握阿里巴巴前端新动向

免费下载!玩转云服务器,就看这5本电子书!

云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。玩转云服务器ECS是上云的第一步,也是最重要的一步。开发者社区准备了“ECS上云大礼包”助你一臂之力,快来学习吧! 1、《7天学会ECS》 《7天学会ECS》电子书正式上线,阿里云高校“在家实践”指定教材,开启云上生活,建站/博客/云笔记/云上编程环境/Linux学习环境搭建,五大实践场景轻松一站式掌握。https://developer.aliyun.com/topic/download?id=40 2、《玩转ECS从入门到精通(入门篇)》 《玩转ECS从入门到精通》本书分为入门、进阶两册,本篇先来了解入门篇。阿里云的1024种玩法之ECS云服务器,从基本组件概念、实例规格选型到资源计费介绍,本书精简了阿里云云服务器ECS的入门知识,以图文形式带您快速了解ECS, 上手阿里云服务。https://developer.aliyun.com/topic/download?id=947 3、《玩转ECS从入门到精通(进阶篇)》 《玩转ECS从入门到精通》本书分为入门、进阶两册,本篇内容直达进阶。适合对ECS云服务有一定熟悉认知的开发者。ECS,不只云服务器,进阶篇从入门与选型、自动化运维最佳实践以及架构优化思维三方面来介绍。本书通过多种服务化工具使用助你轻松管理云服务器ECS,手把手教你ECS最佳实践,揭秘你不了解的黑科技。https://developer.aliyun.com/topic/download?id=990 4、《ECS运维指南 之 Linux系统诊断》 本书以浅显易懂的案例带领您进入Linux 的世界,由浅入深,由表及里,层层推进,从运维工作的实际需求出发,全面讲解相关的技术、经典案例,以及常见问题的解决方案。作者通过风趣幽默的讲解,让读者尽可能避免枯燥乏味的理论解释,是学习Linux不可多得的一本好书。https://developer.aliyun.com/topic/download?id=143 5、《ECS运维指南 之 windows系统诊断》 无论你是新手还是老手,你的Windows系统都会遇到不容易诊断的问题。而当发生这种情况时,你会怎么做?本书结合阿里云工程师多年云上ECS运维经验,从实战角度讲解windows,实例丰富,容易理解,内容实用,适合学习。希望可以在系统出现问题但是又不知道到底发生了什么以及问题出现在哪里时,为大家提供解决思路和方法,高效的解决问题。https://developer.aliyun.com/topic/download?id=710 更多电子书合集分享 大数据电子书系列合集Java电子书合集云原生电子书合集 藏经阁系列电子书 阿里云开发者社区——藏经阁系列电子书,汇聚了一线大厂的技术沉淀精华,爆款不断。点击链接获取海量免费电子书:https://developer.aliyun.com/ebook

Java工程师必下载!Java开发手册+成神指南,史上最全阿里工程师实践精华!

Java作为众多开发者的必修课之一,在编程语言榜单上占据着重要地位,更是从事云计算、大数据等开发工作必备技能之一,了解Java编程规范当然是重中之重,本次社区分享了Java开发手册+成神指南+实战演练,带你学习大厂如何用Java! 1、《Java开发手册(华山版)》 网红级的开发手册,始于阿里内部规约,在全球Java开发者共同努力下,已成为业界普遍遵循的开发规范,涵盖编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程规约、设计规约七大维度。修炼一年终出关,这个版本将会给开发者带来更多惊喜。https://developer.aliyun.com/topic/download?id=10 2、《Java开发手册(泰山版)》 潜力修炼一年之久的《Java 开发手册(泰山版)》出关!此次共计新增 34 条规约,修改描述 90 处,其中错误码规则更是第一次提出完整的解决方案,可参考错误码示例表,快来下载阅读吧!https://developer.aliyun.com/topic/download?id=12 3、《Java开发手册(嵩山版)》 嵩山版经过不断地精进与苦练,已经日臻完美,它的内功提升之处在于: 第一、增加前后端规约。打通前后端的任督二脉,形成前后端协作开发的共识。第二、重画分层图例。新图更加突出分层的清晰度,并且去掉图中有歧义的向上箭头。 第三、修正BigDecimal的equals错误。3.0与3.00在我们的常规认知里是相等的,但是equals比较的结果由于考虑到精度因素,所以返回为false。 第四、修正泰山版的部分文字描述错误。 https://developer.aliyun.com/topic/download?id=805 4、《Java工程师成神之路(基础篇)》 《Java工程师成神之路(基础篇)》介绍了普通Java工程师必须要学习的相关知识点,包括面向对象和Java语言基础两大部分,涵盖基本数据类型、关键字、异常、I/O流、集合、反射、泛型和枚举......另外,内附成神导图! https://developer.aliyun.com/topic/download?id=923 5、《〈Java开发手册(泰山版)〉灵魂13问》 《〈Java开发手册(泰山版)〉灵魂13问》独家首发!全网千万阅读量技术博主深度剖析Java规约背后的原理,从“问题重现”到“原理分析”再到“问题解决”,下载《Java开发手册》必备的伴读书目!https://developer.aliyun.com/topic/download?id=80 6、《〈Java开发手册(嵩山版)〉灵魂15问》 《〈Java开发手册(嵩山版)〉灵魂15问》重磅来袭!“一线大厂如何用Java”解读再升级,千万阅读量博主深究Java规约背后的原理。规范学好Java还不来看一看? https://developer.aliyun.com/topic/download?id=811 7、《Spring Cloud Alibaba 从入门到实战》 Spring Cloud Alibaba 脱胎于阿里中间件团队内部,经受了阿里多年海量业务场景的考验,是目前最成熟、功能最丰富也最有前景的 Spring Cloud 实现。本书涵盖从基础知识到具体技术的讲解,从要点到实践,让你也能从入门到实战。即刻下载阅读!https://developer.aliyun.com/topic/download?id=940 更多电子书合集分享 大数据电子书系列合集 ECS电子书合集 云原生电子书合集 藏经阁系列电子书 阿里云开发者社区——藏经阁系列电子书,汇聚了一线大厂的技术沉淀精华,爆款不断。 点击链接获取海量免费电子书:https://developer.aliyun.com/ebook

舒文:浅谈阿里前端的多样化

作者 | 舒文 2007年,Jeff Atwood 提出了一个著名的观点, 戏谑又似认真地称其为 Atwood's Law:any application that can be written in JavaScript, will eventually be written in JavaScript. 时间快速穿行13年到今天,仿佛在印证戏言成真:在互联网软件工业的疆域上,以ECMAScript 为圆点朝各个方向射出一箭,凡目力所及的范围内,皆似洒落上了这一箭之威。 而在阿里,也像在诠释着这些上述断言,前端技术如初生牛犊般从蛮荒时代的PC Web 踏入到多个领域,在许多重要战场中发挥着重要作用。 在这儿,借着 D2 大会的契机,简单分享几个前端领域在阿里的应用场景,附带一些我对前端技术领域的一些思考,期待能够和众多的行业同仁们有交流互动的机会。 从 Web 互动到媒体互动 在早期,Web上的互动是为提升页面氛围作为附庸而存在的,为此有一个专用词“网页特效”作为代称。 曾经很长一段时间,互联网上存在大量的特效代码库、特效网站专门服务于开发者。而这些特效的基础原理就是通过 Javascript来变换样式和操作DOM实现的。 随着标准组织和浏览器厂商的不断努力,现代化互动的基础开始成型。除了硬件性能提升外,HTML5/CSS3,Canvas、WebGL让互动的开发显得更为标准、更高效可行,而非各种原理古怪、性能堪忧的Hack技巧。这也让在Web上实现大型互动成为可能性 - 可是要知道,曾几何时,Flash几乎是“双十一狂欢城” 唯一的选择。 今天,互动产品及对应的互动前端技术早已成为各大互联网公司的标配: 在技术上,继承了Web的优势,能够调整迭代,无需发版,天生跨端的同时还能兼具不错的性能。 在商业形态上,更游戏化的互动包括不限于“蚂蚁森林”、“淘宝人生”、“天猫农场”等类社交游戏产品使“人与人”、“人与平台”之间的互动具备了更好的可玩性、用户黏性,从而具备了更高的商业价值。 2020年,互动技术也成为阿里经济体前端技术的重点发力方向。以淘系互动技术为例,它构建在一个大型、完备的前端基座上:一体化的工程、构建、容器、框架、发布系统、渲染引擎。互动前端技术的核心简单地大概分为三部份: (互动)框架:基于游戏领域的通用构架,自底到顶的分层实现-Render/Render OBJ/Design Pattern/Utils,具备加载器、ECS、场景、插件化扩展等基础能力。 (互动)素材中心:接收并处理互动展示层所需要的资源并输出成型的互动素材,并通过SaaS化服务进行管理。 (互动)研发平台:面向互动生产者的工作平台,它具备包括不限于编码、拼装、编排在内的构建能力。 基于这套互动技术体系,冷冰冰的商业化产品开始具备了越来越多的趣味性和创意体验。 当互联网基础设施不断完善,硬件与带宽成本持续降低,直播/短视频逐渐形成获取用户时间的主流产品形态,也成为人&人、人&机互动的新场景。 传统的解决方案是在视频媒体上“遮盖”一层Web页面,内嵌在页面中的互动(如领取红包)和视频内容没有事实上的关联,而是通过预置的逻辑进行触发,“伪装”成视频与互动同步的用户体感。这种方式成本低廉,但代价则是牺牲了创意和灵活性,缺少想像空间,没有未来。 而媒体智能互动则是更合理的解决方案:通过智能化手段进行手势、表情等识别,互动素材与效果均与视频内容强关联,并在视频流上完成素材渲染。 从实时渲染角度来看,核心技术环节在:图像采集、数据处理、算法识别、渲染计算、端渲染展示 从研发生产角度来看,关键流程在:玩法生产、应用管理、玩法使用、端渲染展示 上述每个节点都涉及到各个关联技术及工具/产品,正是这些能力组成了媒体智能的技术体系。 从长远来看,无论在互动的自身形态、输入方式、承载媒介还是玩法创意,都必将有长足地发展,对于前端体系的从业人员,只要持续关注用户&终端、熟悉业务、不断学习必定会获得长足的技术竞争力和创造力! 搭建,不止于提效 过去几年,我在负责面向消费者端的搭建体系:把形形色色、千奇百怪的页面都看作组件们的集合,然后用极致简单的搭积木方式将它进行可视化组装。 如果拿冰山举例,我们尽量让用户们(运营、开发者)只看到露出海面的那一段,把概念和实操尽一切可能地简化,而被屏蔽在冰山下面的东西,包括了一系列的交付 高度被抽象的 界面+数据描述标准 ,我们称之为模块; 兼顾性能和灵活性的 客户端+服务端渲染架构 ; 离线的、简洁的 零代码可视化平台; 提供线上服务的 页面渲染引擎 + 数据网关; 有了这些交付物(以及基于它构建的大型生态),前端、设计师、后端(多数时候甚至不需要)围绕着高度可被复用的产品模块即可进行页面组装,将业务发布上线。这个方案简单又高效。以至于在很长时间,这套构架最终产生成了数以百万计的各种页面,其中包括不限于双十一,我们在阿里系各种App看到的很多页面都是基于这样的方案出来的。 然而这并不是终点。 其实道理也很简单:当效率上达到一定临界点后(通常是边际效应开始递减),对应的技术方案都越界碰触到另一个领域。 搭建技术也一样 - 一个业务的运行通常不是搭建一个页面就完成了 - 它涉及到整个业务的执行周期。好比一个线下商场要做一场年货活动,上架商品 这个任务只是工作中的一部份,其他包括不限于选商家、选货品、制造氛围、顾客动线都是必须得完成的工作。 而线上业务的运行亦如此,除了“搭建页面” 这个看似简单的动作外,还有各种上下游环节,包括不限于 - 数据哪来(选品)、以什么规则展示(算法千人千面)、抵达什么用户(人群规则)、界面是怎样的(新式交互)、在哪儿展示(跨端渲染)、浏览体验是否又快又好(性能&质量)、业务效果如何(数据看板)等等,每个环节都或多或少地关联着前端相关技术。 基于此,我们根据业务的实际需要拓展了系统的功能边界。慢慢地,原本的面向效率、被高度抽象化的工具系统成为了一个解决具象业务的产品。 在这个转变过程中,原本核心工作是完成前台页面的前端程序员,逐渐成为了一个面向业务的技术工程师,而其工作职责从原来的高效交付扩大到了方方面面,技术视野、技术能力都得到了很大的提升。这时,我们也很难单纯用技术栈来界定这位程序员是前端抑或是后端工程师。 相信在未来,这样的前端工程师会越来越多,也会成为前端发展的一个方向。技术栈从来不是技术人的桎梏! Serverless,孕育新的生产关系 还是得谈谈这个话题,如果说越发完善的研发工程体系在提升交付整备质量、周全的性能故障监控系统在改进交付效果,那么 Serverless 就是在尝试着在最合适的环节来优化生产关系。 想必很多初入 CRUD 阶段的前端同学都尝试写过一个形如 Todo、blog-like等应用,基于广受各类教程推荐的 Express/Koa+MongoDB+ReactJS/VueJS 套件方案实现。 然而写完应用后的踌躇满志在遇到技术面试/业务应用时则一片茫然:怎么和预想的不一样? - 性能调试、高可用、容量规划、多应用调用、数据库优化、跨栈中间件等等都是未曾太多考虑的问题,但若稍加深入思考,无需很久就进入新一阶段的灵魂拷问:为什么我要使用Node而不是其他工业化程度更高的语言技术栈? 而云原生下的Serverless 让多数前端们开始解除束缚: 便捷可弹的BaaS服务 弱/低运维成本 现代化的函数计算 无用赘谈太多的优势,只需缓解运维成本、稳定可弹的计算资源,在完备地BaaS下,离终端用户足够近的前端们就能快速的进行多栈开发,而这则很大机会带来的生产关系的变革,重新定义前后端的边界 - 把原来以 BFF 层为界碑的研发模式重新刷新一遍。 在这个基础上,一部份的前端职能会发生深刻的变化,他们为成为离业务更近的产品工程师,既可以实施商业小程序/轻应用,也能主导一场营销大促、也能驱动一个新业务场景的诞生。 当然,围绕着这种生产关系的周边生态,如职业定义、招聘要求、未来前景、企业人才规划都会随之发生变化。 也期待着这一天的到来。 关于 D2 多样化专场 其实在阿里以至行业,有更多的垂直深入的前端技术场景,包括不限于智能研发、文档协同、行为分析、跨端IoT、中后台研发、数据可视化、跨端研发等技术领域,限于篇幅不在此赘述,其中一部分领域性内容也会在 D2 大会上进行输出。 D2 组委会成员们花了相当多的时间和精力组织预选、试讲和遴选,从超过40个话题里面选取了少数具有代表性、技术性的内容,而它们都来自各领域的技术专家们基于实际的业务场景进行抽象淬炼,内容质量和信息密度都经得起推敲,也感谢这些热爱技术、愿意分享的嘉宾们。 在最后,今年的D2设立了“多样化”专题,当然不是为了证明前端无所不至这种狭隘观点。 其实,除了很多人记得的 Atwood 的妙语外, Reg Braithwaite 也有箴言:The strength of JavaScript is that you can do anything. The weakness is that you will. 软件语言史上至今没有、相信未来也不会有银弹。任何一项技术的诞生都源于解决某类逻辑事务,而随着问题逐渐被缓解,带着技术信仰的领域头羊们总会试图在衍生场景中复用技术优势,撞破边界牢笼 - 尽管大多最终颓然而止 - 这是不幸的,但确实是幸福的:不幸的是他们没有成功,幸运的也正是他们失败了。 在前端领域,包括不限于标准规范、应用框架、解决方案每隔一个阶段就会被更新,我们不需要抱怨要学习的东西如此之多。因为这一方面预示着这项技术的工业化程度还需要提升,同样地,在问题的背面也意味着行业空间大,具备非凡活力,行业人拥有了不起的创造力和多且大的发展机会。 相信驱动这些活力和创造力的,不是来自空中造楼阁欲望,而是技术人对解决现实世界问题的渴望。 同时也衷心祝愿所有参加D2的前端同行们能够在这个快速变化、发展的技术领域中找到最适合的赛道成就自我! 一起来第十五届D2前端技术论坛多样化专场学习更多精彩内容 关注「Alibaba F2E」把握阿里巴巴前端新动向

Rax 小程序运行时方案解密与思考

作者 | 逆葵 2020 年 3 月,暨支持编译时方案之后,Rax 小程序发布了支持运行时方案的版本。截至目前,Rax 仍是业界唯一一个同时支持编译时和运行时方案的小程序开发框架。本文将向大家介绍 Rax 小程序运行时方案的原理以及我们的思考。 回顾编译时方案 介绍运行时方案之前,我们再回顾下什么是编译时方案。顾名思义,编译时方案侧重于编译,这其中的代表框架是 Taro v2.x。其通过静态编译的方式,将 JSX 转换为小程序的模板语言(即 WXML/AXML 等),再辅以轻量级的运行时 JS 代码,抹平小程序生命周期和 React 生命周期的差异,使用户能够以熟悉的 React DSL 进行小程序开发。Rax 的编译时方案原理与 Taro v2.x 类似,关于实现细节,可以参考之前的文章Rax 转小程序链路原理解析(一)及Rax 小程序编译时方案原理解析。区别于编译时方案,运行时方案侧重在运行时实现渲染能力,不依赖静态编译,因此几乎没有语法限制,这也是其最大的特点。下面就来看一下运行时方案实现的原理。 小程序的底层实现实际上也是基于 Web 技术,但是反映至开发者层面,与 Web 却又大相径庭。在小程序中,逻辑层和视图层隔离,逻辑层通过唯一的 setData 方法将数据传递至视图层触发渲染,视图层则通过事件的方式触发逻辑层代码,其架构如下图所示。相比 Web 开发时开发者可以通过 JS 调用浏览器提供的 DOM/BOM API 随心所欲操作渲染内容,小程序的架构更加封闭也更安全,但也意味着 Web 代码无法直接在小程序上运行。对于现代的前端框架(React/Vue)来说,底层基本都是通过调用 DOM API 来创建视图。而小程序的视图层模板是需要开发者事先写好的,这意味着动态创建 DOM 的方式在小程序中不被允许。但是,小程序的自定义组件具有的『自引用』特性为动态创建 DOM 打开了突破口。所谓自引用,就是自定义组件支持使用自己作为子节点,也就意味着通过递归引用的方式,我们能够构造任意层级和数量的 DOM 树。 举例来说,假设一个小程序自定义组件 element 的 WXML 模板如下所示: <view wx:if="{{r.tagName === 'view'}}" id="{{r.nodeId}}" <block wx:for=“{{r.children}}” wx:key="nodeId" <element data="{{r: item}}" /> </block> </view> <text wx:elif="{{r.tagName === 'text'}}" {{r.content}} </text> 注意到,element 在模板中递归引用了自身,并通过条件判断终止递归。那么,当逻辑层通过 setData 传递了以下一份数据过来时: "nodeId": "1", "tagName": "view", "children": [ "nodeId": "2", "tagName": "text", “content”: “我是?" "nodeId": "3", “tagName": "text", "content": "rax" 最终呈现出来的视图便成了: <view> <text>我是</text> <text>rax</text> </view> 通过这种方式,我们巧妙地实现了在 WXML 模板固定的情况下,根据传入的 setData 数据来动态渲染视图的能力。而这,也正是运行时方案能够诞生的基础。 Rax 的运行时方案脱胎自 kbone——微信官方推出的小程序与 web 端同构解决方案。kbone 的设计原理可以参考其官网介绍,简单总结就是通过在逻辑层模拟 DOM/BOM API,将这些创建视图的方法转换为维护一棵 VDOM 树,再将其转换成对应 setData 的数据,最后通过预置好的模板递归渲染出实际视图。从 DOM API 到维护 VDOM 树的过程基本原理并不复杂,createElement/appendChild/insertBefore/removeChild 等对应着基本的数据结构的操作。 熟悉 Rax 的同学应该知道,为了支持跨端,Rax 有 driver 的设计。实际上,我们完全可以针对小程序端再编写一个 driver,根据上述原理实现其接口 API 即可。但我们最后的选择还是通过更底层的模拟 BOM/DOM API 来完成了整个渲染机制。这么做的考量是,第一,基于 kbone 开发,这是最快的一套方案,小程序端的 driver 只需复用 web 端的 driver-dom 即可,毕竟底层的 document 和 window 变量都已经模拟好;第二,则是因为我们想为开发者提供更贴近 web 的开发体验。这套方案意味着开发者除了使用 JSX 之外,也是支持直接使用 BOM/DOM API 创建视图的,灵活度会更高一点。我们把目光拉长到整个市面上的小程序运行时框架,remax 通过 react-reconciler 直接从 VDOM 层和小程序对接(类似上面说的 Rax 小程序 driver 设计),而 kbone 和 Taro 3.0 都选择通过模拟 Web 环境来实现渲染。这也与框架开发人员的设计意图有关,见仁见智。Rax 小程序运行时方案的基本原理图如下所示: Rax 小程序运行时中,模拟 DOM/BOM API 的库为 miniapp-render,其支持的 API 如下:除了处理渲染数据外,另一个比较重要的事情便是事件系统。其通过 EventTarget 基类实现了一套完整的事件派发机制。逻辑层 DOM 节点均继承自 EventTarget,通过唯一的 nodeId 来收集自身绑定事件。视图层模板上的每个内置组件都会绑定 nodeId,并监听所有可触发的事件,比如一个简单的 view 标签,会将 bindtap/bindtouchstart/bindtouchend 等事件都进行绑定。在事件触发时,通过 event.currentTarget.dataset.nodeId 获取到目标节点 id,再触发该节点上用户绑定的对应函数。 Rax 小程序运行时的工程主体流程 follow 了 Rax Web 的设计,Web 端 Webpack 打包出的 JS Bundle 可以在小程序运行时中复用。我们通过插件将 miniapp-render 模拟出的 window 和 document 变量注入该 bundle,再生成一个固定的小程序项目骨架,在 app.js 中加载 JS Bundle 即可。其整体工程结构如下图所示: MPA or SPA ? 以上架构是逐步演进的结果。最初,我们使用了 webpack 的多 entry 模式打包运行时小程序代码,也就是每个页面都会作为一个 entry 独立打包。这使得从行为上来说小程序更像一个 MPA。这带来的问题就是页面间公共依赖的代码不在同一内存中执行,与原生小程序表现不符。这个差异导致我们最终决定变更工程打包模式。目前版本的 Rax 运行时小程序更符合 SPA 的形式,所有的业务代码都打包到了一个 JS 文件中。 我们将 Rax 工程入口的 rax-app 包在小程序运行时上的链路做了一定改造,其在初始化时会根据路由返回各个页面的 render 函数,该 render 函数创建 root 节点(document.createElement)将对应的 Rax 组件挂载至 其上,并将 root 节点 append 到 body 节点(document.body.appendChild)。小程序每个页面在 onLoad 生命周期中,会创建一个独立的 document 并设置为全局变量,然后调用其对应的 render 函数进行各个页面的独立渲染。 从上面的小程序运行时原理来看,其性能相比原生是存在一定差距的,这主要由以下几个方面造成:第一:逻辑层运行完整的 Rax + 通过模拟 DOM/BOM API 处理 VDOM 并生成 setData 数据,需要消耗更多的计算时间;第二,相比原生小程序需要传递更多 setData 数据,如果容器层数据序列化能力较弱,会大大增加数据传输耗时;第三,视图层通过自定义组件递归动态生成视图,而我们知道递归动作本身就是一个性能损耗点。此外,由于无法预先知晓用户需要绑定的属性和事件,自定义组件模板中只能将所有属性和事件预先绑好,这导致小程序运行过程中会触发很多无用的事件,进一步加重负担。经过我们的 benchmark 计算,在支付宝小程序平台上,运行时小程序框架(包括 Rax/Taro/Remax 等)与原生小程序存在约 40% 的性能差距。 Rax 小程序运行时发布后,经测试其性能相比其他运行时框架存在着较为明显的差距,于是我们启动了性能调优的专项计划。通过以下方面的重构,成功将 Rax 小程序运行时小程序的性能拉升至业界领先水平,与 Taro/Remax 基本处于同一水平线。 更新数据精确化。在旧版本中,setData 的数据是全量更新的,虽然有 dom 子树分割批量更新的设计,但是数据传输仍然存在大量冗余。重构版本中,Rax 增加了节点渲染判断,未挂载节点无须触发更新;将所有更新收拢至顶层 root 节点统一批量处理, 并且通过精确计算数据更新的 path,实现局部更新。比如某次更新节点的 class 属性时,setData 的数据可能是: "root.children.[0].children.[1].class": "active" 内置小程序组件无需维护其属性列表,而是根据用户传参直接赋值。旧版本中,我们维护了所有内置组件的属性,在获取属性值的时候均需要调用 domNode.getAttribute,具有一定性能开销。重构版本 Rax 直接根据用户传参给属性赋值,并将默认值设置的操作移至视图层 WXS/SJS 中处理。 更新 miniapp-render 中的数据结构。经过梳理,Rax 移除了冗余的 tree 数据,重写了 getaElementById 等 API;重构了 attribute、classList 等类;使用了更符合场景需要的 Map/Set 等数据结构,提升了整体的数据处理性能。 渲染模板优化。在支付宝小程序中,Rax 使用 template 进行递归调用;在微信中,Rax 使用 template 调用 element 再调用 template 的形式以避免微信端递归调用 template 的层数限制。在模板中,我们尽量使用 template is 语法进行判断,减少 a:if/wx:if 条件判断,提升模板递归时的性能。 无论是出于旧有业务的迁移,或者是出于性能考虑,Rax 小程序运行时中都存在着混合使用的需求。目前,Rax 已经打通与小程序内置组件、小程序自定义组件、小程序页面、小程序插件混合使用的能力。这其中,使用小程序自定义组件是最为复杂的。 与小程序自定义组件混用 在 Rax 中使用小程序自定义组件,其引入路径需要与 usingComponents 保持一致(例如 import CustomComp from '../components/CustomComp/index')。在编译阶段,Rax 工程使用 Babel 插件进行代码扫描,检测到 JSX 中使用的某个组件是小程序自定义组件(根据其引入路径是否存在同名 axml 文件)时,会将其使用到的属性和事件进行缓存,然后通过 webpack 插件动态生成至递归模板中。在运行时中的创建节点阶段,通过查询缓存判断节点是否为自定义组件。若是自定义组件,则其渲染数据中会插入缓存中的属性,并且绑定事件至该自定义组件实例。 与编译时组件混用(双引擎混合) 通过 Rax 小程序编译时方案产出的组件,从使用形态上来说,可以直接视为小程序自定义组件。而 Rax 工程加强了运行时与编译时的联系,当在 Rax 小程序运行时中使用编译时组件 npm 包时,用户无需引入组件的具体路径,只需像使用普通组件时一样引入,Rax 工程将自动根据该组件 package.json 中是否存在 miniappConfig 字段来判断其是否为一个 Rax 多端组件,然后直接使用其编译时的组件实现。 未来优化方向 Rax 作为业界唯一一个同时支持编译时和运行时引擎的小程序开发方案,其双引擎混合使用的能力能够较为完美地实现性能与开发效率的平衡。在未来,Rax 将实现更为灵活的双引擎混合使用方式,如支持在单个项目中指定某个组件以编译时引擎编译,为业务提供更高的灵活度。 以上就是 Rax 小程序运行时方案的原理解析。运行时方案解决了编译时方案天生的语法限制问题,但是也存在着明显的性能掣肘。可以说,在当前 2020 年这个节点,小程序开发仍然没有所谓的银弹,也许 Rax 小程序双引擎的融合会是一个相对范围内的最优解。逆标准而上的小程序究竟能走多远,谁也无法下定论,未来相当一段时间内,开发者仍然要面临种种问题。站在小程序开发框架的角度,只希望所有开发者能够选择对自己最合适的框架,爽快而又高效地完成小程序的开发。 第十五届 D2 前端技术论坛抢票倒计时 关注「Alibaba F2E」把握阿里巴巴前端新动向

从需求生成代码?D2 最具争议的分享,你值得来瞄一眼

作者 | D2 前端技术论坛 狼叔和卓风即将在第十五届 D2 前端技术论坛上(12月19日)做《前端智能化实践:P2C 从需求文档生成代码》主题分享。这个 Topic 是 D2 多样化专场中最具有争议的,也是所有评委最想听的。据说在预审阶段,10 位评委中有 9 位给这个分享投了票。在试讲阶段,也得到了现场评委的认可,表示这个主题非常前沿,具有一定的前瞻性。 那么,为什么这个 Topic 具有如此大的吸引力呢?小编以为有以下几点。 有 2 位嘉宾共同一起演讲,他们的分工是怎样的? P2C (PRD to Code)是什么?这个事儿好像业界第一次听说,真的有用吗? P2C 有什么可提前爆料的黑科技没? P2C 和之前的 Imgcook 主张的 D2C(Design to Code)有啥差别?同一个团队,这 2 个概念之间是颠覆还是继承关系? 狼叔之前一直活跃于 Node/Serverless 社区,现在转战智能化领域,是什么原因?有怎样的思考? 下面我们提前采访一下狼叔和卓风,先介绍一下这两位分享嘉宾。 (左:狼叔 右:卓风) 狼叔,Node.js 技术布道者,Node 全栈公众号运营者,曾就职于去哪儿、新浪、网秦,做过前端、后端、数据分析,是一名全栈技术的实践者。已出版《狼书(卷1) 更了不起的 Node.js》《狼书(卷2) Node.js Web 应用开发》。入职阿里的三年时间,主要是在优酷 PC/H5 端从 0 到 1 的落地 Node.js 全栈,使用 SSR 对 Web 页面进行优化和重构,建设 SSR 应用的容灾、发布、灰度等能力,是集团内第一大 QPS 的 SSR 应用。在支撑好业务的同时,与组内同学一起孵化出开源框架 egg-react-ssr。2020 年到淘宝技术部,开启前端智能化的旅程,目前负责 P2C,和卓风是搭档。 卓风,入职阿里的八年时间,主要是在淘宝负责天猫、聚划算大促及日常营销业务产品的落地,曾负责面向天猫、淘宝、聚划算等商家的搭建产品建设和淘系智能 UI 体系建设和业务落地,相关产品和体系已陆续在向集团落地。近 1 年投身到前端智能化领域,致力于 Service to Code 体系建设,推动服务端智能出码的落地,目前相关体系具备一定雏形,在团队内业务范围进行闭环试验。 Q1:双嘉宾的分工 有 2 位嘉宾共同演讲,你们的分工是怎样的? 2 个人一起演讲是因为在 P2C 过程中,需要由多个部分组成,而这些组成部分分别由狼叔和卓风负责,二人以交互式的演进方式,一是希望降低理解成本,二是 D2 大会也希望能有一些新的创新形式。二位嘉宾都是爱说爱笑的,应该会大家呈现一场不一样感受的分享,非常值得期待。 Q2:P2C 的定位:需求即代码 P2C 是什么?这个事儿好像业界第一次听说,真的有用吗? 在前端智能化的探索过程中,甄子提出了 P2C,即 PRD to Code。站在整个研发链路上,集合现有优势,做到需求即代码的这个最终目标。通过我们近一年的探索,证实这套方案在频道业务上是可以落地的。 我们需要了解 PD 的痛点。 PD 的目标是什么? PD 要做什么?是频道,页面,模块,会场,还是啥? PD 要将做的东西投放到哪里,典型的业务场景有哪些? OKR 的核心目标分解和关键结果。围绕目标进行拆解,并及时反馈,所以 OKR 才被认为是一种高效的协作方式。那么 PD 围绕的业务目标是什么?PD 出的需求方案是否有传承或复用?PD 是否能够更简单的工作,降低沟通成本,省出时间,做更多商业模式上的创新?这是一张核心的 P2C 大图。P2C 的最终目标是需求即代码,其中 2 个拆解目标分别如下。 1)让 PD 能够做 0 标注,找到标注过程中样本。 2)让开发做到 0 投入,在 AI 和逻辑点提高出码准确率。 这 2 个核心目标论证是可行的,P2C 背后设计的技术体系也非常庞大的,从业务能力接入到研发能力到商业化、 Pipcook 基建等分层上,其复杂度也是可想而知的。这里面还有很大的探索空间。未来针对于流量场,是否有定式?能否成为商业 OS,也是非常值得期待的。里面有D2C、S2C、P2C、C2C 等这些概念,先不细讲,留在分享中。 Q3:爆料“以图搜图”黑科技 P2C 有什么可提前爆料的黑科技没? 这里先放一个以图搜图,一个极小但非常实用的功能。从图片或设计稿出码,大家见得多了,那么能不能通过相似性来快速生成呢? P2C 站在 PD 的视角,已经解决了很多问题。我举个例子,以图搜图是 P2C 的一个工具功能。大家只要有图就能搜索到对应模块。搜到模块,就能找到对应的开发者,对应业务来说是很方便的。这还只是工具。假设你去截任意活动的一张页面图片,假定你的模块库里有相似模块,通过以图搜图可以直接生成具体页面,是不是很酷?PD 如果想仿制,贴一个竞品页面地址就搞定了,它可以让前端打开无数想象。放这个目的是为了让大家能够有点体感,即使是很小的一个功能也能解决很多问题。 但是,挖掘 PD 脑子中的业务逻辑,做需求即代码,需求即生成,这才是更高级的做法,具体 P2C 方案会在第十五届 D2 前端技术论坛(12月19日)上做分享《前端智能化实践:P2C 从需求文档生成代码》。 Q4:P2C vs D2C,为什么做 P2C ? P2C 和之前的 Imgcook 主张的 D2C(Design to Code)有啥差别?同一个团队,这 2 个概念之间是颠覆还是继承关系? Imgcook 是目前业内最好的利用 D2C(Design to Code,即设计稿出码)能力智能出码的工具,它使用计算机视觉、深度学习等智能化手段,可以一键根据设计稿进行代码生成。 2019 年 Imgcook 借助核心的 D2C(Design to Code,即设计稿出码) 能力,将模块智能出码水平提升到 79%,而分析发现未能智能出码的部分均是从视觉稿中获取不到代码信息的,比如多态逻辑、交互逻辑、数据服务逻辑,需要借助分析 PD(产品经理) 的原始 PRD(产品需求文档)才能获取到这部分代码信息,于是提出了 P2C(PRD to Code) 概念,希望通过 PRD、视觉稿(Design)结合的方式,来进一步提升出码水平。本次分享通过详细讲解 P2C 的整个探索和产研过程,希望为大家在前端智能化领域的开拓创新起到一个参考。 今年双十一会场承接了 90.4% 的新模块代码智能生成,代码可用率达到 79.26%(对比去年升级设计稿智能检查能力,视觉稿无需人工辅助调整)。得益于 D2C 的研发提效,今年并没有出现往年借调资源投入会场开发的情况。相比传统模块开发模式,使用设计稿生成代码技术后编码效率(模块复杂度和研发耗时比值)提升 68%,固定人力单位时间模块需求吞吐量增加约 1.5 倍。最新文档请查收: 使用 Imgcook 开发天马模块:https://www.imgcook.com/docs?slug=tianmAImgcook.private 使用 Imgcook 开发天马组件:https://www.imgcook.com/docs?slug=tianma-component.private 使用 Imgcook 生成无障碍属性:https://www.imgcook.com/docs?slug=accessible.private 使用 Imgcook 支持自定义组件:https://www.imgcook.com/docs?slug=comp-to-code 更多请查看官方文档:https://www.imgcook.com/tutorial 从研发效率上看,Imgcook 已经做得非常好了。它是提效,不是无开发。这点是需要注意的。AI 是要用机器替代人工,否则 AI 是做得不够的。 本身 D2C 解决的是设计师和开发者之间的提效。能够让 AI 通过设计稿生成代码,这是减少了开发者的工作量。但有很多业务逻辑其实是在 PD 脑子里的,如果想让需求快速交付,就需要站到整个研发链路上看,从需求到生成代码,能否缩短交付时间,甚至是需求即代码? 从纯前端的角度讲,单一角色确实很难解决这个问题。我们可以看到前端智能化是 AI 和前端的融合,在全链路的思考里,是融合多个职能角色的。在做 D2C 的时候,甄子团队整合了 AI 和前端,在做智能 UI 的时候,甄子团队整合了算法,在做设计系统的时候,甄子招了设计,在做 AI 基建时,甄子招了知名大佬 Yorkie。目前整个团队横跨多个角色,是最适合做这种创新型探索项目的。 Q5:狼叔因何“出圈”? 狼叔之前一直活跃于 Node/Serverless 社区,现在转战前端智能化领域,是什么原因?有怎样的思考?能行么? 在今天,Node/Serverless 已经不能不放到一起谈了。Node.js 在十一年的稳定增长后,已经变成了主流选择。所有云计算厂商都爱 Node.js,也就导致在 Serverless 大潮中,Node.js 依然是宠儿。我们能看到的是语言慢慢的被基建取代,已不再有往日的重要地位,并且 Serverless 端渲染等新生物,解决实际问题,但这部分其实已经划归了基础架构组来做。它能够拿到成绩,未来几年也会持续落地和增长。 对狼叔而言,开源 ykfe/egg-react-ssr 和 ykfe/ssr,已经完成了 Serverless 端渲染相关的探索,他需要更多的探索空间,这时候选择前端智能化也是必然的。AI 目前能够解决的问题确实是有限的,广义问题确实不适合 AI 来接,但针对特定场景,具备特征和 Pattern 的是可以替代人工的。从目前的实践来看,确实也是做到了的。 到前端智能化团队,狼叔最大的挑战有 2 个,1)掌握 AI 能做什么,2)站在产研链路上去看待 P2C。这其实是很有挑战的,之前做的事儿无非是提效,搞来搞去还是前端的某一个领域,做深或做广。今天要跨角色去思考提效,这个事儿对格局要求明显是很高的,这其实才是最吸引狼叔的点。 狼叔表示,虽然一把年纪,但还是能够坚持学习,在一个多样化的团队里,跟不同职位的小伙伴们一起成长,一起创造、探索,是非常快乐的事儿。不确定一定能够颠覆什么,但折腾的过程一定是值得享受的,对每个人的成长都是极为有利的。预告一下,《狼书(卷3):Node.js 高级技术》预计年前可以出版,今年5 月份已交付,已经在走出版流程。 关于前端智能化,狼叔曾说过:”面对未知我们太弱了,是思维方式的束缚,是事推事的磨砺,是无比强大的内心。能看出趋势很难,能找对方法很难,能带着一群人去疯狂更难。方向对了,还怕路远吗?“ 最后,狼说和卓风说要致敬前端智能化的领路人,前端世界摸爬滚打 20 年,最早的腾讯 3-3,创过业当过CEO/CTO,到今天成为行业(前端智能化)领导者和开拓者。他就是了不起的甄焱鲲(花名:甄子)。 欢迎大家来观看第十五届D2前端技术论坛,来听狼叔和卓风的分享,一起来领略前端智能化的无限可能。 关注「Alibaba F2E」把握阿里巴巴前端新动向

作者 | 秦粤 点击查看视频 大家好,我是秦粤。阿里巴巴自从2019年加入Ecma后,我们就在Ecma中积极参与推进,决定JavaScript语言发展未来的各种议题,阿里巴巴的议题Error Cause也已经成功的推进到Stage 2。今年在阿里内部由前端委员会牵头也成立了阿里巴巴前端标准化小组,用组织架构保障阿里前端,持续在影响前端生态未来的标准规范上发力。 与此同时我们也特别关注到TC39成员中,不少成员都在关注和推进JavaScript中函数式编程的体验。作为今年D2语言框架会场的出品人,因此我们邀请了RxJS的团队负责人Ben,引入JavaScript函数式编程的议题。另外,今年Ecma组织的大事件ES2020已经发布,我们也将继续邀请TC39的成员Ujjwal,讲解其中有哪些特性值得我们前端同学关注以及这些议题的诞生过程。 函数式编程 in Javascript 函数式编程的思想从1930年提出来已经过去很久了,但大多数工程师使用的场景并不多。函数式编程在JavaScript中几乎是天然就支持的,Brendan Eich参考的语言中包括了函数式编程语言Lisp,因此JavaScript有了函数是一等公民和闭包的概念。 我们大学学习的离散数学,线性代数等等课程,都很容易让我们习惯面向指令编程。我们的代码习惯性都是从上到下,从左到右,加上控制指令block的方式。 ES5之前,如果我们学习了面向原型,会在我们的代码中采用prototype。 ES6和TS后,如果我们学习了面向对象,代码中又会加上Class抽象。 但某种程度而言,这些代码方式都是面向机器友好的。函数式编程是否可以带来一些改变呢? 我自己使用函数式编程的感受是,在面对每个要开发的功能,就像在解数学题。首要是思考数据加工过程如何拆解,初期要不停查工具,看看有哪些函数方法可以给我使用。后期熟练后,会开始用函数式注释,毕竟长时间不看自己原先的代码,同样会忘记。而且不会采用一逗(句号)到底的方式,分段一下。 函数式编程的基础概念,我在此就不啰嗦了。它们是:范畴论,函数一等公民,纯函数,组合,柯里化,等等。 感兴趣的同学可以学习一下:https://mostly-adequate.gitbooks.io/mostly-adequate-guide/content/。 "show me the code",我们来看看具体例子:调用后台API返回了一个数组,其中我们需要对商品的金额进行汇率运算,转换成用户本地的汇率显示。 success: true, data: { 'name': 'ProductsDetail', 'list': [ name:'T shirt', price:'10.00', unit:'$' name:'T shirt with logo', price:'15.00', unit:'$' name:'T shirt with brand logo', price:'20.00', unit:'$' userCurrency: '¥', userCurrencyRate: '6.5', 通常,我们会直接写一个循环,或者用UnderscoreJS这样的库将price获取到转化成数字,然后乘以userCurrencyRate。 我们不妨看看函数式的做法,先从简单的函数拆解来看。例如我们乘法函数,我们通常会这样写: const multiply = function(x,y) { return x * y; multiply(3, 5);// 15 而当我们想复用乘法函数,例如固定乘3的函数。我们可以采用JS高级编程的柯里化Currying。 先复习一下柯里化Currying:一个函数将返回一个新的函数,直到接收所有参数。我们用Vanilla JS可以写成: const multiply = function(x) { return function(y) { return x * y; const multiply3 = multiply(3); multiply3(5);// 15 不过这样还有一些不方便,Curry函数这些的写法,我们想用multiply函数multiply(3,5)又不可以了。JS高级编程常见的面试题之一,就是autoCurry,顾名思义根据参数判断函数如何返回。有兴趣的同学可以自己挑战一下实现autoCurry函数,这里我们就直接采用RamdaJS的curry方法。 const R = require('ramda'); const multiply = function(x, y) { return x * y; const multiplyAutoCurry = R.curry(multiply); multiplyAutoCurry(3)(5);// 15 multiplyAutoCurry(3, 5);// 15 有了Curry函数,对于数组我们可以使用map函数,将函数应用到每一项。 const R = require('ramda'); const multiply = function (x, y) { return x * y; const multiplyAutoCurry = R.curry(multiply); const multiply3 = multiplyAutoCurry(3); R.map(multiply3, [1, 2, 3]);// [3, 6, 9] 因此函数式编程的版本实现,我们就可以写成: const R = require('ramda'); const multiply = function (x, y) { return x * y; const multiplyAutoCurry = R.curry(multiply); const multiplyCurrency = multiplyAutoCurry(6.5); const parseIntCurry = R.curry(parseInt); const parseInt10 = parseIntCurry(R.__, 10); const currencyConvert = R.compose(multiplyCurrency, parseInt10); const result = { success: true, data: { name: 'ProductsDetail', list: [ name: 'T shirt', price: '10.00', unit: '$' name: 'T shirt with logo', price: '15.00', unit: '$' name: 'T shirt with brand logo', price: '20.00', unit: '$' const priceArray = R.pluck('price', R.prop('list', R.prop('data', result)));// ['10.00', '15.00', '20.00'] R.map(currencyConvert, priceArray);// [ 65, 97.5, 130 ] 由于API返回的结果中price是字符串,为了消除不确定性,我们需要先将price转为数字。这里我们可以用parsefloat,为了演示如何将build-in函数转化成函数式,我选择了parseInt,通过第二个参数传入10解决低版本浏览器兼容性问题。 R.compose是将2个方法组合使用,执行顺序是从右到左。然后我们只需要将我们组合好的工厂函数应用到获取到的价格数组上就行了。 D2 语言框架专场 大家可以发现,我们整个运算过程只使用一次元数据result,这也就是“无副作用”。另外我们将整个过程都转化成了数学解题,而不是让自己像计算机一样思考。前端同学们熟悉的React库也在使用函数式编程的思想,例如单向数据流,State要求immutable。 对于数组和数据流的操作,特别适合函数式操作。ReactiveX就是将数据看成是函数式流处理,因此抽象出Observable, Observer, Subscription等等概念。 import { fromEvent } from 'rxjs'; import { throttleTime, scan } from 'rxjs/operators'; fromEvent(document, 'click') .pipe( throttleTime(1000), scan(count => count + 1, 0) .subscribe(count => console.log(`Clicked ${count} times`)); 今年D2的语言与框架专场邀请了RxJS:Reactive Extensions For JavaScript团队负责人Ben Lesh,讲解如何利用JS特性重构RxJS,让代码更小更快。 另外函数式在TC39中,也是大厂专家积极讨论的对象,如何优化JS中写函数式的体验,相关议题有: https://github.com/tc39/proposal-pipeline-operator https://github.com/tc39/proposal-partial-application https://github.com/tc39/proposal-pattern-matching https://github.com/tc39/proposal-record-tuple 同时我们也邀请了Igalia的TC成员Ujjwal,为我们讲解ES2020和ES2021都有哪些可以提升我们JS开发体验的新特性,以及这些特性是如何从TC39中诞生的,我们如何决定影响JS语言的未来。 函数式编程也不是银弹,但在适用的场景,非常好用。大家无妨给自己的工具箱多装备一个函数式编程的工具。我在今年的D2大会语言与框架专场等你。 参考文献: https://mostly-adequate.gitbooks.io/mostly-adequate-guide/content/ Hey Underscore, You're Doing It Wrong!: https://www.youtube.com/watch?v=m3svKOdZijA JavaScript函数式编程: https://github.com/doodlewind/jshistory-cn/blob/master/part-1.md https://mostly-adequate.gitbooks.io/mostly-adequate-guide/content/ 关注「Alibaba F2E」把握阿里巴巴前端新动向

我在阿里巴巴做 Serverless 云研发平台

作者 | 林昱(苏河) 技术的成熟度源自大规模的实践,在 Java 领域,阿里将自身的实践源源不断的反哺给微服务技术体系;在 Node.js 领域,阿里正掀起了前所未有的前端革命浪潮,将实践反哺给 Serverless 技术体系,并逐渐拓展到其他多语言体系和后端 BaaS上。 Serverless 云研发平台作为阿里巴巴集团前端委员会发起的一体化云研发平台,底层基于函数计算 FC,是整个 Node Serverless 体系中的研发入口,承接了淘宝、飞猪、ICBU、考拉、高德、文娱等研发、交付和运维工作。目前,集团已经有上千位前端和客户端的工程师使用 Serverless 云研发平台进行业务的开发工作,包括但不限于营销导购、中后台、行业前台等规模化场景。 从今年双 11 整体的大盘数据来看, 仅淘系 Node Serverless 的支撑流量就已经从去年的 2K QPS 峰值增加到今年的 30K QPS 峰值,峰值流量增加了近15倍,集团整体更加是从近 5.8K QPS 到达今年的 50K QPS峰值。 解决方案上,我们定制了面向更多场景的能力,包括考拉 Dart 解决方案的落地,以及一些面向导购的模型驱动解决方案;运维上,我们优化了大促态和日常态流程,让开发者在应对更高 QPS 规模时,精力花费降低至少 50%;在研发体验侧,打造解决方案体系,降低研发门槛,支持前端快速入场,提升研发效率 39%;在底层 Serverless 基座上,我们适配了多个 Serverless 平台,支持多平台的实时切换,以应对单一平台的不确定性。 本文将介绍 Serverless 云研发平台是通过提供哪些能力保障各租户业务的快速开发和安全交付的。 研发的本质 大家可能都在「人员协同、服务可靠性」上支付着高额的人力成本,但研发的本质是交付「业务功能」。今天,我们从传统的「前端开发者」慢慢走向「应用研发者」,摸爬滚打不容易,除了需要去思考「什么是真正的按需付费」、「弹性」等底层运维相关的命题之外,还需要去考虑「研发效能」相关命题,这也是为什么有更高效的协同模式、组织关系的变化,甚至整个前后端协同的生产关系都在发生变化的原因,今天我们谈「云端一体」,本质是从用户的视角去思考问题,用更高效的方式去解决业务问题。 如今,软件开发对于成本的控制要求越来越高,单位时间的产能会慢慢成为衡量一个团队是否高效的标准。 因此从研发的本质,我们来看看 Serverless 云研发平台要解决的命题: 让业务开发变轻,聚焦业务逻辑; 让业务开发变快,提升产研效率; 让基础设施变厚,提升稳定性。 图为 Serverless 云研发平台架构图 Serverless 方案定制能力来完善云端一体研发者市场,提供开发者更多选择、打造云端一体的研发集成闭环来提供业务更快的交付速度、以及业务低成本的使用基础 BaaS 服务能力以及业务 BaaS 成为研发平台的核心抓手。 Serverless 研发平台 Serverless 业务解决方案 我们定义的解决方案 :即解决某一横向或纵向领域的,贯穿创建、研发、交付、运维阶段的一系列能力的集合。为什么当时需要定义解决方案的定制能力,核心原因是面向今天云端一体化的场景,不同事业部的业务同学有着不同的定制需求。我们调研了几个事业部,包含 AE 、考拉、淘系等,起初的 Serverless 云研发平台的定制开发能力偏弱,无法很好的承接业务诉求,我们需要让平台有一定的开放定制能力,例如淘系面向研发面板的 low code 的定制能力,考拉面向函数的资损风险等级和应用风险等级录入等需求。 但是开放能力会涉及创建、研发、交付、运维这几个阶段,每个过程能提供什么定制能力、开放到什么程度是要由平台根据收集到的需求和平台自身管控要求去综合考虑的,所谓「人挪活,树挪死」,结构化了几个关键能力之后 Serverless 云研发平台开放解决方案的定制能力在当时多个租户的调研下产生了。 上图为结构化几个可定制节点以及多个场景的调研情况 通过上图结构化的信息,我们定义了解决方案元数据相关信息,示例为中后台一体化解决方案相关元数据信息。 "name": "ICE-FaaS", "display_name": "Web 端一体化", "description": "传统 Web 一体化解决方案,解决中后台开发需求(ICE、React等),同时支撑中后台前端页面和 FaaS 的研发", "owner": "*", "generator": { "id": 30 "depserver": [], "page": {}, "widget": {}, "baas": {}, "ide_plugin": ["midway-helper"], "checkConfig": { "cf": true, "cr": true, "fone": true "flow": { "id": 1 "ops": { "resource": [{ "type": "faas" "type": "assets" 截止目前,Serverless 云研发平台通过共建一共沉淀了 14 个解决方案,包括 5 个通用解决方案和 9 个面向不同租户的定制化解决方案。 接下去介绍 3 个典型的解决方案。 一体化解决方案 一体化应用解决方案是基于 Midway Hooks 提供的上层业务云端一体解决方案,借助 Serverless + Hooks + “零” API 调用的特性,开发者在研发流程中仅需关注业务逻辑,即可高效完成应用的交付。 一体化应用在使用时,具有诸多的优势: 易于开发,前后端同仓库,无缝融合一体开发 易于部署,前后端一同发布与部署 易于维护,后端代码使用Serverless 部署,运维难度低 而在开发时,我们也提供了诸多的功能来帮助开发者加速研发。 “零 API 调用” Hooks 支持 在阿里内部,我们提供了中后台一体化与搭建模块一体化两种解决方案。其中,中后台一体化应用在内部已经落地了 300+ 应用,快速且高效的支撑了各个 BU 的中后台需求。 淘系模型驱动解决方案 模型驱动是淘宝导购业务开发过程中沉淀的一种开发方式,面向导购大量的召回补全展现需求。通过配置面板,将模型、数据来源、插件配置组合,最终生成业务逻辑代码,供业务消费。整个操作面板的核心关注点在右侧的流程画布上,我们希望使用固定的流程来解决这一类业务问题,这些逻辑遵从预定义的操作路径。在云市场轻应用外包介入开发的模式中,由内部同学生成物料,外包同学开发模块和选择业务字段并串联流程,帮助内部同学节省了大量流程串联和模块联调成本,相比传统的开发方式整体提效10%左右。这也是一种创新的协同模式,物料丰富后会有更大的提升空间。 数据源(召回) --> 模型(补全) --> 扩展逻辑(插件) 模型驱动解决方案在淘宝很好的解决了业务问题,但是面临更多的场景需要的是更加灵活的模板定制能力 考拉 Dart 一体化解决方案 考拉大前端自 2020 年 3 月份开始尝试 Flutter 的应用,部分客户端和前端同学均参与进 Flutter 的开发,对于 Dart 相对熟悉,所以 Dart 一体化解决方案最初目的主要是考虑帮客户端同学解决开发提效的问题。考拉之前主要在使 Node.js Runtime 的 Serverless 方案,相比于 Java Script,Dart 对于客户端同学也更友好一些,同时也不断有客户端同学提出 Dart Serverless 的诉求。 在函数计算 FC 研发团队的帮助下,考拉基于 Dart Runtime 的前期测试版本,快速完成了考拉 App 今日活动 Tab 的改造重构,并已于 9 月底灰度上线。10 月中下旬,基于 Dart Runtime 开始和 DEF 平台对接,最终 DEF Serverless 创建面板,会透出 Dart 纯函数解决方案,目前和 FC 侧基本流程已调通,即将上线 Dart 的纯函数解决方案。除了已上线的 Dart Ast 生成服务,考拉将基于 Dart Serverless 方案推出更多的业务场景,如 App 端数据模型的动态下发、业务逻辑的动态配置、Flutter 动态化尝试,以及 App 跨端搭建能力等。 除了以上 3 个解决方案,ICBU 团队研发的 EaaS 微应用级别的解决方案,天猫行业团队研发的面向轻店场景的原生小程序一体化 解决方案等,这里不展开一一介绍了。 函数稳定性保障 最开始的时候,我们关注的重点是如何用 Node 完成业务逻辑,比如数据怎么组织、 Java 二方包怎么调用、怎么结合阿拉丁链路、线上 bug 怎么快速修复。现在有了这么多线上运行的业务,我们关注的重点已经从怎么完成业务需求,转变成如何高效地、稳定地完成业务需求。 线上稳定性,本质上是对问题的治理。从问题出发,可以分为以下几个主要环节:预防问题、发现问题、定位问题和解决问题。在预防问题上,要尽可能降低问题发生的概率和缩小影响面,做好上线卡口,以及做好对应的预案。发现问题上要尽可能实现全链路监控,以及实现合理有效的报警分发机制。定位问题上,要尽可能缩短问题的定位时间,在报警元信息的基础上,做一些机器的辅助分析,关联上下文,从而做到半自动定位或提供更多有逻辑的上下文,来缩短人为定位问题的时间。在解决问题上,要保证解决方案的有效,安全以及快速。 大促稳定性保障手段 大促场景下, C 端场景需要重保,以下的稳定性保障手段经历数次大促压测,同时越是大促态,整个稳定性保障也愈发紧张。稳定性是保障了,但是在之前我们是对照上述的文档完成上线流程的,流程冗长无比,最终并沉淀成一个作战手册,同时这些内容无法和应用关联,离散在文档角落,整个过程「又臭又长」。 上线流程 -> 作战手册一体化 因此,Serverless 研发平台上希望规范化整个流程,从从 强弱依赖梳理 -> 预案配置 -> 监控报警订阅 -> 单链路压测 -> 作战手册生成,记录所有函数上线过程,流程可追溯,文档可沉淀;另外预案、压测、监控等流程做到半自动化,减少上线时间。我们将每个流程节点定义成一个 SOP 单元,这样根据业务特性可以进行 SOP 流程的随意组装。 发布SOP流程 通过半自动化流程生产的作战手册,函数和作战手册关联的硬盘化记录方式,并结合自动限流和下游依赖分析以及预案生产,例如:通过预发流量录制的回放,自动分析出函数下游的强弱依赖,并录入强依赖负责人,方便出现线上问题的时候可以第一时间找到负责人排查问题;根据不同租户对单元化的需求,平台可以帮助用户进行多机房、多单元部署实现异地多活。这些都能够让业务的大促态变得更轻松一些。 淘系业务作战手册 专家应急响应 为解决线上问题定位慢的痛点,平台还提供了应急响应系统,当函数成功率降低触发报警时,平台会自动拉取函数以及下游多项数据信息,进行错误分析,快速产出错误报告推送给函数开发者。并引导开发者回到研发平台进行切流、执行预案等止血操作。例如,下游服务强依赖服务A成功率下降,导致函数自身成功率下降,需要联系服务A负责同学。 平台上的每个租户都有对应的租户管理员,对各自租户的函数稳定性负责,包括租户下函数的单元化部署规则、大促管控、自建网关配置、容器额度、租户私有解决方案等,为此平台提供了一系列运维工具。 帮助管理员更好的观测到租户下函数的服务质量,和容器额度使用状况,提供函数错误率和 RT 黑榜,并且每周都会有治理周报推送给管理员,帮助其更好的进行运维其租户下的函数。 帮助管理员细致的观测每个函数线上运行的具体状态,包括函数线上存在的版本、容器数量、 Runtime 版本、灰度、单元部署状况,甚至可以观测到函数部署是否均衡。 平台还提供针对大促态的运维管控能力,管理员可以将租户下参与大促的函数服务一键切换到大促态,进行大促态的额外配置,比如大促容量配置,Broker 侧限流,网关侧统一监控预案等能力,保障大促的稳定。 Serverless 云研发平台后续将在提升用户正向和逆向流程的效率上继续演进,L1 是希望让用户低成本的上手,L2 是希望让用户低成本的进行研发,让前端往应用研发更进一步。以下是基于用户正向研发链路耗时统计的一些分析: 技术方案产出的时间较久,占比整体研发周期 5%,核心原因是服务物料难以检索以及服务可用性难以评估,领域模型沉淀不足; FaaS 整体研发占比 25%~30% ;模型驱动等可视化编排在物料准备完备的情况下,能够提效,但是不具备规模化场景; 联调耗时较久占整体成本 20% 左右,过度依赖预发环境,据统计,完成一个项目需要部署 50 次; 压测成本依然存在,平台熟悉成本过高。 当然还有监控运维逆向链路的一些分析: 报警分发不准确,因现在无法区分报警是底层框架和上层业务的问题,所以往往需要架构组和业务同学的共同介入; 定位问题效率低,如失败率报警,可能是底层架构的问题也有可能是下游的问题,还有可能是机房或者自身的问题,往往需要去多个平台逐一排查; 缺乏对服务质量的统计或整体认知; 缺乏能针对 80% 线上问题的排查和解决的标准化流程,依赖用户对问题的定位和解决能力。 Serverless 云研发平台经过这半年多的蜕变,已经从简单的解决工程链路的平台演进成一个面向研发、上线、运维的全生命周期研发平台,后续要解决的命题会集中在用户低门槛上。 希望我们在 Serverless 上的实践和探索,能给业内其他公司带去一些启发,让路上的障碍变少,让应用的研发变轻。 欢迎关注第十五届D2前端技术论坛 一起来 Node.js(Serverless) 专场学习更多精彩内容 双促实践 - 打造更稳定的 Serverless 业务陈仲寅(张挺) / 阿里巴巴高级前端技术专家 在过去的一年,阿里集团内部 Serverless 业务以数倍的增速落地,在这其中,Node.js 架构组承担了数倍的压力,不仅要面对双促的的业务落地和稳定性压力,也要面对集团多云环境复杂的部署架构。如今,大促结束,Serverless 稳定性也在业务得以验证,希望分享在云原生时代,如何围绕其进行研发效率与成本优化红利,以及在大促压力之中,作为今年的云+端 2.0 方案的业务承接者,如何围绕下一代框架、下一代架构、高可用体系等领域,让前端增效,业务获利。此次演讲将分享阿里集团的Serverless双促稳定性保障经验。 SSR 在双十一会场的落地实战邓宏才(霸剑) / 阿里巴巴前端技术专家 会场是每年双十一的主角之一,会场的用户体验自然也是每年最关注的点。在今年双十一,我们基于 Serverless 基建将 SSR 带到了会场,将首屏秒可见率提高到了新的高度(82.6%)。本次分享为大家带来 SSR 在重要且复杂的业务场景落地时的前期思考、遇到的问题以及稳定性保障的方法论,希望能让大家在业务落地 SSR 时有更多的思路和信心。 Node.js - What's nextMichael Dawson / Node.js 技术委员会(TSC)主席、Red Hat 和 IBM 的 Node.js 方向负责人 想要了解 Node.js 接下来会有什么样的发展吗?如新特性?重要更新?亦或者技术上乃至组织上的关键举措?Node.js 技术委员会主席将会为你带来 Node.js 前沿进展报告。 Serverless 在前端部署领域的实践凌艺宾 / 字节跳动头条号业务前端负责人 字节内部为前端实现了一套 Serverless 部署架构,可以便捷地实现普通页面部署、微前端应用部署、SSR 部署以及 BFF 部署,目前接入项目已经有 4000+,CSR 日访问量 2 亿+/QPS 3000+,最高支撑过 1W+ QPS 的活动,SSR QPS 最高 4000+。本专题为 Serverless 在前端部署方面的应用带来一些新的思考和方案,希望能给大家带来一些新的思路。 高密度部署实践顾珠彬(零弌) / 蚂蚁集团前端技术专家 传统基于容器应用存在资源利用率低,运维成本高的问题,在蚂蚁的 serverless 过程中发现如果基于容器这些问题无法绕开。本次分享主要介绍在蚂蚁通过高密度部署的方式,带来一种对于应用开发者 0 运维成本的研发体验。 关注「Alibaba F2E」把握阿里巴巴前端新动向

盒马中后台跨端方案探索

作者 | 孙伟伟(景庄) 随着云计算和无线网络等基础设施的成熟,移动设备呈现爆发式增长,越来越多的企业级产品开始拥抱多平台设计,移动化办公概念已深入人心。华为发布了基于微内核的全场景分布式 OS -- 鸿蒙,期望打造以人为核心,万物互联的流畅体验,让用户在不同的场景设备中自如切换。苹果早在 iOS 8 上便发布了 Hand-Off 功能,支持用户在任意的苹果设备间实现跨设备的任务协同和无缝体验。SaaS 软件巨头 SAP 也早已在其全线的 SaaS 产品中提供了跨平台和移动办公的支持,用户不再受限于传统的办公室场景,而是可以实现任意时间和任意地点的便捷工作。 盒马中后台体验边界的延展 同样,在实体零售数字化的大背景下,盒马尝试对人货场进行全新的数字化重构。在消费者端,为用户提供精准的人货匹配与全新的消费体验;在作业者端,通过构建全新的数字化流程,为用户提供简单高效一致的作业体验。在这种新型的数字化关系下,作业形态和作业场景更加多元化,不再受制于特定的时间与地点,作业者可以借助多类型的智能设备来完成作业任务。因此,对于盒马体验技术团队而言,我们需要重新思考和定义中后台的体验边界。 图:盒马门店智能设备网络 在盒马,不同于传统的中后台场景,场的载体更加多样化,不只是传统的办公室场景,还包括门店,仓库,配送站,甚至是移动中的卡车与电瓶车;这其中的作业者角色也更为多元化,例如总部管理职能部门,门店经营职能部门,仓储作业部门,配送作业部门等等;场与人的多样性下,是多样化的作业设备来达成各类的作业意图。 图:盒马多元化中后台场景与多端工作台 盒马的各类职能人员通过盒马的多端工作台来完成各项工作,因此整个盒马工作台就是一个庞大的新零售操作系统,面向不同的角色提供不同的能力,例如仓储管理,物流管理,CRM,财务,ERP,EHR等等。在各类作业场景下,不同的作业人员可以借助不同的作业设备访问到特定的能力,例如在门店经营作业中,小二可以通过 PC 查看经营报表,使用手机获取消息,使用平板电脑管理餐饮档口,使用扫码枪进行拣货作业,并且各项作业任务通常还会联动各类的打印设备,IOT 设备等等。 围绕盒马的多端工作台,体验技术团队需要做的就是让各类作业角色在合适的设备中,以合适的方式,简单高效一致的完成合适的任务。 盒马中后台场景下的跨端体验挑战 大致梳理下盒马中后台的研发现状。总部管理、门店营运、仓储作业等角色需要通过盒马工作台完成各类作业任务;用户通过PC、Pad、Phone 等多种类型的设备访问到工作台的能力来完成特定的任务,例如通过桌面电脑访问各类报表和专项任务,通过手机查看消息和执行审批,通过掌中宝 Pad 进行门店的营运管理,通过扫码枪 RF 执行拣货作业;同时,作业任务的跨端协同需求也较为常见,同一个任务通常需要依赖多个设备协同完成。 图:盒马中后台研发现状概览 针对多端研发场景,一方面我们需要面向不同的设备提供跨端内容交付,另一方面,还需要构建面向不同角色和场景的多端体验基础设施,从而去改善和提升不同作业者在不同场景下使用不同设备的作业效率与体验问题。 盒马中后台跨端体验解决方案 面向盒马的中后台多端体验场景,我们构建了一套完整的跨端体验解决方案。该产品涵盖了从设计系统,跨端组件,跨端应用,到多端容器,工程基建,多端体验大脑,消息中心,状态同步中心等一系列的工具和服务,是一套服务盒马中后台研发场景的全场景解决方案。 图:盒马中后台跨端体验解决方案构成大图 下文将将会具体介绍我们在该产品构建过程中对于跨端设计系统,跨端组件,跨端应用方面的思考和方案。具体包括: 如何通过统一的设计系统来支持差异化的作业场景和作业设备 如何通过一套组件架构支持不同作业端的跨端复用 如何通过一套应用架构支持不同作业端的跨端使用和跨端联动 全场景跨端设计系统 针对多类型的设备,传统的做法是面向单一的设备提供设计系统并构建对应的交付能力,例如 PC 有独立的设计规范和组件体系,Phone 有独立的设计规范和组件体系。这种做法虽然有效,但随着设备类型的增加,面向单一设备提供交付能力的方案会带来设计体系的分裂与开发投入的大幅增高,并且用户在跨设备的作业任务中会产生较大的体验割裂感。为此,建立多端统一的设计体系有助于设计和开发团队快速响应端的变化,为作业者提供一致的作业体验。 构建设计系统的过程本身并不复杂,但在复杂的 B 类作业场景,如果要提供一套多端可用的设计系统,就需要更进一步的考虑到具体的作业环境和作业类型的差异,例如在办公室中和门店档口中,环境的光线和湿度会对屏幕内容产生影响,另一方面用户的交互姿势不同也会对屏幕内容产生影响;再比如在盒马的配送站中,配送员需要通过悬挂的叫号屏获取任务信息,但不同的空间布局和光线环境会导致不同配送站的信息获取效率的差异,此时屏幕内容展示就需要响应这种空间布局和光线导致的内容展示差异。 图:盒马的多样化作业场景与多样化作业类型 我们认为跨端设计系统需要考虑到作业场景下影响作业者体验的具体环境因素。对其中可能会影响到用户体验的环境因素我们大体可以分类为: 设备类型差异:屏幕尺寸、使用视距、屏幕比例、交互方式、硬件能力等。 作业类型差异:风格传达、情感传达、反馈模式、色彩模式等。 作业环境差异:光照、声音、湿度等。 系统类型差异:信息密度、产品风格、操作风格、横竖屏等。 图:盒马全场景多端设计系统 如果能够建立环境因子和设计系统之前的关联,那么我们就可以利用这些环境因子来计算设计系统中的各个子系统在具体环境下的取值,而不再仅仅依赖设计师的经验。在此基础上,我们就可以去构建整个多端设计系统中的各个子系统,例如色彩系统、字体系统、间距系统、尺寸系统、阴影层级等等。 图:基于环境变量计算 Design Token 的过程 为了能够更进一步的去验证和调整多端设计系统的 UI 逻辑,我们开发了一个基于环境因子的基础设计规则配置系统,用户可以基于给定的配置变量来生成 Design Token,例如设备类型、屏幕尺寸、使用视距、信息密度、动静状态、操作频率等等。 一套代码多端可用的跨端组件 与移动端跨端场景相比,中后台跨端场景需要面对的是更加复杂的设备类型,更大范围的屏幕尺寸范围,以及多种类型的操作系统,在设备能力上往往也相差甚远。为此,在构建了多端统一的设计系统的基础上,我们就需要面向多端场景提供统一的 UI 层解决方案。考虑到多类型的容器环境,我们采用了统一的 Web 方案提供一套代码,多端可用的解决方案。 针对盒马的中后台跨端场景,我们构建了一套全新的面向跨端场景的组件方案,主要包括: 灵活响应式的跨端视图层方案,提供响应式支持,Design Token 支持,原子化 CSS 支持 可复用的跨端行为层 Hooks 方案,提供跨端行为的 Hooks 封装 可复用的组件状态层 Hooks 方案,提供可跨组件复用的状态管理封装 我们以 Switch 组件为例,来看一个组件当需要解决跨端复用时该如何去拆分与实现。按照上述思路,我们认为一个组件整体上可以被拆分为三层,分别包括: 视图结构与样式层,用来定义组件的基本视图结构,并响应跨端的尺寸变化,色彩模式变化; 行为逻辑层,响应用户的交互行为,例如鼠标点击,键盘操作,手势操作等; 状态逻辑层,管理组件内部的状态,通常是多端一致的,不涉及到跨端的适配问题。 图:Switch 组件构成拆解 组件实现复杂度的根源在于我们通常会在同一份代码里耦合了这三层逻辑。尤其在中后台的跨端场景下,如果组件要同时支持多设备下视图和交互的变化,就有必要去深入的解耦这三层逻辑,并在此基础上去构建可复用可拼装的原子化跨端能力集。 图:新版跨端 Switch 组件的实现说明 可多端复用与跨端联动的应用架构 在应用层,我们通常会通过拼装组件来构建符合一定业务意图的用户界面,跨端场景下的应用,通常需要面临两种典型模式,应用的跨端运行,和应用状态的跨端联动。例如对于一个巡检任务单而言,通常需要既可以在 PC 端打开,也可以在 Phone 端打开,当执行具体的巡检任务时,拍照上传类的任务更适合在 Phone 端完成,而大表单填写则适合在 PC 上完成。此时,我们就需要应用层能够低成本的支持这种跨端联动的多设备协同能力。在这样的业务背景下,我们重新思考了跨端应用方案的设计。 一个业务如果有多端诉求,其差异往往是在视图层上,而其底层的业务数据模型基本是相同的。因此,整个应用就被拆分为 应用容器层、数据模型层、跨端视图层 三层。应用容器层借助统一容器 SDK 提供统一的 API;数据模型层包括统一的数据服务和数据模型,和 UI 层方案无关,并可以借助独立的云端持久化服务来实现应用状态的跨端持久化;跨端视图层则用来面向不同端提供差异化视图,得益于组件层的跨端能力,应用层默认可以做到多端可用,但也可以针对某些特定的业务诉求来实现差异化视图。 图:盒马跨端应用 App 架构概览(以门店巡检应用为例) 对门店巡检应用而言,借助于多端视图,巡检应用可以实现低成本的跨端视图适配,无需开发者进行任何是额外适配。对于跨设备的状态协同,得益于独立的可序列化的数据模型层,可以借助状态远程持久化服务实现应用层状态的跨端联动。 在这种分层架构下,模型层可以做到与具体的框架层方案无关,借助于应用状态的远程持久化服务,我们便可以建立同一应用在不同设备间保持状态的异地唤起与同步,从而在端与端之前建立桥梁,支持用户在不同设备间实现跨端联动。 最后,总结下盒马中后台跨端场景解决方案的探索过程。为了解决盒马在中后台场景的多端作业需求,并改善不同作业场景下的各类作业者的跨端作业体验和跨端联动体验,我们尝试在设计系统中融入环境变量,并构建统一的面向多类型的设备的统一的设计系统,来统一支持不同端的设计与开发。在组件层,我们通过全新的跨端组件架构,通过构建全新的视图层方案和原子化的组件行为和组件状态管理能力来实现原子化能力的复用,并解耦组件层的复杂度。在应用层,我们建立了统一的应用层分层范式,构建标准的数据模型层来实现跨端应用的基础数据模型和数据服务复用。 D2 分享预告 关于盒马中后台跨端方案的更进一步内容将会在 2020年12月19日举行的 D2 前端技术论坛中进行深入分享,欢迎大家关注第十五届 D2 前端技术论坛跨端技术专场,一起来交流。 关注「Alibaba F2E」把握阿里巴巴前端新动向

跨端浪潮下前端开发者的机遇与挑战

作者 | 曹阳(染陌) 跨端一直都是一个前端开发者绕不开的话题,无论是基于研发效率的考量还是从业务场景的需求出发,跨端都是一个“刚需”。从最早的 PC 时代到移动时代,从移动时代到 IOT 时代,不断地涌现各种端,除了最常见的智能手机,它可能是小到一块智能手表,也可以是大到一个大屏终端 IOT 设备。而层出不穷的跨端技术,也为我们跨端方案提供了更多的选择。 那么我们究竟要跨哪些端? PC 端与移动端:从最早期的 PC 时代过度到移动时代,开发者希望通过一套代码同时在 PC 跟移动两端复用,于是产生了响应式等技术,使业务在 PC 发展的同时,也完成了在移动端的布局,保证业务不会在移动时代落后。 Native 与 Web:最常见的两种智能手机的操作系统 Android 与 iOS,Android 应用是用 JAVA 编码的,而 iOS 使用 oc 或者 Swift 编码的。同样,基于降级策略以及外放的考虑,我们也希望一套代码可以同时运行在 Web 上,而 Web 则是使用 JavaScript 编码的。天然的差异需要我们在端上适配时提供多套不同的代码实现,这使得研发周期加长,研发工作量剧增。 IOT 设备:随着进入万物互联的时代,越来越多的 IOT 设备涌现在我们的生活中,随处可见的大大小小的带屏终端设备,都是新的“端”,譬如智能家具、可穿戴设备以及车载设备等等。跨端早就不只是 Android 跟 iOS 的事情了,各种各样的设备终端带来的新的挑战。 小程序、轻应用:各种标准以及 DSL 诞生了新的“端”。 APP:各种 APP 之间互相投放。 and more...... 跨端技术的演进 本着对研发效率以及用户体验的极致追求,跨端技术也随着历史的浪潮不断地发展。从最早的 H5 方案到 Hybrid 方案,以及后来的 Weex/React Native 方案,到现在如火如荼的 Flutter。每个方案的演进都是为了解决当下方案的一些已知问题,但需要考量的因素都逃不过这些方面——渲染一致性、性能、体验、研发效率。我们并不希望需要去为不同的操作系统分别开发两份不同的 UI,期望可以通过一份代码使他们的渲染结果完全一致。同时,我们希望可以直接使用强大的生态去支撑我们的开发,拥抱标准,使得每次升级方案不需要对现有代码或者方案做一次大规模的重构。同样,性能与体验,也是端上绕不开的话题,这直接影响到我们的用户体验。 那么,下面来介绍一下跨端技术演进的几个重要阶段。 Web 以及 Hybrid APP 其实大家熟悉的 Web 就是最成功的跨平台方案之一,它与生俱来的跨平台能力、开放的标准以及强大的生态使它成为赤手可热的容器之一。 但是 Web 本身还是存在一些问题: 内存消耗大、GPU 利用率低、长列表滚动等,这使得它在移动端的表现并不尽人意。 由于各个浏览器厂商实现标准的迭代节奏慢,兼容性差,往往我们无法在 Web 上使用一些较新的能力,这使得我们的业务开发非常受限。 性能差,尽管网络以及硬件的发展给了性能足够多的红利,但是日益复杂的业务总能把已有的性能吃透。 由于 Web 需要向前兼容,有着非常重的历史包袱,一些古老的或者低性能的 CSS 可能会导致相当复杂的布局计算逻辑,消耗大量的时间。 于是在 Web 之上,衍生出一系列增强 Web 能力的方案: Hybrid App:依赖原生容器提供给 Web 更多的能力,包括 prefetch、离线化等。 PWA:提供了离线缓存、系统通知等能力,但是目前在国内发展不容乐观。 PHA:使用 Hybrid 的手段让 Web 的体验更加趋向 Native。 但是 Web 的方案还是存在性能问题,但是原生开发我们需要适配多端开发多端代码,于是我们需要寻求一个性能与研发效率的平衡点,于是产生了 Weex 以及 React Native 等方案。 Weex/React Native Weex 等方案通过 DSL 与 W3C 标准的子集向上结合了前端开发的生态,使我们熟悉的任何前端相关的工具都可以直接使用,保证了研发效率。而向下则是调用了系统自带的原生空间,使用原生渲染保证了性能与体验。 用前端代码开发原生 UI,这是一个非常美好的愿景,但是事与愿违,实际上还是存在一些问题。Weex 方案并没有抹平多端的差异,而是把差异的问题放在了容器侧去解决。由于底层直接调用了原生组件,而原生组件本身就存在一些限制,有限的能力不能满足开发者所有的需求,所以在实现 W3C 标准时有些牵强,会有一些在多端表现不一致的行为,没法保证完全的多端一致性。 Flutter Flutter 可以说是这两年跨端方案的新宠,它既不使用原生组件,也不依赖 WebView,而是通过自己的高性能渲染引擎直接调用底层的 Skia 进行自绘渲染,保证了多端的渲染一致性。 Flutter 使用 Dart 语言进行开发,Dart 既支持 AOT 也支持 JIT,在开发时可以使用 JIT,这使得我们可以直接使用 HMR,保证良好的开发体验。但是在运行时它是在 AOT 模式下的,这也使得它在运行时会有更佳的运行效率。 但是对于前端开发者来说, Widget 这种基于状态驱动的开发模式已经是非常熟悉,同时学习一门 Dart 语言的成本也不算高。但是对于已有前端生态与基建等的替换成本却是无法接受的,同时,它本身不支持动态化在复杂多变快速迭代的业务中并不能很好的胜任。所以在 Flutter 的基础上,也出现了非常多与 Web 结合的方案的探索,比如说 Kraken、WFlutter 等。通过对接 W3C 标准,保证上层直接使用 Web生态,底层使用 Flutter 的自绘渲染保证多端的渲染一致性。 跨端中的变与不变 各种新的技术层出不穷,在技术的迭代演进中,也演化出了各种新的技术方案以及新的容器。技术在演进,容器在发展,这是“变”。 那么什么是不变?容器那么多,如何进行适配,是否每出现一种新的容器,我们必须要把目前的所有业务代码进行重构才能保证在新的容器上稳定运行呢?我们的上层所有基础设施是否需要重新开发?我们怎么样快速复用我们的强大的前端生态保证我们的开发效率?任何软件工程遇到的问题都可以通过增加一个中间层来解决,我们通过 Rax.js 等研发框架,抹平了不同容器的差异,向上提供了同一套 DSL 给开发者,实现 “Write once, run everywhere”。 当然,标准化也是未来的趋势,标准化的流程可以使未来各种新的方案无缝衔接。提到标准,前端开发者自然会想到 W3C,各种容器各种端,最终会殊途同归,拥抱 W3C 标准,向标准化迈出一大步。 机遇与挑战 无论方案怎么变,我们无非是想要在性能、体验、研发效率以及渲染一致性这几个纬度中找到一个最佳的平衡点。在跨端的浪潮中前端开发者如何找准方向,以及将会遇到怎么样的机遇与挑战呢? 欢迎关注第十五届D2前端技术论坛跨端技术专场,我们将邀请一线技术专家,为各位带来有关跨端研发解决方案的新思路、新进展、新挑战,结合真实业务场景共同剖析跨端研发提效、性能优化的最佳实践。 以全球 Web 角度谈前端性能的更新与趋势Palances Liao / Google 资深 Web 技术专家 前端性能一直以来都是一个艰深的话题,除了各家都有自己不同的量测标准之外,怎样取得更精确的真实用户性能数据及通过工具的辅佐让我们更快速的调试成为了性能优化的一大难点。本专题会注重在 Google 如何定义性能指标,采集及提供优化性能的工具链如何帮助所有开发者快速调优前端性能,带来 Google 的最新研究。 盒马中后台跨端方案探索孙伟伟(景庄) / 阿里巴巴前端技术专家 实体零售数字化过程中,盒马对人货场进行了全新的重构,在多元的业态和作业场景中,传统中后台的体验边界也进一步被延展,前端不再单一面向单一类型设备进行开发与交付,而是需要触及到 TVPCPadPhonePOSRFWatch 等更多的智能设备。在盒马,我们通过构建多端体验产品 Hippo 去解决新零售科技场景下的多端内容交付与体验一体化的问题,本次分享主要介绍盒马的中后台跨端探索过程,包括多端统一的设计体系,可跨设备复用的组件架构,以及支持跨端协同的应用架构。 跨端的另一种思路佘锦鑫(当轩) / 阿里巴巴前端技术专家 Write Once, Run Everywhere 是诸多跨端方案的最终理想,然而理想和现实往往存在差距,跨端方案本身在带来提效的同时也伴随着相应的成本。本次分享主要介绍从场景出发,以 Flutter 和 Web 的逻辑跨端为例,介绍除 Write Once, Run Everywhere 之外的另一种思路。 关注「Alibaba F2E」把握阿里巴巴前端新动向

ECMAScript 双月报告:TC39 11月会议提案进度汇总

作者 | 吴成忠(昭朗) 这次 TC39 会议是 2020 年度最后一次全员会议。这次会议中没有任何提案争取到从 Stage 2 进入 Stage 3 的共识,也没有提案从 Stage 3 进入 Stage 4。 Stage 1 → Stage 2 从 Stage 1 进入到 Stage 2 需要完成撰写包含提案所有内容的标准文本的初稿。 Error Cause 提案链接:https://github.com/tc39/proposal-error-cause提案文本链接:https://tc39.es/proposal-error-cause/ 这个提案为 Error Constructor 新增了一个可选的参数 cause,可以接受任意 JavaScript 值(JavaScript 可以 throw 任意值),并会把这个值赋值到 cause 属性上。 错误原因的特性在许多其他语言中都有类似的设计,如 C# Exception Cause,Java Exception Cause,Python raise exception from cause。同样的,在庞大的 JavaScript 生态中也已经有了非常广泛的使用,如 verror 每周有上千万的下载量,@netflix/nerror 每周有数十万的下载量。 不过,即使在 JavaScript 第三方库中有再多的使用,Chrome DevTools 等开发者工具也难以依赖这些第三方库中定义的、不是语言定义中存在的属性。有了这个提案之后,这些开发者工具也可以默认打印 cause 属性中的值了,可以为异常处理带来更良好的体验。 try { return await fetch('//unintelligible-url-a') .catch(err => { throw new Error('Download raw resource failed', err) } catch (err) { console.log(err) console.log('Caused by', err.cause) // Error: Upload job result failed // Caused by TypeError: Failed to fetch Stage 0 → Stage 1 从 Stage 0 进入到 Stage 1 有以下门槛: 找到一个 TC39 成员作为 champion 负责这个提案的演进; 明确提案需要解决的问题与需求和大致的解决方案; 有问题、解决方案的例子; 对 API 形式、关键算法、语义、实现风险等有讨论、分析。 Stage 1 的提案会有可预见的比较大的改动,以下列出的例子并不代表提案最终会是例子中的语法、语义。 JavaScript Module Blocks 提案链接:https://github.com/tc39/proposal-js-module-blocks 目前很多设备都有非常多的处理器核心,JavaScript 代码在多个执行单元(线程、进程,如 Web Worker,Node.js 进程,Node.js worker_threads)中同时执行也是越来越常见。但是现在的 JavaScript 对于多个执行单元间共享 JavaScript 代码并没有非常理想的方案,通常我们可以 1、将不同执行单元间的代码写在不同的文件里: const Worker = new Worker('./my-worker.js') worker.postMessage({ action: 'add', params: [40, 2] }) worker.addEventListener('message', data => alert(`Result: ${data}`)) 2、通过一个通用的 Worker 执行器,然后将期望执行的 JavaScript 直接以字符串形式发送过去并执行(即每一次执行 JavaScript 引擎都需要重新解析这段 JavaScript 代码): const result = await runInWorker('return "foobar"') 3、通过一个通用的 Worker 执行器,接受一个函数并将这个函数 toString 后直接以字符串发送执行: function add(lhs, rhs) { // 这里捕获了外部变量的话,难以检测 return lhs + rhs; const result = await runInWorker(add, 40, 2) // 不支持 async function async function generateGraph() { /** complex code */ 这些方式要么不够工效,要么效率较差、更有安全风险。而这个提案则提出了一个隔离了变量作用域的代码块,并且这个代码块中的代码可以实现解析一次,到处使用。也意味着代码块中有任何语法问题,都可以快速地在引擎第一次解析即可被检查出来: let workerCode = module { onmessage = function({ data }) { let mod = await import(data); postMessage(mod.fn()); let worker = new Worker(workerCode, { type: 'module' }); worker.onmessage = ({ data }) => alert(data); worker.postMessage(module { export function fn() { return 'hello!' } }); 其实在之前 TC39 已经有过类似的提案 Blöck。不过之前这个提案的主要推进者已经退出了 TC39,提案也长期未有更新,故现在有新的委员会代表继续拾起想法开始推进。 Extensions 提案链接:https://github.com/hax/proposal-extensions 在这个提案之前,TC39 已经有过多个相关的提案,如 Pipeline Operator (Stage 1) ,Bind Operator (Stage 0)。其中 Bind Operator 的主要 Champion Group 成员已经长期没有推动提案的演进,而这次这个 Extensions 提案即是重新拾起了 Bind Operator 的大部分想法,并作了部分设计上的修订,继续提案的推进。 目前提案在技术委员会上的演示内容包含了几个部分的动机: 为任意 JavaScript 值引入局部作用域的方法与访问器(Accessor)扩展,替代 Monkey Patch 成为 JavaScript 中具有高工效、隔离性的扩展机制; 为扩展声明定义一个独立的命名空间,避免扩展声明被普通变量声明覆盖。 提案的内容可以简单地总结为以下几个例子: // 为集合类型拓展 toSet 的方法定义 const ::toSet = function () { return new Set(this) } // 给 DOM 对象拓展 allDivs 属性访问器 const ::allDivs = function { get() { return this.querySelectorAll('div') } const ::flatMap = Array.prototype.flatMap const ::size = Object.getOwnPropertyDescriptor(Set.prototype, 'size') let classCount = document ::allDivs ::flatMap(element => element.classList) ::toSet() ::size 除了直接在局部作用域声明扩展之外,还可以从外部模块导入扩展声明,或者是使用 namespaceOrConstructor:method 来使用快捷访问一个扩展: import ::{ identity } from '某些模块' arrayLike ::Array:map(x => x) // Array.prototype.map.call(arrayLike, x => x) ::identity() // identity.call(arrayLike) 相对于之前的 Bind Operator 提案来说,目前的 Extensions 提案有以下不同之处: 增加扩展字段访问器的定义; 对于局部定义的扩展方法、字段访问器有独立的变量命名空间; 增加使用命名空间扩展(obj::namespace:extension)的语法; :: 操作符现在与 . 操作符的优先级相同; 移除了 ::obj.foo (BindExpression),这个表达式相当于是 foo.bind(obj) 的语法糖。 相比于 Pipeline Operator 的将运算符的左运算符作为右运算符的第一个参数,这个提案中的 :: 运算符是将左运算符作为右运算符的 this 参数。不过,通过这个提案其实也能在一定程度上获得类似的体验: function capitalize (str) { return str[0].toUpperCase() + str.substring(1); function exclaim (str) { return str + '!' * Pipeline Operator 例子 let result = "hello" |> capitalize |> exclaim result // => 'Hello!' * 扩展例子 const ::pipe = function (fn) { return fn(this) } let result = "hello" ::pipe(capitalize) ::pipe(exclaim) result // => 'Hello!' 值得注意的是,当前 Pipeline Operator 的一个未完成的设计就是不支持 async/await,而对于扩展语法来说,这就有比较大的可自定义空间: async function post(data) { const resp = await fetch('127.0.0.1', { method: 'POST', body: data }) return resp.text() * Pipeline Operator 例子 let result = "127.0.0.1:8080" |> await post // 语法错误 * 扩展例子 const ::pipeAwait = async function (fn) { return fn(await this) } let result = await "hello" ::pipeAwait(post) ::pipeAwait(post) 另外,通过扩展语法我们更可以实现类似自定义单位的方案: const ::px = Extension.accessor(CSSUnitValue.px) // 非现有 API 1::px // CSSUnitValue {value: 1, unit: "px"} 除了以上所述的使用场景之外,目前提案给予了扩展的声明独立命名空间的设计上在会议上有较多的异议。前有例子如 Decorator 的第3个版本,它同样具有类似的独立命名空间设计,在委员会上存在强烈的异议。所以虽然提案目前总体进入了 Stage 1,相信这个设计后续会有更多针对性的讨论。 Grouped Accessor 提案链接:https://github.com/rbuckton/proposal-grouped-and-auto-accessors 这是一个来自微软的代表的提案,提案主要动机是让 JavaScript 的字段访问器(getter、setter)可以写在一起,同时给 Decorator 提案设计带来一个更加工效的字段装饰方案: class C { get() { ... } // equivalent to `get x() { ... }` set(value) { ... } // equivalent to `set x(value) { ... }` const obj = { get() { ... } set() { ... } class D { @logger() // 同时装饰 getter/setter get() { ... } set(value) { ... } 不过以目前 JavaScript 现有的字段访问器声明语法,较难让人信服新的方案能够带来更好的语法一致性。如果和现有的 getter/setter 与新的语法一起使用,语义上并没有增加新的特性,反而却额外增加了一个写法,可能会带来更多问题。这个提案在本次会议上也是在非常多的讨论后才进入 Stage 1。 @JackWorks :如果现在所有的 TC39 提案都写在一起 JavaScript 会变成什么样? 每年进入 TC39 的提案多种多样,而 TC39 的分阶段的流程必然给这些提案与提案的推进者们施加了强大的推进阻力。不过也正是这些分阶段性的推进阻力,让推进者们必须阐明提案所希望解决的问题,提案如何解决问题,提案能否解决问题,是否应该成为 ECMAScript 的一部分等等灵魂发问,才不会让 ECMAScript 变成一个揉杂了各种突发奇想的产物。 第十五届 D2 前端技术论坛 语言框架专场 TC39 核心成员 Ujjwal Sharma 将带来主题分享 《揭秘TC39:ES2020和ES2021》。重点讨论ES2020和ES2021中令人兴奋的新特性,并讨论我们在 TC39中正在进行的一些提案,包括Temporal和Intl.DurationFormat,同时与大家分享我在这个过程中学习到的一些经验,以及如何将它们应用在自己的工作中。最后为大家介绍 TC39 是如何工作的,以及社区的同学如何参与 TC39 并发表自己的意见。 关注「Alibaba F2E」把握阿里巴巴前端新动向

RxJS 负责人、TC39 成员、Node.js 技术委员会主席等 21 位大咖齐聚 D2 ,早鸟票最后 1 天,速抢!

D2 前端技术论坛 眼看着今年的 D2 越来越临近,赶在早鸟票结束之前,跟大家报告下到目前为止我们精心挑选的演讲主题。本届 D2 前端技术论坛依然本着专业、开放的态度进行主题征集,预计会有 20 个演讲主题,21 位演讲嘉宾(其中一场双人演讲)进行线上直播分享。目前我们已经对外公布了其中 18 个演讲话题,快来看看,哪一个是你最想听的? 语言框架专场 精选2位活跃在语言和规范最前沿的国际讲师,为你带来更潮的架构思想和语言标准化演进中的思考。 《重构 RxJS 架构:我们如何让其更小、更快》- Ben Lesh 在 Reactive 方面,有两个非常知名的工程师,他们是来自 Netfix 的 RxJava 作者Ben Christensen 和 RxJS 作者 Ben Lesh,两人在 Reactive 方面都做出了非常多的贡献。当然在 Reactive 社区,RxJS 还是最核心的底层框架,始终发挥着重大作用。RxJS 代码第一贡献者、RxJS 团队负责人 Ben Lesh 将在本届 D2 带来主题演讲,就其 RxJS 的开发经验和大家分享一下他的经验,相信大家一定会有新的收获。 《ECMAScript 2020》- Ujjwal Sharma 继去年 D2 的语言专场 TC39 核心成员 Daniel 的分享后,这段时间语言规范又增加了新特性?本届 D2 我们仍将邀请 TC39 的核心成员 Ujjwal Sharma 来分享 ECMAScript 新特性,以及这些特性在 TC39 讨论中如何克服困难,脱颖而出成为标准的故事。 跨端技术专场 跨端是各个语言和框架一直坚持探索的方向,从Java语言到大前端的Cordova/React-native/Weex/Rax/小程序/Flutter,开发者在跨端技术上投入了大量精力,也有非常优秀的实践。本专场共3位嘉宾,首先邀请了 Google 的开发者 Palances Liao 分享以全球Web视角谈前端性能,覆盖最新的性能衡量体系和未来趋势的分析。另外2位是来自阿里巴巴的分享嘉宾,已确定是来自景庄的《盒马中后台跨端方案探索》,另一个阿里内部精彩话题确认后释放出来,敬请期待。 《以全球 Web 角度谈前端性能的更新与趋势》- Palances Liao 前端性能一直以来都是一个艰深的话题,除了各家都有自己不同的量测标准之外,怎样取得更精确的真实用户性能数据及通过工具的辅佐让我们更快速的调试成为了性能优化的一大难点。本专题会注重在谷歌如何定义性能指标,采集及提供优化性能的工具链如何帮助所有开发者快速调优前端性能。为大家分享谷歌最新的相关研究。 《盒马中后台跨端方案探索》- 孙伟伟(景庄) 实体零售数字化过程中,盒马对人货场进行了全新的重构,在多元的业态和作业场景中,传统中后台的体验边界也进一步被延展,前端不再单一面向单一类型设备进行开发与交付,而是需要触及到 TVPCPadPhonePOSRFWatch 等更多的智能设备。在盒马,我们通过构建多端体验产品 Hippo 去解决新零售科技场景下的多端内容交付与体验一体化的问题,本次分享主要介绍盒马的中后台跨端探索过程,包括多端统一的设计体系,可跨设备复用的组件架构,以及支持跨端协同的应用架构。 前端安全生产专场 在阿里巴巴内部已经越来越重视前端安全生产,这也是我们首次面向前端业界提出这个分享专题的原因。安全生产本身也是一个工程问题,所以今年 D2 的前端工程专场将聚焦安全生产,我们将首次对外披露阿里经济体在前端安全生产上的建设成果。如果你的前端团队已经具备一定规模,并且正在高质量研发和高效业务迭代之间矛盾苦恼,那么我相信在这个专题一定能有所收获。 《前端故障演练的探索与实践》- 潘晨笑(辰啸) 近年来前端安全生产,特别是前端可用性成为了大家非常关注的话题。故障演练通过以战养战的方式,帮助我们在面对生产环境突发情况时做到有备无患。目前这个领域对前端而言还是相对比较新的领域。本专题旨在与听众一起,借助混沌工程的思路,探索如何将异常注入稳态的前端生产和消费链路之间,并验证系统和组织对此的响应,最终撬动前端在业务可用性上的表现提升。 《如何建设跨端灰度监控》- 黄建波(墨辉) 从历史数据发现80%左右的故障是线上变更引发导致的,怎么降低变更带来的风险以及线上问题的发现能力是监控核心要解决的问题。本次分享主要介绍跨端灰度监控整体的技术方案和应用实现,通过建立标准化方案来覆盖多种跨端场景,帮助业务在变更过程中及时发现问题。 《腾讯文档自动化测试》- 吴涛 腾讯文档是一款重前端的业务,历史上的腾讯文档自动化测试主要依靠测试同学。在研发效能提升的推动下,如何让前开发同学更方便地使用自动化测试框架并自主保障业务质量,是摆在我们面前的一大难题。本主题的分享内容将包含:腾讯文档质量保障的背景、历史上的腾讯文档自动化测试、新版腾讯文档自动化测试、落地效果。 Node.js(Serverless) 专场 在 Serverless 和云原生架构的发展之下,Node.js 最新版本已经是 v15 了,前端会在不同领域去使用 Node.js 和 Serverless 结合,这将使得整个前端开发领域带来怎样的变革?我们如何基于自身的业务场景去运用,发挥 Serverless 的最大价值?本专场将邀请一线技术专家分享最新资讯和技术实践,给大家带来更多的思考和经验参考。 《Node.js - What's next》- Michael Dawson 想要了解 Node.js 接下来会有什么样的发展吗?如新特性?重要更新?亦或者技术上乃至组织上的关键举措?Michael Dawson 是 Node.js 技术委员会(TSC)主席、Red Hat 和 IBM 的 Node.js 方向负责人,他将会为你带来 Node.js 前沿进展主题分享。 《Serverless 在前端部署领域的实践》- 凌艺宾 字节内部为前端实现了一套 Serverless 部署架构,可以便捷地实现普通页面部署、微前端应用部署、SSR 部署以及 BFF 部署,目前接入项目已经有 4000+,CSR 日访问量 2 亿+/QPS 3000+,最高支撑过 1W+ QPS 的活动,SSR QPS 最高 4000+。本专题为 Serverless 在前端部署方面的应用带来一些新的思考和方案,希望能给大家带来一些新的思路。 《双促实践 - 打造更稳定的 Serverless 实践》- 陈仲寅(张挺) 在过去的一年,阿里集团内部 Serverless 业务以数倍的增速落地,在这其中,Node.js 架构组承担了数倍的压力,不仅要面对双促的的业务落地和稳定性压力,也要面对集团多云环境复杂的部署架构。如今,大促结束,Serverless 稳定性也在业务得以验证,希望分享在云原生时代,如何围绕其进行研发效率与成本优化红利,以及在大促压力之中,作为今年的云+端 2.0 方案的业务承接者,如何围绕下一代框架、下一代架构、高可用体系等领域,让前端增效,业务获利。此次演讲将分享阿里集团的 Serverless 双促稳定性保障经验。 《SSR 在双十一会场的落地实战》- 邓宏才(霸剑) 会场是每年双十一的主角之一,会场的用户体验自然也是每年最关注的点。在今年双十一,我们基于 Serverless 基建将 SSR 带到了会场,将首屏秒可见率提高到了新的高度(82.6%)。本次分享为大家带来 SSR 在重要且复杂的业务场景落地时的前期思考、遇到的问题以及稳定性保障的方法论,希望能让大家在业务落地 SSR 时有更多的思路和信心。 在 Node.js(Serverless) 方向上我们还有来自蚂蚁的业务实战话题尚未释放出来,请大家多多关注我们的更多信息。 多样化专场 本届 D2 的多样化专场,真的可以说是神仙打架,开拓眼界。在这个专场,你可以感受到关于前端未来的无限可能。PRD 真的能生成代码吗?直播流媒体背后的思考和实践、大型场馆背后选座技术实现、Webassembly 在 IoT 设备上的应用实践、海量数据在前端如何处理?以及钉钉 Excel 的演进之路。多样化专场还有一个外部话题确认中,未更新,敬请期待。不用多说,多样化专场精选各种最新最潮的分享,一定有你感兴趣的演讲。 《媒体智能-淘宝直播流媒体互动方案及实践》- 潘佳(林晚) 直播间里互动玩法对于观看时长和互动率具有较大影响,基于流媒体的AI/AR互动玩法将给直播间的互动率带来极大提升。淘宝直播构建了一套媒体智能方案用以生产流媒体互动,同时利用工程化手段来生产提效。本次分享会介绍淘宝直播在流媒体互动方向上的方案设计及案例实践。淘宝直播前端团队负责人,带你揭秘时下最火的直播间里的前端技术。 《基于 WebAssembly 的 IoT 应用架构实践》- 唐兹源(渊之) 随着 WebAssembly 标准的发展,脱离浏览器环境的 wasm runtime 可用性已经变得越来越强,本次分享将为大家带来天猫精灵技术团队基于 WAMR 和自研渲染引擎打造的新应用架构实践经验,介绍 WebAssembly 在天猫精灵智能音箱的典型应用案例,以及未来对 WebAssembly 更多应用场景的思考。来自天猫精灵前端技术团队的 IoT 研发专家,与你分享 WebAssembly 与 IoT 结合的精彩内容。 《前端智能化实践:P2C 从需求文档生成代码》- 桑世龙(狼叔)&李帅(卓风) 2019 年 Imgcook 借助核心的 D2C(Design to Code,即设计稿出码) 能力,将模块智能出码水平提升到 79%,而分析发现未能智能出码的部分均是从视觉稿中获取不到代码信息的,比如多态逻辑、交互逻辑、数据服务逻辑,需要借助分析 PD(产品经理) 的原始 PRD(产品需求文档)才能获取到这部分代码信息,于是提出了 P2C(PRD to Code) 概念,希望通过 PRD、视觉稿(Design)结合的方式,来进一步提升出码水平。本次分享通过详细讲解 P2C 的整个探索和产研过程,希望为大家在前端智能化领域的开拓创新起到一个参考。 《10万级大型场馆背后的绘选座技术》- 赵芃苏(芃苏) 票务相关的业务和日常出行、娱乐生活息息相关,从商家绘座再到消费者选座,都是围绕座位展开。这其中,演唱会或体育赛事中的大型场馆,座位数量甚至可以达到10万以上。本话题将重点阐述,如何一步步突破10万座位带来的性能瓶颈,以及体验优化过程中前端技术上的思考。 《深入剖析海量数据场景下的用户行为分析方案》- 刘乐元(沅沅) 本次分享会的主题取自于阿里巴巴体验管理平台(AEM)中的一套用户行为分析系统。该系统服务阿里集团上百个BU,涉及上千个业务线,在日均百亿级别的用户行为数据中发掘分析问题,推动产品体验升级。本次分享会针对“海量数据分析”和“复杂链路的可视化展示”这两大难点进行深入剖析,带领大家了解如何快速构建用户行为分析体系。此外,分享最后还为大家准备了小福利,敬请期待。 《钉钉表格 —— 从 0 到 1 打造在线 Excel》- 谢光磊(叶斋) 钉钉表格是一款功能完整对标 Excel 的 Web 应用。从 0 到 1 的研发路径中,我们遇到了诸多传统前端开发不曾有过的挑战。这些挑战的解决,有些通过借鉴桌面端 Excel 已有的成熟设计,有些借助现代浏览器提供的强大底层能力,还有一些则受益于前端工程、框架、语言的进步。某种程度上,钉钉表格整合了上下游几乎所有主流的前端技术,探索出了一条完整的桌面级 Web 应用研发的道路。此次演讲将分享钉钉表格内部的技术架构,研发过程中遇到的技术挑战,以及这些挑战是如何被解决的。 《从中台的前端走向前端的中台》- 廖恺 有赞中台前端团队从成立至今, 伴随着各业务发展, 以及大量云定制场景入侵, 现有的业务体系结构已不堪重负。在此背景下如何建设前端中台能力, 从面向应用/页面的研发, 转向面向业务单元与业务场景编排的研发,走出从团队资源化困境,迈向建设前端中台,更好的为企业整体业务发展赋能。 上面已确认的分享主题,覆盖了今天前端的各个方面,有最新资讯,有语言规范,有听起来不太靠谱的 PRD 生成代码,也有 SSR 在双十一会场的业务落地,可谓是一场国内外顶级的前端盛会。除了各个专场的精彩分享,阿里巴巴经济体前端委员会联席委员长展炎将在本届 D2 带来大会开场主题演讲,为大家分享阿里前端各个技术方向的规划和背后的思考,以及面向前端行业,阿里前端未来的主要方向。前端领域在今年的双十一既有安全生产、稳定性保障,也有技术创新在大流量场景的落地,相信对参会者也会有一定的启发。 今年 D2 的脚步越来越近,D2 早鸟票今天也是最后一天了,30 元的票价绝对可以带走超超超值的技术内容,明天就要恢复 98 元的原价了,感兴趣的同学们不要错过早鸟票哦~

Chrome 87 重要更新解读

作者 | 彼洋 2020年11月17日,Chrome 发布 M87,这是今年的最后一个正式版本(由于圣诞节原因,M88 稳定版推出要到2021年1月),Chrome 产品总监 Matt Waddell 在一篇博客文章中写道:该版本是多年来Chrome浏览器性能获得最大提升的一次。到底是何特性撑得起如此美誉,我们这就来一探究竟。 新增稳定功能 即使你打开了大量标签,也只会同时聚焦在少数几个标签上,其余标签白白消耗着大量的内存和CPU。Chrome 团队通过调研发现,后台标签超过 40% 的工作消耗在JS定时器上,于是对其进行了限流,嵌套层级小于5的后台任务1s调用一次,否则会1min调用一次。这项优化会降低 Chrome 的 CPU 使用率到1/5,并且可以延长笔记本使用时间达1.25h。同时,这项优化不会影响音乐播放和通知等功能。 更多信息,请移步链接。https://docs.google.com/document/d/11FhKHRcABGS4SWPFGwoL6g0ALMqrFKapCk5ZTKKupEk/view 该功能可以检测到那些真正可见的窗口和标签,而不是那些已被最小化,或者已被遮挡的窗口。Chrome 可以对这些窗口和标签进行资源优化,使得启动速度加快25%,页面加载速度加快7%, 以及内存占用更小(无具体数字)。 更多信息,请移步链接。https://docs.google.com/document/d/1Di4DiGwHamIgLYjaOpripOJQinUquUuyxuiim2-WUIs/view 前进/后退缓存 很多时候,我们需要回退到上一个页面,在移动端场景下,这个比例甚至会高达20%,Chrome 在 Android 端支持了 bfcache,可以缓存前进后退的页面,目前可以覆盖20%的场景,计划后续提升到50%。 更多信息,请移步链接。https://web.dev/bfcache/ WebAuthn调试功能 测试网络验证功能一直都很困难,因为用户需要设备来测试代码。从 Chrome 87 开始,可以在devtools的一个新面板中模拟和调试。路径为 More options => More tools => WebAuthn,如下图所示:更多信息,请移步链接。https://developers.google.com/web/tools/chrome-devtools/webauthn 摄像头PTZ 有些摄像头具有平移(pan)、上下摇摄(tilt)、放大(zoom)等功能,合称PTZ,所以摄像头可以指向房间中的某个人。这不是会议室摄像头的专享功能,网络摄像头也可以支持PTZ。从Chrome 87开始,一旦用户许可,就可以控制网络摄像头的PTZ。 特性检测方式如下: const supports = navigator.mediaDevices.getSupportedConstraints(); if (supports.pan && supports.tilt && supports.zoom) { // Browser supports camera PTZ. 像其他强大的API一样,摄像头和PTZ功能也需要用户授权。通过调用navigator.mediaDevices.getUserMedia(),可以请求PTZ功能权限。弹出的提示框如下: 调用 MediaStreamTrack.getSettings() 可以获取摄像头支持的功能。进而通过调用videoTrack.applyConstraints() 来调整其PTZ参数,代码调用如下: function enablePan(capabilities, settings) { const input = document.getElementById('rangePan'); input.min = capabilities.pan.min; input.max = capabilities.pan.max; input.step = capabilities.pan.step; input.value = settings.pan; input.addEventListener('input', async () => { const opts = { advanced: [{ pan: input.value }] }; await videoTrack.applyConstraints(opts); 相关功能,可以在该网站进行试验。https://ptz.glitch.me/ 更多信息,请移步链接。https://web.dev/camera-pan-tilt-zoom/ 范围请求和Service Worker HTTP 协议范围请求(Range Request)允许服务器只发送 HTTP 消息的一部分到客户端,这在传送大的媒体文件,或者与文件下载的断点续传功能搭配使用时非常有用。它在主流浏览器中已被支持很多年,但由于历史原因,和service worker配合不佳,需要开发者绕过。从 Chrome 87 开始,在service worker内部发起范围请求,其HTTP头部可以透传出去。 更多信息,请移步链接。https://web.dev/sw-range-requests/ 新增试用功能 字体获取API 对于设计师来说,电脑本地会安装很多字体,比如企业logo字体、CAD或其他软件的专用字体。Chrome 87开始试用字体获取API,站点可以枚举本地安装的字体,供用户使用。代码调用如下: // Query for all available fonts and log metadata. const fonts = navigator.fonts.query(); try { for await (const metadata of fonts) { console.log(`${metadata.family} (${metadata.fullName})`); } catch (err) { console.error(err); // Roboto (Roboto Black) // Roboto (Roboto Black Italic) // Roboto (Roboto Bold) 站点也可以调用底层API,获取字体的字节编码,让用户实现复杂的typography。代码调用如下: const fonts = navigator.fonts.query(); try { for await (const metadata of fonts) { const sfnt = await metadata.blob(); makeMagic(metadata.family, sfnt); } catch (err) { console.error(err); 更多信息,请移步链接。https://web.dev/local-fonts/ 废弃&删除的功能 iframe allow 属性的逗号分隔符 之前,iframe 的 allow 属性可以使用逗号来做分隔,但这是不标准的,应该使用分号,从Chrome 87开始,逗号分隔符会被废除。 -webkit-font-size-delta Blink 将不再支持使用 -webkit-font-size-delta 属性,开发者应该使用 font-size 属性来替代。 更多参考https://mp.weixin.qq.com/s/arJe36fWJh63VOh071yRpw https://mp.weixin.qq.com/s/g3UFdV4uQDdtaooDVIJE_Q https://blog.chromium.org/2020/10/chrome-87-beta-webauthn-in-devtools.html https://blog.chromium.org/2020/11/tab-throttling-and-more-performance.html https://developers.google.com/web/updates/2020/11/nic87 第十五届 D2 前端技术论坛早鸟票倒计时,速抢!一起来语言框架专场学习更多精彩内容 继去年 D2 的语言专场后,这段时间又有哪些新的语言诞生了,哪些语言规范又增加了新特性?函数式编程和函数式流编程的思想究竟如何,我们是否应该将其引入到我们的产品中?本届 D2 的语言框架专场,将邀请 RxJS 的开发者为大家介绍 RxJS 内部的结构,以及 RxJS 如何重构的又快又小。同时我们也将邀请 Google 的 V8 核心成员讲述最新 ECMAScript 新特性,以及这些特性在 TC39 讨论中如何克服困难,脱颖而出成为标准的故事。 关注「Alibaba F2E」把握阿里巴巴前端新动向

人机协同时代,AI助力90.4%双11前端模块自动生成

作者 | 淘系-苏川 2017 年,一篇论文 pix2code: Generating Code from a Graphical User Interface Screenshot 引起业界关注,论文讲述了使用深度学习技术实现从一张 UI 截图识别生成 UI 结构描述,然后将 UI 结构描述转成 HTML 代码。有人认为这种从 UI 截图直接生成代码的意义不大,AI 和 Sketch 软件本来就是用数据结构保存设计文件的结构描述,不需要通过机器学习来获取,而且生成的代码不确定性很大。也有一部分人对这个思路给予肯定,提出让深度学习模型学习 UI 界面特征,还可以做 UI 智能设计。 随后基于 pix2code 开发的 Screenshot2Code 项目进入 Github 排行榜第一名,该工具能够自动将 UI 截图转成 HTML 代码,该项目作者号称 3 年后人工智能会彻底改变前端开发,对此也有不少用户表示质疑,认为前端技术复杂框架各异,仅 HTML 代码无法满足需求。 2018 年,微软 AI Lab 开源了草图转代码工具 Sketch2Code ,一些人认为生成代码效果不理想不适用于生产环境,但也有人认为代码自动生成还处于初级阶段,未来发展值得想象。 2019 年,阿里巴巴对外开放智能生成代码平台 imgcook,可以通过识别设计稿(Sketch/PSD/图片)智能生成 React、Vue、Flutter、小程序等不同种类的代码,并在同年双 11 大促中自动生成了 79.34% 的前端代码,智能生成代码不再只是一个线下实验产品,而是真正产生了价值。 每当这些新的自动生成代码产品发布,网络上总会出现“人工智能会不会取代前端”“一大批前端程序员要失业了”这些讨论。 那人工智能到底会不会取代前端?人工智能在未来很长的一段时间内不会取代前端,但是会改变前端。一是会改变在前端智能化方向的前端领域探索者,他们除了可以成为 Nodejs 服务端工程师,还可以成为机器学习工程师,为前端智能化领域创造更多的价值和成果;二是会改变享受前端智能化成果的前端开发者,改变他们的研发方式,例如代码智能生成、代码智能推荐、代码智能纠错、UI 自动化测试等可以帮助他们完成大量简单重复的工作,可以把更多的时间放在更有价值的事情上。 本篇文章将给大家分享作为前端智能化领域的探索者,我们是如何看待人工智能在前端领域的未来发展方向,如何推进智能化能力在智能生成代码平台 imgcook 上的应用落地和迭代升级助力今年双 11 会场 90.4% 新模块的代码智能生成,编码效率提升 68% 的。 阶段性成果 imgcook 官网首页平均每月 PV 6519, 平均每月 UV 3059。相比于 2019 年, 2020 年月平均 PV 和 UV 均是 2019 年的 2.5 倍。 imgcook 用户共有 18305 个,其中社区用户占比 77%,阿里集团内用户占比 23%。imgcook 模块共有 56406 个,其中外部模块占比 68%,内部模块占比 32%。相比 2019 年之前总量,2020 年用户增长 2.7 倍,模块增长 2.1 倍。 社区覆盖公司至少 150 家,集团内部覆盖 BU 10 个以上,双 11 会场新增模块覆盖度 90.4%,无人工辅助情况下智能生成的代码被保留发布上线的占比 79.26%,编码效率(模块复杂度和研发耗时比值)提升 68%。 与 2019 年相比,用户感官提效提升 14%;和完全不使用 D2C 相比,固定人力单位时间模块需求吞吐量提升约 1.5 倍。与传统研发模式相比,使用 imgcook 研发链路编码效率可提升约 68%。 (Imgcook 研发效能数据概览) 技术产品体系升级 技术原理简介 我们先来了解下 imgcook 智能生成代码的原理, imgcook 能够自动生成代码主要是做了两件事: 从视觉稿中识别信息,然后将这些信息表达成代码。 本质是通过设计工具插件从设计稿中提取 JSON 描述信息,通过规则系统、计算机视觉和机器学习等智能还原技术对 JSON 进行处理和转换,最终得到一个符合代码结构和代码语义的 JSON,再用一个 DSL 转换器,转换为前端代码。DSL 转换器就是一个 JS 函数,输入是一个JSON,输出就是我们需要的代码。例如 React DSL 的输出就是符合 React 开发规范的 React 代码。 (D2C 智能生成代码使用动线) 其中核心部分在于 JSON to JSON 这部分。设计稿中只有图像、文本这些元信息,位置信息是绝对坐标,并且设计稿中的样式与 Web 页面中的样式表现存在差异,例如 sketch 中透明度 opacity 属性不会影响子节点,但在网页中 opacity 会影响子节点,而人工编写的代码具有各种布局类型、DOM 结构需要合理可维护、代码需要语义化、组件化、循环等信息。 如何能智能生成像人工编写这样的代码,这是智能还原这部分要解决的事情。我们把 D2C 智能还原部分做了能力分层,每一层的输入和输出都是 JSON,智能还原部分的本质是一层一层的做 JSON 转换,这就是整个智能还原的流程。如果需要对生成的 JSON 做修改,可以通过 imgcook 编辑器可视化干预,最终通过 DSL 开放层将得到的符合代码结构和语义的 JSON 转换为代码。 (D2C 智能还原技术分层) 智能还原的核心链路构成了 D2C 的核心技术体系,并通过度量体系来衡量核心还原能力和研发提效效果。下层依托算法工程体系提供核心技术体系中智能化能力的底层服务,包括样本制造、算法工程服务、前端算法工程框架,上层通过 D2C 研发体系承接智能还原的后置链路,通过提供可视化干预能力满足用户二次迭代的需求,并通过将工程链路内置到 imgcook 平台实现一站式开发、调试、预览和发布来提升整体的工程效率。再加上支持自定义 DSL、自定义开发物料等扩展性很强的自定义能力形成的开放体系一起构成了整个 D2C 架构,服务于阿里内部 C 端、小程序、中后台等以及外部社区各种不同的业务场景。 (D2C 技术架构图) 今年在前端智能化大背景下,对 D2C 技术体系全链路进行了智能化能力升级,并为前端同学带来了让前端工程师能成为机器学习工程师的前端算法工程框架 Pipcook 和解决样本收集问题的样本制造机 Samplecook。同时带来了营销模块研发链路产品化升级,助力全链路研发提效。 智能化能力升级 智能化能力分层定义 《汽车驾驶自动化分级标准》基于驾驶自动化系统能够执行动态驾驶任务的程度,根据在执行动态驾驶任务中的角色分配以及有无设计运行条件限制,将驾驶自动化分成 0 至 5 级。在高级别的自动驾驶中,驾驶员的角色向乘客转变。这种明确的标准有助于各类企业更有针对性展开研发和技术部署的工作。 (自动驾驶分级标准) 参考自动驾驶分级标准,基于 D2C 系统能够自动生成代码的程度,根据编码的角色以及是否需要再人工干预和验证,我们定义了一个 D2C 系统交付的分级标准,用来帮助我们认识 D2C 系统当前所处的级别以及下一阶段的发展方向。 (D2C 系统交付分级参考标准) 目前 imgcook 的能力处于 D2C 的 L3 级别,智能生成的代码还需要可视化干预或人工兜底开发后验证上线。未来期望达到 L4 级别,我们需要对 UI 信息架构进行拆解,对从 UI 信息自动生成代码的智能化能力进行细分。 (UI 信息架构拆解) 一个应用由多个页面组成,每个页面中按 UI 颗粒度划分可以分为模块/区块、原子模块/区块、组件(业务组件、基础组件)、元件。每一个颗粒度的 UI 我们都需要识别到它的布局结构和语义,才能生成像人工编写一样模块化、组件化、语义化的可维护性较高的代码。 根据对 UI 信息架构的拆解,我们结合 imgcook 生成代码的技术体系从不同颗粒度对智能化能力进行分级 I0-I5(I 是 Intelligent 的首字母)。 (D2C 智能化能力分级) 其中涂色部分是目前已具备的能力,从这个维度来看 imgcook 的智能化能力目前处在 I3 和 I4 级别,并与 I2 级别的能力协同运作于生产环境。I3 级别的智能化能力需要不断优化和迭代模型,当线上真实场景准确率达到 75% 以上或模型具备自我迭代能力则进入 I4 级别。如果达到了 I5 级别的智能化能力,根据 D2C 系统交付分级参考标准,D2C 系统交付分级可以从 L3 进入 L4, 生成的代码将不需要人工干预和验证即可直接上线。 当然我们可能会长期处于 L4 级别这个人机协同编程的阶段,这种分级的定义是为了促进智能化落地的进程,可以指导 我们提升 D2C 智能化能力,对 D2C 智能化有个更清晰的认识。 我们以生成代码的可用度作为总体技术指标,并根据代码生成链路的技术分层给出各阶段的技术指标以及对代码可用率影响的权重,其中生成代码的理论准确度 = (各个环节准确度 * 权重)之和,而真实的代码可用率 = imgcook 生成的代码在最终上线的代码中留存的占比。 (各分层技术指标与权重定义) D2C 的智能化能力分布在还原链路的各个阶段,我们以提升代码可用率为目标,对全链路进行智能化能力升级,将技术方案细化到如何让各阶段模型识别准确率提升以及如何能将识别结果最终应用到智能还原链路生成代码,如何做到从样本收集、模型训练、模型部署到模型应用到工程链路整个流程能够自动化、自我迭代优化,不断优化和迭代模型能力。 智能化能力的应用还需要工程链路的支撑,例如模型识别结果的应用、线上用户行为召回、前端开发组件对 UI 组件识别结果的承接等,整体的 D2C 技术体系也需要同步升级。 (D2C 技术体系升级大图) 各阶段智能化能力升级 1、图层解析阶段imgcook 通过解析设计稿图层信息,并通过规则系统、智能化技术等识别和生成代码,但由于设计域与研发域的表达方式、结构和规范等差异,设计稿的图层结构对生成代码的合理性影响较大,一些设计不规范的设计稿需要用 imgcook 的“成组”和“图片合并”协议对设计稿进行调整。 开发同学在开发代码时也经常会有写多余的 console.log、没有注释、变量重复声明等代码不规范的问题,为了解决这些问题,提供了 ESLint、JSLint 等工具来保障代码规范的统一。 在设计域,我们也同样可以开发一套设计稿规范智能检查工具来保障设计规范,智能审查设计稿的规范性,提示错误并辅助调整。我们把这套工具称为 Design Lint(DLint) (设计规范检查) 2、物料识别阶段UI 物料可以分为模块/区块、组件和元件,从 Sketch/PSD 中直接提取的信息只有文本、图片和位置信息,直接生成的代码都是由 div、img、span 组成,实际开发中组件化、代码语义化必不可少,如何从设计稿中提取组件和语义信息,这是 NLP、深度学习等智能化技术非常适合解决的问题。 去年我们在组件识别、图片识别、文本识别这几个方向都有探索和实践,识别的结果最终用于语义化和字段绑定,但使用的技术方案对识别的效果限制较大,今年我们做了如下改进: 3、组件识别 原本使用目标检测的方案来识别 UI 组件,但这种方案既需要识别出正确的组件类别还需要识别出正确的位置,以整个视觉图片作为输入,复杂的图片背景很容易被误识别,并且由于识别出的位置偏差导致很难挂载到正确的节点上,模型识别结果在线上的应用准确率较低。 基于这些原因,以及 imgcook 能够从视觉稿中获取每个图层位置信息的优势,我们将方案转换成了图片分类,并能将识别结果真正的应用到线上,这其中依托一套组件可配置、可识别、可渲染、可干预、可出码的智能物料体系。 (组件识别应用全链路) 以下是组件识别应用到线上的演示,识别视觉稿中的视频信息,并用 rax-video 前端组件承接生成组件粒度的代码,需要配置自定义的组件(组件库设置)、组件识别模型服务(模型服务设置)、支持渲染 video 组件的画布资源(编辑器配置-画布资源)以及应用组件识别结果的业务逻辑点(业务逻辑库配置)。 点击查看组件识别全链路演示 4、Icon 识别 Icon 识别其实是一个图片分类的问题,依然沿用图片分类的方案,但为了能够让模型的泛化能力能自我增强,我们设计了一个 Icon 自动收集、处理数据、自动训练模型、自动发布模型的模型闭环链路,让模型能够自我迭代优化。 (Icon 识别模型闭环链路) 自上线以来,新增训练集总数达到了 2729 个,平均每月回捞有效数据 909 个, 模型经过几次自我迭代测试集的准确度从 80% 提升到了 83%。 5、图片/文本语义识别 在 imgcook 智能化系统中有一个很关键的部分,就是如何对 UI 界面内的元素绑定语义化信息,之前解决方法是基于图片和文本分类模型识别,该方法有很大的局限性:仅对文本进行分类,没有考虑与整个 UI 界面内的上下文语义,导致模型效果不好。 举个例子:$200,这个字段文本分类是没办法对其进行语义识别的,因为它放到不同的场景中有着不同的意思,如:活动价、原价、优惠劵…,正确的做法是考虑该字段与在 UI 界面的联系(即独特的样式)来对它进行语义分析。 因此,我们引入了一种能结合 UI 中上下文语义的方案来进行语义识别,采用图片元素决策+文本分类两步走的方案解决界面元素语义化问题,具体流程是:先基于强化学习对界面元素按样式“过滤”一遍,识别出有样式的非纯文本字段,再对纯文本的字段进行文本分类。具体框架如下。 (强化学习 + 文本分类) 以下是模型算法训练结果 (基于上下文的语义分析) 布局还原阶段 布局即是代码中每个节点与节点之间的关系,是父子关系还是兄弟关系。从颗粒度大小上划分,可以分为页面间模块/区块之前的关系、模块/区块内原子模块/区块之间的关系以及原子模块/区块内组件、元件之间的关系。 目前 imgcook 已具备了循环识别与多态识别的能力,识别设计稿中的循环体生成循环代码,识别同一个节点有多种 UI 状态时生成多状态的 UI 代码,并定义了布局可维护度衡量方式来衡量还原阶段的准确度。 (布局还原阶段识别能力升级) 逻辑生成阶段 在业务逻辑生成阶段优化原有的配置链路,将业务逻辑库与算法工程链路解耦,并承接所有识别结果的应用和表达。物料识别阶段只关心 UI 中有什么物料,不关心识别的结果如何用于生成代码,布局还原阶段的循环识别和多态识别同理。这样做的好处是我们可以自定义识别结果的表达,并且可以让用户感知智能识别的结果并选择是否使用。 除了从业务逻辑库生成逻辑代码也可以从需求稿生成部分逻辑,或者来源于代码片段推荐,或者来源于代码智能推荐( Code to Code,C2C)。 (通用业务逻辑库配置) 标算法工程体系升级 样本制造机 算法工程服务提供了 UI 特征识别的模型训练产品,为所有想使用业务组件识别的小伙伴打造一个玩弄机器学习的链路。为了解决使用算法工程服务的关键痛点,所以有了新的衍生产品:样本制造机,为前端 UI 识别的模型提供样本制造捷径。 前端算法工程框架 有很多同学会觉得,让前端同学用机器学习技术去解决前端领域的问题,会不会难度很大。为了降低前端工程师使用机器学习的门槛,我们开发了前端算法工程框架 Pipcook。前端工程师可以用熟悉的 JavaScript 来完成机器学习任务。 Pipcook 通过提供通用的模型能力,比如图片分类、目标检测、文本分类等,减少了在 imgcook 中从开发到上线这些模型的门槛,使得如此多的底层识别能力也具备快速迭代的可能性。imgcook 全链路的识别能力,如组件识别、Icon 识别、字段语义识别等都是基于 Pipcook 训练。 (前端算法工程框架 Pipcook) 我们可以这样理解 Pipcook, Node.js 的出现可以让前端工程师成为一位服务端工程师,做服务端同学能做的事情, Pipcook 的出现可以让前端工程师成为一位机器学习工程师,可以做机器学习工程师做的事情。 (前端与机器学习) 关于 Pipcook 是如何用 Node.js 桥接机器学习生态以及目前 Pipcook 的应用情况。 研发链路升级 天马模块研发链路 淘系营销以模块开发为主,模块开发的完整链路是从模块管理平台创建模块 ⇥ 进入 imgcook 平台智能生成代码&可视化研发 ⇥ 开发完成后进入 IDE 调试预览 ⇥ 测试完成后进入工程平台发布。整个研发流程需要切换多个平台,开发链路体验和工程效率都有待提升。 创建模块后进入 imgcook 平台智能生成代码&可视化研发,如果能够直接在 imgcook 平台开发、调试、预览和发布,一站式的 D2C 研发模式是提升整体研发效率和研发体验的一个不错的选择。 所以我们自定义了具有可视化模式和源码模式的营销版本 imgcook 可视化编辑器,在可视化模式智能生成代码和可视化研发,并将生成的代码一键同步到源码模式的 WebIDE,在 WebIDE 中支持界面化的调试、预览、发布。 (天马模块 imgcook 可视化研发动线) 我们通过计算使用传统研发模式开发的模块与使用 imgcook 可视化研发模式开发的模块的效率值(复杂度与研发耗时比值)看到,使用 imgcook 可视化研发链路开发的模块编码效率提升 68%。 点击查看天马模块 imgcook 可视化研发全链路演示 智能 UI 研发链路 智能 UI 是一种通过分析用户特征为用户提供个性化 UI 的方案,因此需要开发大量的 UI 界面,在淘系智能 UI 平台鲸幂中开发智能 UI 的原始链路是在上传视觉稿解析物料之后会批量创建 imgcook 模块,但每种物料都需要进入对应的 imgcook 可视化界面单独开发、创建仓库、单独发布,并且看不到智能 UI 整体的视觉效果。这样导致智能 UI 所需要的大量物料的开发成本很大,业务接入智能 UI 的成本比较大。 (智能 UI imgcook 可视化研发动线) 这次升级了智能 UI 的研发链路, D2C 可视化研发链路承接了智能 UI 的批量化生产。在上传设计稿解析出 UI 物料之后,创建 imgcook 模块,批量生成物料 UI 代码,同时创建代码仓库与 imgcook 模块关联,并支持将已创建的物料批量导入 imgcook,批量生成 UI 方案(不同类型的 UI),在生成的 UI 方案中集中式对物料进行开发,最后还将支持物料的批量发布,整个链路集中高效了很多。 今年前端智能化助力前端研发模式升级,数个 BU 共建前端设计稿识别算法模型和数据集,并于双 11 会场大规模应用落地。 设计稿生成代码技术体系全面升级(如对 UI 多态、直播视频组件、循环的智能识别增强等)带来了营销模块研发链路产品化升级:双十一会场有 90.4% (高于去年)新模块的代码智能生成。升级设计稿智能检查能力,在可统计范围内,无人工辅助的情况下智能生成的代码被保留发布上线的占比 79.26%。 相比传统模块开发模式,使用设计稿生成代码技术后编码效率(模块复杂度和研发耗时比值)提升68%,固定人力单位时间模块需求吞吐量增加约 1.5 倍。 目前还需要人工改动代码的主要原因有:循环未被识别、条件展示逻辑代码未自动生成、字段绑定猜测错误(字段标准化情况不佳)、业务特性必须的图片合并问题等,这些问题也都是接下来需要逐步完善的。 (D2C 代码生成用户更改情况) 同时,imgcook 支撑了天猫淘宝的主会场和行业会场智能 UI 的批量化生产,极大的提升了智能 UI 的生产效率。 (智能 UI 批量化生产结果) 智能化方式无论是使用计算机视觉还是深度学习技术,都会有准确率的问题,准确率低在线上环境可能无法被接受。需要建立一套与线上用户使用数据形成闭环的算法工程链路,实现样本自动化收集、算法工程链路的闭环才能让模型线上识别准确率不断提升。目前在 imgcook 的系统中,Icon 识别从样本收集到模型识别结果的最终应用已经形成了完整的链路闭环,开发同学不需要花太多精力用于模型的优化。对于其他的模型,后续也会用同样的思路让模型具有自我迭代的能力。 另一个 D2C 智能化的难点是模型识别的结果最终如何用于生成代码,例如组件识别模型能识别组件的类别,但最终生成代码使用哪个组件库的组件、如何识别 UI 中的组件属性值这些问题,imgcook 的平台能力与智能还原技术分层架构具备解决这些问题的能力,未来会有更多的智能化方案用于生产环境。 后续我们会继续根据对 imgcook 的 D2C 智能化能力拆解,探索更多智能化解决方案,优化现有模型能力,建立算法工程闭环机制实现每一个模型的自我迭代,不断提高模型的泛化能力和线上识别准确度,辅助生成可维护性更高语义更强的前端代码。 欢迎大家一起来交流。 TC39成员、Node.js的核心协作者 Ujjwal Sharma 确认出席第十五届 D2 前端技术论坛。早鸟票倒计时五天,速抢!

作者 | 圣司 点击查看视频 伴随互联网业务形态的多样化,无线流量渠道矩阵逐步成型,更多场景化的流量入口带来了天然细分的人群与触点,流量红利的逐渐式微也让越来越多的业务开始重视用户增长。在小程序、轻应用等开放平台,及腾讯广告、微博、巨量引擎、百度信息流、阿里汇川等商业化引擎能力加持下,全域投放、全域触达、全域营销的思路逐渐成为标配,IoT、OTT、POS 等设备需求也爆发式增长,端侧业务需要在合适的时机,通过合适的端/渠道,出现在合适的人手中形成承接,朴素的业务需求之下,也对面向多端场景的业务研发提出了更高的要求与挑战。 当我们聊跨端时,我们在聊什么? 1990 年,Tim Berners-Lee 在自家的 NeXT 电脑上打开了 Web 技术的大门,并带来了 HTML 和 HTTP,前端技术的种子自此落地,开始生根发芽。随后的三十年风起云涌,从 PC 时代、移动时代到万物互联的 IoT 时代,繁荣的背后越来越多的设备、系统与解决方案纷至沓来。 跨端作为大前端技术的一个分支,重点在于面向不同终端设备,提供高效的业务场景研发解决方案,并保障性能与体验。今天我们提到的跨端,一般包含四类场景: 跨设备平台,如 PC/Mobile/OTT/IoT。不同的设备平台往往意味着不同的硬件能力、传感器、屏幕尺寸与交互方式,尤其在移动互联网早期,由于研发主力仍在 PC 上,而移动设备作为下一个风口也需要布局,诞生了大量跨平台解决方案,Web 技术下典型的就是响应式布局。 跨操作系统,如 Android/iOS/HarmonyOS。对于传统前端开发来说,移动端各类操作系统差异已被图形库、渲染引擎等基础设施抹平,并以标准化的形式提供上层 API;但在 RN、Weex 等依赖原生控件渲染的方案下,依然会对跨端差异有明显感知。 跨 App,如 淘宝/微信/头条。由于移动平台 CS 架构 App 间天然的壁垒,不同 App 间无法再通过超链接的形式完成资源的索引,而是在各个 App 封闭体系内遵循一套自有标准进行资源的索引与定位。而同一业务投放至不同 App 端时,同样需要适配这些不同的路由规则与原生方法。 跨渲染容器,如 Webview/RN/Weex。前面三类场景催生了不同平台、不同操作系统、不同 App 间解决方案的差异性,无线领域各种 native 化渲染、自绘渲染与魔改 Webview 的方案被设计出来,也大大提高了跨端场景下的迁移成本。 考虑到当下移动领域仍是互联网绝对的统治者,我们先将问题的讨论范围收束到移动技术领域。 跨端技术发展史 2007 年苹果发布初代 iPhone 拉开了移动互联网的序幕,08~14 年迎来了 全球范围年复合 35.1% 的高速增长,伴随终端设备的日趋多样化,PC 之后,Mobile、IoT、OTT 等一系列新设备开始登上历史舞台,而在 Web 标准向移动设备适配的过程中,诞生了种类繁多的跨端解决方案,大体上可以分为几个阶段: 19/20 全球移动开发者跨端解决方案使用率,数据来源 statista H5 wap 阶段,jquery/KISSY → Zepto/KISSY-mini。Web 天然跨平台,但由于早期网络环境原因,页面加载速度无法满足业务预期,加之设备传感器标准缺失、内存占用大、GPU 利用率低等问题,在移动设备量爆发伊始,难堪大任的论调一下子被推上风口浪尖,并在 12 年达到顶峰: "The biggest mistake we made as a company was betting too much on HTML5 as opposed to native. It just wasn't ready." —— Mark Zuckerberg, 2012 彼时标准化组织与浏览器厂商正在酣战,04年 WHATWG 诞生,直至 10年后 HTML5 标准终于发布;相对后来的跨端解决方案,PWA 是 Web 正统,完全的标准化运作实现,但由于受多方阻力,推进缓慢,国际层面 相对有一些声浪,而在国内甚至只能存在于各大厂商的面试题中,近两年受小程序的冲击尤甚。 Hybrid 阶段,典型代表是 Cordova/PhoneGap/ionic。从核心功能上看,Hybrid 解决了 web 跨端时代的两大痛点问题,1)性能,依靠容器能力,各类离线化、预装包、prefetch 方案大幅减少页面渲染所需加载资源数量,或提前加载时间,配合一些编码上的优化,在 2/3G 及 4G 时代早期把 Web 的秒开体验拉到了与 Native 一个数量级的水平;2)功能,通过 JSBridge 桥接的方式,规避了 Web 标准制定长流程,及与 Native 原生的割裂带来的底层能力缺失。 Hybrid 本质上是 Web 标准/实现滞后于无线业务发展速度之下的一种权衡与妥协,Web 技术借助 hybrid 的加持在无线时代成功撕开了口子,让前端有了一席之地,也为后来的演进方向作了不少探索与铺垫。但 Hybrid 带来的 Web 标准超集,不同 App 间容器能力、配套设施的差异也导致了 PC 浏览器、移动操作系统之后,前端开发的第三次碎片化。 Native 容器化阶段,典型代表是 ReactNative/Weex。通过 JSC(V8)链接 Web 生态与原生控件,结合 React/Vue 等框架,尝试在研发效率与性能体验间寻找更佳的平衡点,也为前端与无线的协同模式开辟了一条新的道路,各类领域解决方案(受限 DSL + 魔改 web 标准 + Native 渲染能力)开始涌现。Native 容器化拉开了大前端融合渲染方案的序幕,传统前端/客户端的职能边界开始变得模糊。 "It's worth noting that we're not chasing 'write once, run anywhere.' Different platforms have different looks, feels, and capabilities, and as such, we should still be developing discrete apps for each platform, but the same set of engineers should be able to build applications for whatever platform they choose, without needing to learn a fundamentally different set of technologies for each. We call this approach 'learn once, write anywhere.'" —— Tom Occhino, 2015 相比 RN “Learn Once, Write Anywhere”,Weex 的 “Write Once, Run Everywhere” 更理想化也更贴近前端的思想,但从两者的发展脉络上看,两个弊端无法回避:1)Native 容器化本质上没有消灭一致性问题,而是把问题转移到了容器层解决,瓶颈依然存在;2)伴随业务需求的复杂化,每个新特性的支持都会带来容器复杂度的升高,进而影响到性能/体验/稳定性,更多的分层也带来了问题排查难度的提升;当这两个问题达到某个临界点,Native 容器化方案表现甚至会弱于传统 Web,“屠龙少年最终变成了恶龙”。 数据来源 google trends 同层渲染阶段,典型代表是 WVC/BlendUI/CoverView。是一种介于 Hybrid 与 Native 容器化之间的中间态跨端增强渲染方案。早期通过在 Webview 上直接绘制 Native 组件并跟随滑动的方式,实现客户端内视频等富交互组件原生化,增强体验;之后借力 Android U4 与 iOS WKWebView 提供的同层渲染技术,可以使 Native 组件像普通 DOM 元素一样使用,滑动跟随、层级控制/遮盖、事件透传、生命周期打通,跨端场景下能够更好贴合所处渲染环境的自有方案,渐进增强。严格来说相较其他几个阶段,同层渲染技术并没有达到同样体量的影响力,但它所代表的思想对于当下与未来诸多方向的融合具有重要意义,因此在此也作简要记录。 小程序/快应用阶段,典型代表是 Taro/uni-app/mpvue。小程序的核心是商业模式,而非技术实现,它不为解决跨端问题而生,在此将它列为一个阶段,是因为双线程模型及自建 DSL 的引入带来了新的跨端问题。 从技术上说,小程序跨端方案大体分为编译时与运行时两类,前者主要通过静态编译的方式将基于 React/Vue 等框架的业务代码转换为小程序原生 DSL,如 Rax 编译时、Taro 2.x,优势在于性能相对较好,但受编译限制需要使用非标的受限语法,研发体验比较差;后者则通过运行时框架对接小程序 setData 的方式来实现跨端,优缺点与编译时正好相反;按具体实现不同运行时方案可再细分为两类,1)利用 React 框架特性,通过 react-reconciler 在 VDOM 层直接对接对接小程序渲染,如 Remix;2)通过模拟 DOM/BOM API 的方式,在运行时框架层维护 VDOM 并对接小程序渲染,如 KBone、Rax 运行时、Taro 3.x,这个方案理论上可以对接 react、vue、Angular 等任何上层框架。 小程序在帮助头部 App 建立起封闭流量体系的同时,也让国人第一次在跨端技术领域 “走在了世界前列”(手动狗头保命),各类开发框架、配套工程体系及魔改 DSL 在神秘的东方国度创造出了 “小程序宇宙”(Rax、Remix、wepy、mpvue、uni-app、Megalo、mpx、Chameleon、Taro,相信你还能说出不少),魔幻而现实。 自绘渲染阶段,如 Flutter/Qt。自绘本身不是个新词,在此把自绘和 H5、原生渲染并列也不够严谨,这里的 “自绘” 更强调不使用系统原生控件或 Webview 的渲染管线,而是依赖 Skia、Cairo 等跨平台图形库,自底向上自建渲染引擎、研发框架及基础配套的方式,解决跨端一致性问题。自绘渲染能作为一个独立阶段,很大程度上源于 Flutter 这个跨端研发新贵的崛起,双端一致、HMR、状态驱动,以及 Dart 带来的异步编程体验等特性迅速点燃了客户端研发领域。 然而自绘也并非万能,与 iOS/Android 原生设计语言分离,对于使用原生控件、遵循平台交互视觉标准的存量 App 接入不够友好,未来系统层面规范升级也需要投入更高成本适配;2020Q1 调研拿到的 反馈数据 显示,调试、Debug、崩溃、内存问题等 RN/Weex 曾经历的阵痛 Flutter 也一个不缺;从 社区层面 看,生态建设繁荣,但达到成熟的程度尚需时日。对于前端来说,Dart Framework 本身上手成本并不高,甚至相较客户端,前端能更快适应它的语法与设计模式,但 JS 的背后是标准与生态,切换到 Dart 远不只是学习一门新语言那么简单,而是庞杂生态秩序的重建。从数据上看,Flutter 虽然增长迅猛,但对 RN 等偏前端驱动的解决方案目前 有很多讨论,但没有造成太多冲击,而更多是替换掉了 Cordova/Xamarin 等传统解决方案,未来其在大前端领域的定位仍需摸索,与前端的关联关系也需我们更积极地探索。 其他涉及跨端的方案还有很多,如 Xamarin/SwiftUI/Kotlin/Qt/Unity/Electron 等,考虑到这些方案或不面向前端领域、或在国内缺少广泛受众和讨论、或不以无线领域为重点、或已进入衰退期,在此略过不表。 纵观跨端技术发展史,想象一根线段,左边是 H5,代表研发效率与动态性;右边是 Native,代表高性能与体验,这几年技术演进的过程,就是通过不断在两个端点间找寻更好平衡的过程,方案无绝对的好坏,而更多是看业务场景诉求,没有银弹,未来这些方案也将在很长一段时间内和平相处,共同构建起大前端的边界与生态。 阿里跨端方向现状与思考 阿里跨端技术发展脉络 财年初我们对经济体超过 25 个 BU/部门端技术现状进行了 1v1 沟通交流,从采样结果上看,91.7% 的团队业务涉及多 App 端(手淘、支付宝、飞猪、高德、钉钉...)投放场景,其中涉及大量工程能力不统一、跨端 API 不统一、跨端埋点/账号不统一等问题;在此基础上,超过 95.8% 的部门存在多渲染容器适配的场景,在一/二/三方容器选型不统一情况下需要同时兼容 Web/Hybrid/Weex/小程序等渲染方案,也暴露出多套 DSL 重复开发成本、性能体验不统一及搭建能力缺失等问题;同时,37.5% 的业务需要适配多种类型的设备,保障功能统一的同时,实现特性匹配的交互视觉,这类场景也面临着跨端适配能力、组件库缺失的高要求。传统角度看跨端技术,聚焦的点无非性能体验、一致性、研发效率,这些问题过去存在,当下存在,未来很长一段时间也会持续存在,阿里跨端技术经过多年发展,新的挑战也在不断涌现: 难以单纯依靠硬件升级解决性能体验问题。摩尔定律下硬件技术的突破没有带来预想中的性能体验问题默认解决,业务研发中,依然需要投入不小的精力进行针对性优化,究其原因,本质上是端技术架构与业务功能复杂度的提升对冲掉了硬件升级带来的性能红利。并且伴随移动互联网流量见顶,业务进入存量博弈阶段,复杂度会进一步提高,纯粹的 Web 解决方案天花板依然会长期存在,因此结合 PHA/SPA/SSR/Snapshot/Prerender 等方向,各业务独立定制容器侧渲染方案依然无可避免; 前端与无线不匹配的技术演进节奏,重构沦为常态。从 H5 与 Native 技术演进上看,前端技术更多聚焦在编程思想突破上(MVC/MVVM/reactive/one-way data flow),而容器技术更多聚焦在性能与体验上(Bridge/Native 化容器/自绘渲染引擎)。两者背后的主导力量不同,发展很难说是同步的,而新的编程思想与新的渲染容器技术往往都会带来新的解决方案、研发配套,直接导致 1)业务代码需要跟随两条主线频繁重构;2)演进与迭代过程中进一步加深跨端技术方案的碎片化,包括端内框架/容器的碎片化(稳定性风险),与跨端投放不同 App 异构解决方案的碎片化(高兼容成本)。 Flutter 等新物种对前端标准的冲击:作为跨端技术新贵,在性能体验接近原生、研发效率接近前端的基础上,通过自绘保障了双端一致性,对未来客户端研发提供了更好的选择。同时,面向未来 Flutter for Web 瞄准的是更大的领域空间,依靠 HTML Mode/WebGL Mode 两套方案有条不紊的推进,从前端角色角度看未来大前端格局迷雾重重,如何定位 Web 标准与 Flutter 之间的关系并协作共存,将是未来一段时间内必须直面的问题。 愈发多样化的设备与使用场景带来的兼容适配成本:伴随新零售业务的铺开,大量线下业务场景带来了各具特色的设备,以盒马业务距离,除了常规 Mobile 端外,还涉及 PC、Pad、RF、餐饮一体机及各类 OTT 设备,同时同样一个屏幕,使用者日常使用场景与屏幕距离的不同也需要对应的适配解决方案,甚至不同门店的光线差异也要考虑并妥善处理。 业务最本质的诉求,是在一套研发流程下,一份业务代码(哪怕对代码规范存在一定限制)可以跨端适配,同时在新的 App 或渲染容器方案之上,能够实现业务代码的无缝平迁。今年阿里前端委员会将跨端技术定为重点突破技术之一,期望在容器标准化、研发框架统一、配套设施完善、性能体验优化等方向形成一定突破,赋能各类业态实现更好更快增长。同时今年第 15 届 D2 前端技术论坛也对应推出跨端技术专场,与业内同仁共同分享、探讨一些跨端方向的新思路、新解法。 D2 跨端技术专场 本次 「15 届 D2 前端技术论坛-跨端技术专场」我们邀请了国内外一线技术专家,围绕性能体验度量、跨平台适配、跨端渲染、Flutter 等方向进行话题探讨,目前已入驻以下主题,更多高质量话题也会逐步放出: 主题:以全球 Web 角度谈前端性能的更新与趋势 讲师:Palances Liao,Google 资深 Web 技术专家。专注于 Web 前端技术及确保 Web 生态的完整性 ,同时为许多大型合作伙伴提供 Web 技术解决方案及分享 Web 技术。 简介:前端性能一直以来都是一个艰深的话题,除了各家都有自己不同的量测标准之外,怎样取得更精确的真实用户性能数据及通过工具的辅佐让我们更快速的调试成为了性能优化的一大难点。本专题会注重在 Google 如何定义性能指标,采集及提供优化性能的工具链如何帮助所有开发者快速调优前端性能,带来 Google 的最新研究。 主题:盒马多端一体化前端体验基建 讲师:景庄,阿里巴巴前端技术专家。目前负责盒马中后台多端体验基建产品 Hippo,包括多端一体化的设计体系和盒马工作台体验管理体系;Alibaba Fusion Design 技术体系前核心开发。 简介:实体零售数字化过程中,盒马对人货场进行了全新的重构,在多元的业态和作业场景中,传统中后台的体验边界也进一步被延展,前端不再单一面向单一类型设备进行开发与交付,而是需要触及到 TVPCPadPhonePOSRFWatch 等更多的智能设备。在盒马,我们通过构建多端体验产品 Hippo 去解决新零售科技场景下的多端内容交付与体验一体化的问题,本次分享主要介绍盒马的中后台跨端探索过程,包括多端统一的设计体系,可跨设备复用的组件架构,以及支持跨端协同的应用架构。 从 IE6 到 Chrome;从自动屏蔽图片的 wap 浏览器,到即用即走的小程序;从应用开发/UED 兼职写页面,到前端成为独立岗位,跨端这个话题几乎贯穿了前端技术发展的全过程。本次 D2 前端技术论坛也期待与更多开发者一起开拓视野、碰撞思想、凝聚共识,为构造更好的跨端技术生态,共同努力! 一起来 D2 跨端技术专场学习更多精彩内容

史上最快破5亿用户的互动 - 2020双11养猫技术大揭秘

作者 | 淘系-珑晴 在电商领域,互动是一个重要的用户增长方案,在提升用户黏性、活跃以及拉新上都发挥着重要的作用。今年双11,淘系互动团队推出了“超级星秀猫”,我们不盖楼、不开车,全民参与养猫出道,3只风格各异的萌猫咪一经问世,瞬间俘获了无数消费者的心。通过 EVA 互动体系一整套解决方案,大幅提升研发效率,支撑全民养猫猫在手淘、猫客、支付宝等多个 APP 互通。借助客户端能力及 EVA 互动体系将性能与内存良好控制,让多数用户体验高清稳定的互动,实现 0 故障及秒开,同时星秀猫参与人数再创新高。这篇文章将主要从页面渲染基建、EVA 研发体系和全局稳定性方案 3 个方面,来具体阐述淘系互动前端团队是如何做到双11互动又快又好又稳的。 页面渲染基建 不知道大家有没有发现,今年的双11养猫互动(以下简称双11互动)页面打开特别快,具体可看下面与去年双11互动主页在 iPhone 11 PRO 机器手机淘宝上的主页加载对比视频。不仅如此,还有个明显的变化是以往互动页面的标配--进度条没有了。 点击查看视频 互动主页加载对比,左:2019年双11,右:2020年双11,机型:iPhone 11 PRO 见多识广的你也许会问,是不是今年双11互动使用了 Native 版本?是不是今年双11互动使用了缓存方案?是不是今年双11互动也使用了预渲染技术?然而,答案是,都没有,今年双11互动与历年狂欢城一样,仍然是 web 页面,且资源全部走 CDN 无额外缓存。 那么,我们是如何做到如此顺滑的加载体验呢?这就要从 Solution 说起。 Solution 是天马搭建体系(https://zhuanlan.zhihu.com/p/137470317 )的概念,主要解决的问题是将模块+数据组合成页面,简单理解就是负责页面渲染 Layout。 自去年618起,淘系互动团队全部业务都开始迁移到天马搭建体系,Solution 也使用了官方推荐的通用 Solution。但是,通用 Solution 由于其通用性,冗杂了淘宝/天猫 60% 以上业务逻辑(粗略估计),体积大的同时易受其他业务影响导致稳定性风险高;而互动由于其业务特殊性,很多优化甚至稳定性保障方案的实现也需要在 Solution 层面进行定制。基于此,淘系互动团队定制了自己的页面渲染方案,即互动专用 Solution,这也是今年双11互动之所以那么快的核心原因。 得益于天马团队提供的新版 Solution 解决方案,既提供了标准化端渲染机制,又提供了基于插件进行业务定制的能力,还提供了产品化平台。互动专用 Solution 是在上述解决方案的基础上扩展实现,主要做了以下事情: 精简基础依赖/逻辑,去除非必要依赖及非必要逻辑 根据互动场景定制模块加载顺序,提供分批加载能力(当前主要是首屏/非首屏) 提供数据处理能力,通过去除渲染无关字段实现数据自动瘦身 内置基于客户端评分的稳定性保障方案,保障互动页面稳定性,详见下面稳定性方案章节 增加资源及模块加载监控,保障稳定性 集成互动通用能力,包括规范化 CSS/通用的渲染干预能力/常用的移动端调试方案/页面上下线能力等 EVA 研发体系 今年双11互动,非常多的用户反馈猫猫们太好看了、太萌了、特别可爱,很多人都纷纷来咨询小编是如何开发出来的。接下来将重点阐述双11星秀喵加工厂--EVA 研发体系,TA 是淘系互动团队提供的从素材上传到端上渲染的互动研发的一整套解决方案,以引擎、框架、工具、平台为支点,致力于为广大前端带来简单舒适的互动研发体验。 EVA 研发体系,提供互动研发一条龙服务,我们是认真的 EVA Store:素材上传服务 大家看到的星秀喵,并不是3D模型,而是如假包换的2D骨骼动画。它使用 Spine制作,通过网格自由变形和蒙皮技术在视觉上呈现“3D轴”的偏转,应用此类技术的动画软件还有大名鼎鼎的 Live2D。在 Spine 强大动画创作的支持下,双11的星秀喵才有了“3D化”的动画化表现力。一个标准的Spine动画文件包含一张雪碧图、一份骨骼数据以及一份动画数据,那么,我们应该如何上传到 CDN 呢? EVA 为了解决互动业务中常见且频繁的动画和模型素材,提供了一站式的素材上传服务 EVA Store,包括帧动画、雪碧图、DragonBones、Spine、音频等,这些互动素材的协议标准是由阿里巴巴经济体互动小组统一制定。 EVA JS:2D 互动引擎 互动引擎是互动研发的基础,一款好的互动引擎能大大降低研发成本,EVA JS 应运而生。EVAJS 是一款轻量级,用于开发互动游戏的前端框架。EVA JS 支持插件体系,所有的互动游戏能力都是由插件提供的。EVA JS 一方面能够让前端互动游戏开发更加专业,另外一方面帮助前端开发者无需深度学习互动游戏技术即可开发互动游戏。TA 的整体设计是以游戏行业最佳实践的 ECS 设计模式为基础,拆分核心功能和组件能力,按需使用。 EVA JS 引擎 值得一提的是,EVA JS 还提供了无障碍化的支持。以往,游戏区实现无障碍需要手动在图层上添加辅助 DOM 来指定无障碍内容。今年双11,EVA JS 研制了 Canvas 上的无障碍技术,能够在手机淘宝/支付宝客户端上自动识别无障碍对象上的交互事件,降低研发成本的同时,让广大有障碍人士也能全方位体验到撸猫的乐趣,真正做到了互动无障碍体验。 双11养猫无障碍体验 EVA JS 计划在2021年6月份前完成开源,了解更多,可参考 淘系前端互动引擎EVAJS架构与生态实现 。 Rax EVA:Rax 解决方案 素材和引擎都准备好后,就可以上手开始写代码了。市面上大多数的游戏引擎无法和 JSX、Hooks 结合在一起,这样,开发者就需要学习“两套框架”,再加上游戏引擎的学习成本也不低,整体上增加了开发门槛。为解决门槛高、上手难的问题,淘系互动前端团队设计了一套用于开发互动的 Rax 解决方案--Rax EVA,TA 是一个能够在Rax技术体系下,利用 EVA JS 的游戏研发能力,开发动画、游戏类场景的框架。它可以让开发同学用熟悉的 JSX 和 Hooks 语法编写动画、游戏场景的代码。 例如,我们把上一章节上传好的 Spine 动画显示出来(此处为示意版伪代码) import {createElement, render} from 'rax'; import DriverUniversal from 'driver-universal'; import {Eva} from '@ali/rax-eva'; import Spine, {useSpineResource} from '@ali/rax-eva-spine'; function App() { const catSrc = useSpineResource({ image: 'https://gw.alicdn.com/tfs/TB1YHC8Vxz1gK0jSZSgXXavwpXa-711-711.png', altas: 'https://pages.tmall.com/wow/eva/b8597f298a5d6fe47095d43ef03210d4.atlas', ske: 'https://pages.tmall.com/wow/eva/b5fdf74313d5ff2609ab82f6b6fd83e6.json', return ( <Eva width={750} height={1334} <scene> <Spine resource={catSrc} animationName='idle' anchorX={0.5} anchorY={1} /> </scene> </Eva> render(<App />, document.getElementById('root'), { driver: DriverUniversal, 另外,对于前端来说,DOM 和 CSS 有天然的排版能力,这也是它们的优势。而游戏引擎是通过图形引擎渲染的,并不具备 CSS 那样高级的排版能力。于是在整个游戏互动的项目里,即存在 Canvas 又存在 DOM+CSS,也就是所谓的混合开发。Rax EVA 也为这类混合开发提供了方便快捷的方式,在 EVA 组件内,使用background / hud 这两个原生标签划分了游戏区域Z轴方向的三层布局,在这两个标签内以及 EVA 组件外,任何DOM 标签或其他熟悉的 JSX 都可以照常使用。 互动项目分层最佳实践 EVA Ware:弹窗规模化生产 除了基础的游戏研发外,EVA 研发体系还提供了一系列的低代码工具或服务,其中表现尤为突出的就是在今年 618 互动中就表现优异的弹窗规模化生成方案(以下称 Super Modal)。 互动研发最大的工作量之一就是弹窗的开发,相比今年 618,今年双11互动弹窗数量更甚。得益于 Super Modal 在弹窗研发上的抽象,所有的弹窗样式都是在平台上简易拖拽复制生成,通过 DSL+Runtime 提供端上稳定的渲染服务。弹窗的样式、文案可以作为页面配置项快速修改,前端在开发弹窗功能时,不用过多关注弹窗的样式问题,专注于弹窗的显示、关闭逻辑即可。除此之外, Super Modal 还在今年 618 功能的基础上,增加了相对定位布局、自定义组件、弹窗队列管理器插件等功能,并提供了简单的项目管理能力,进一步降低了弹窗开发的成本。 了解更多,可参考 2020年618淘系技术分享-互动生产力进化之路。 全局稳定性方案 细心的同学会发现,今年双11互动主页动效特别多,除了开场视频外,养猫和比拼的主界面上每个区域都在各种动。你一定在好奇,为什么你没有感觉到卡或者出现闪退的情况呢?这一切的背后,除了手机淘宝客户端架构组底层升级外,也有全局稳定性方案在护航。 点击查看双11互动主页动效展示视频 互动场景中存在大量动效、视频,而过高的内存占用可能会引发客户端 crash 影响业务结果。一边是客户端需要更炫酷的玩法去支撑业务发展,一边是一些设备性能较差的用户反馈卡顿,如何让所有设备都能流畅的参与互动呢?比起不顾一切的上动效或是一刀切的砍玩法,显然存在一个更合理的选项--体验分级。淘宝技术质量团队提供了名为 Kite 的获取设备评分的统一降级 SDK,结合互动特性,如下图所示,我们将设备划分为 4 个等级,其中,容灾等级时页面将进入到一个异常兜底页面,用于应对一些低版本或者兼容性较差的机器场景。至此,我们完成了体验分级。 互动设备分级 接下来,就是针对不同设备等级的机型做不同降级方案,这也是互动的稳定性保驾护航重要的一环。基于客户端架构组提供的稳定性指标,我们需要整体考虑页面的内存、帧率、CPU 3 个指标,而动效、图片尺寸、游戏区画布尺寸、FPS 等配置则直接影响这 3 个指标的结果。然而,众所周知,在实际的开发过程中,对每张图片、每个动效做针对性的降级往往需要各种配置项,且人人参与,操作起来非常繁琐和耗时。因此,淘系互动前端团队在上面体验分级的基础上,通过 1 份静态全局降级规则 + 1 个运行时获取配置的稳定性保障 SDK,设计了一套完整的全局稳定性保障方案。 全局稳定性保障方案 正是这套稳定性方案,让双11互动在极大程度做到了高清互动、符合了架构组验收标准而且在线 22 天全程 0 故障。TA 让互动稳定性保障更加系统,也已经成为营销互动的标配。 今年双11整体节奏从之前的“光棍节”到今年的“双节棍”,在这样变化的背景下,今年双11互动依然做到了参与人数再创新高。未来,我们希望完善 EVA 体系,通过不同的技术方案不断地优化我们的开发方式和生产关系,逐渐让更多的人来开发互动,实现“人人可开发,处处有互动”。 第十五届 D2 前端技术论坛开放报名,速抢! X6 是蚂蚁金服 AntV 旗下的图编辑引擎,X 象形图编辑场景的关系链接,同时 X6 又是 G6 的孪生兄弟,所以沿用了 G6 中的 6,深究一下,6 源于《六度分隔理论》,表达了我们对关系数据、关系网络的敬畏和着迷。 更好的阅读体验请点击阅读原文至语雀文档。 图编辑也是图领域一个重要方向,许多流程图、关系图绘制场景都需要它。基于蚂蚁内部的机器学习算法建模平台多年的可视编排能力打磨,我们决定把其中的图编辑内核抽取出来,图编辑 X6。 提炼后经过近一年的内部业务打磨,我们完善了图编辑场景的常用扩展,如小地图、网格系统、对齐线、框选、撤销/重做等,内置了图编辑场景的常规交互和设计,如群组、链接桩、节点缩放、旋转、连线交互,并提供了基于 HTML 和 React 低成本定制节点能力。今天我们很高兴能为可视化开源社区带来 X6 1.0 正式版本,请多关照! 欢迎给我们 GitHub 仓库(https://github.com/antvis/x6)加星 只需要掌握创建画布、添加节点/边、更新节点/边、删除节点/边这几个 API 即可开始使用 X6,并且我们将 X6 所有特性提取到画布的配置项中,一共包含 50 多个配置选项,基于这些配置项我们可以快速定制出自己的画布。详情请参考快速上手教程。 节点、连线与画布,图编辑核心能力 易定制的节点 X6 预置了一些常用节点样式,创建节点时通过 shape 来指定使用哪种图形来渲染节点即可,而且绝大部分节点样式和交互都可被自定义。 我们可以基于 path、 polygon 和 polyline 三个基础图形扩展出更多图形。然而,实际业务场景中的节点可能要更复杂,预置样式不满足需求?没关系,我们还提供了两种灵活的自定义节点的方式。支持使用 HTML 渲染节点,使用时将 shape 指定为 html 即可;另外还可以使用 React 组件来渲染节点,使用时需要安装并引入x6-react-shape,配合咱家 antd 更是天生一对哦。 使用 HTML 和 React 渲染节点 丰富的连线和箭头 内置了丰富的箭头和连线样式,分别可以参考箭头使用教程、路由使用教程和连接器使用教程。其中路由将边的路径点做进一步处理,并在必要时添加额外的点,并返回处理后的点。然后连接器将边的起点、路由处理后的路径点、终点连接成一条完整的连线。同时我们也提供了对应的扩展能力,详情参考自定义箭头教程、自定义路由教程和自定义连接器教程。 网格和背景 网格是节点在画布中定位时最小像素单元,例如当节点的位置是 {x: 12, y: 18} 网格大小为 5 时,那么节点渲染到画布的实际位置将是 {x:10, y: 20}。X6 默认提供了 dot,fixeDdot, mesh 和 doubleMesh 四种风格的网格,并且支持自定义网格大小和颜色。更多详情请参考网格使用教程。另外,如果内置网格样式不满足业务需求,我们还提供了定义和使用自定义网格的机制。 灵活易用的网格系统 同时可以为画布指定背景颜色和背景图片,例如我们可以指定画布背景颜色为 #fcfcfc,同时将 AntV 的 Logo 作为画布的背景图片,设置背景图片的透明度为 0.2,并以水印的方式重复显示。更多背景相关设置请参考背景使用教程,另外我们也提供了自定义背景图片显示方式的接口。 背景颜色和背景图片 交互能力与配套组件,图编辑不可或缺 链接桩是节点上的固定连接点,很多图应用都有链接桩,并且有些应用还将链接桩分为输入链接桩和输出连接桩。创建节点时我们可以通过 ports 选项来配置链接桩。可以指定链接桩的位置,如链接桩位于节点顶部和底部,同时也可以为链接桩指定标签。更多详情请参考链接桩使用教程和链接桩布局选项。 输入和输出链接桩 沿椭圆均匀布局的链接桩 动态添加/删除链接桩 链接桩高亮和自动吸附 我们可以通过父子嵌套来实现群组,支持通过交互拖拽成组,支持限制群组内的子节点的移动范围或自动扩展/收缩父节点的大小,另外也可以通过节点中的展开/折叠按钮来展开/折叠群组,更多详情请参考群组使用教程。 限制子节点移动 自动扩展父节点 展开/折叠 点选/框选 点击节点/边时选中节点,按下 Cmd/Ctrl 连续点击可以同时选中多个节点,开启 rubberband 选项后支持框选能力。更多详情请参考点选/选框使用教程。 撤销/重做 撤销/重做是图编辑场景的常用能力,在 X6 中可以通过 history 配置项来开启撤销/重做能力,更多详情请参考撤销/重做使用教程。 撤销/重做 对齐线是移动节点排版的辅助工具,默认禁用,可以通过 snapline 配置项开启和定制对齐线的样式。更多详情请参考对齐线使用教程。 小地图是完整画布的预览,可以通过平移缩放小地图的视口来平移缩放画布,支持渲染粒度定制和样式定制,即是否在小地图中渲染节点/边,节点的细节粒度等,例如下面案例中使用色块来代替了每个节点。更多详情请参考小地图使用教程。 还有更多配套的交互组件,如剪切板、拖拽、键盘快捷键、鼠标滚轮缩放画布等,请点击对应的链接查看。 UI 组件 搭建一个复杂的图编辑应用还需要用到 Menubar、Toolbar、Dropdown、ContextMenu、Splitbox 等 UI 组件,我们在 x6-react-components 中提供了一些这样的 React 组件,可以搭配 antd 使用。点击下面链接查看每个组件的使用文档。 Menu 菜单 Dropdown 下拉菜单 ContextMenu 右键菜单 Menubar 菜单栏 Toolbar 工具栏 ColorPicker 颜色选择器 SplitBox 包含分割条的容器 ScrollBox 自定义滚动条的容器 AutoScrollBox 自动根据内容大小设置和更新滚动条的容器 颜色选择器 自由灵活的扩展能力 X6 设计之初就充分考虑了可扩展性,精心设计了简单、高可拓展的接口。属性、连接桩布局、连接桩标签布局、节点锚点、边的锚点、连接器、路由、箭头、网格、背景、工具等都可以通过注册机制灵活扩展。有了这些扩展能力,发挥你的想象力,在 X6 这颗种子上生出无限的可能。下面是用 X6 实现的桑基图: 福利来了,三个应用场景 DEMO 上面分享了那么多特性,那如何快速将 X6 应用到自己场景中呢?最快的方式莫过于“拿来主义”,所以我们在配套源码中提供了流程图编排、DAG 图编排和 ER 图渲染三个应用场景 DEMO,我们可以从这三个 DEMO 开始定制自己的应用。更多场景的应用我们正在筹备中,同时也欢迎大家给我们贡献场景案例。 流程图,流程编排场景。有向无环图(DAG 图),算法建模场景。ER 图,ER 建模场景。 非常感谢你的耐心阅读,X6 还是个新生儿,虽然内测版早已在内部数据研发(ER图)、运维中台(流程图)等多个产品应用上线,但相信还有很多问题有待完善,欢迎在 GitHub 给我们反馈问题。 AntV 2020 品牌日的发布详情 利业·立业 - AntV 与业务的故事:https://www.yuque.com/antv/blog/2020story G2Plot 2.0 全新来袭https://www.yuque.com/antv/blog/2020g2 F2Native 1.0 新的起点https://www.yuque.com/antv/blog/2020f2 G6 栈:图可视分析如此简单https://www.yuque.com/antv/blog/2020g6 X6 1.0 抱歉来晚https://www.yuque.com/antv/blog/2020x6 L7 2.3 业务为本完善生态https://www.yuque.com/antv/blog/2020l7 AVA 1.0 你的图表参谋https://www.yuque.com/antv/blog/2020ava 欢迎关注我们的 GitHub 项目,点亮 star 了解我们的实时动态,期待 PR: AntV 官网:https://antv.vision/ G2:https://github.com/antvis/g2G2 是一套基于可视化编码的图形语法,以数据驱动,具有高度的易用性和扩展性,用户无需关注各种繁琐的实现细节,一条语句即可构建出各种各样的可交互的统计图表。 G2Plot:https://github.com/antvis/g2plotG2Plot 的定位是开箱即用、易于配置、具有良好视觉和交互体验的通用图表库。 F2:https://github.com/antvis/f2F2 是一个专注于移动,开箱即用的可视化解决方案,完美支持 H5 环境同时兼容多种环境(node, 小程序,weex)。完备的图形语法理论,满足各种可视化需求。专业的移动设计指引为你带来最佳的移动端图表体验。 F2Native:https://github.com/antvis/F2NativeF2Native 是一个专注于客户端,开箱即用、高性能的可视化解决方案,完备的图形语法理论,满足你的各种需求,专业的移动设计指引为你带来最佳的移动端图表体验。 G6:https://github.com/antvis/g6G6 是 AntV 旗下的图可视化与图分析引擎,G 来自于 Graphic、Graph ,意味着我们要基于图分析技术做图可视化;6 来自于《六度分隔理论》,表达了我们对关系数据、关系网络的敬畏和着迷。 Graphin:https://github.com/antvis/graphinGraphin 是一个基于 G6 封装的关系可视分析工具 ,简单,高效,开箱即用,取自 Graph Insight,图的分析洞察。 X6:https://github.com/antvis/X6X6 是 AntV 旗下的图编辑引擎,提供了一系列开箱即用的交互组件和简单易用的节点定制能力,方便我们快速搭建 DAG 图、ER 图、流程图等应用。 L7:https://github.com/antvis/l7L7 是一个基于 WebGL 的开源大规模地理空间数据可视分析开发框架。L7 中的 L 代表 Location,7 代表世界七大洲,寓意能为全球位置数据提供可视分析的能力。 AVA:https://github.com/antvis/AVAAVA 是为了更简便的可视分析而生的智能可视化框架。 G:https://github.com/antvis/gG 是 AntV 几个产品共同的底层 2D 渲染引擎,高效易用,专注于图形的渲染、拾取、事件以及动画机制,给上层 G2、F2、G6 提供统一的渲染机制。 ChartCube:https://chartcube.alipay.comChartCube 是一个可以快速完成图表制作的在线工具,只需要三步就可以创建出高品质的图表。 关注「Alibaba F2E」把握阿里巴巴前端新动向

更好的阅读体验请点击阅读原文至语雀文档。 F2Native,开箱即用的跨平台高性能可视化解决方案,国民级应用支付宝上的图表组件,在经历3代架构的升级和大量的优化后,终于正式开源 !!!。完美支持 Android、iOS 平台。完备的图形语法理论,满足你的各种可视化需求。 首先,欢迎大家来给我们的 GitHub 仓库加星和收藏,F2Native 官网:https://f2native.antv.vision/ 同样欢迎大家收藏和转发。 F2 是面向移动端的数据可视化解决方案,目前 F2 已经很好的满足了 H5 和小程序的数据可视化需求,但是在蚂蚁集团的整个业务场景中还存在着大量 Native 平台的图形需求,这些需求是 F2 覆盖不到的,如何系统化地解决这些问题,一直是我们困扰的问题,因此我们需要有一套系统化的方案来解决这些问题。 F2Native 的演进史 1.0 时代 - 纯 Native 图表 稍微回溯下历史,F2Native 项目最早起源于支付宝财富业务线,财富业务有大量金融相关的可视化需求,其中最典型的场景是股票的分时趋势图及 K 线蜡烛图。因为我们没有系统化的方案来解决这些场景,所以当时主要的解决方案是针对每种图表类型实现单独的计算逻辑封装,底层的渲染能力直接采用原生系统提供的 Canvas,特图特做,快速迭代来满足业务的需求。 在业务需求的背景下,我们沉淀了一套金融领域的可视化图表:虽然基本需求能够得到满足,但是问题也随之而来。在 Android 和 iOS 平台是不同的计算逻辑和绘制策略,最终的表现始终有一些差异;研发效能上,也需要同时投入双倍工作量来实现一个功能。为了解决这些问题,我们开启了 2.0 时代的升级。 2.0 时代 - 跨平台 在 1.0 时代我们积累了很多图表类型的实践经验,不同的图表类型在计算逻辑和绘制策略上也存在很多共性。在 2.0 的版本中我们把这部分共性的计算逻辑用 C++ 重新实现,极大的降低了双端分别实现带来的差异性。同时底层的渲染能力也由双端系统的 Canvas 调整为基于 OpenGL 的指令调用,在绘制策略也实现了双端的统一。 但是随着集团整体业务的发展,不断有其他业务线的同学过来咨询现有的图表组件能否支持他们的需求。这其中,一部分是我们没有实现过的类型,一部分是在现有的基础上做一些调整,但人力有限,不可能每次都针对具体的需求不断进行资源投入。大家越来越迫切的需要一套完整的图表解决方案。 3.0 时代 - 可视化图表解决方案 因为 F2 在业务中已经有大量的实践和经验,图形语法也在一线开发人员中得到越来越多的关注和认可,但是这些实践和经验却无法触达到 Native 场景,我们希望在 Native 场景也能享受图形语法带来的便利。在充分探讨用 C++ 重新实现图形语法的可能性,并经过半年多研发和业务场景验证后,我们正式推出全新的 Native 端数据可视化解决方案- F2Native。 F2Native F2Native 结合了原生系统的高性能渲染能力,完美支持 Android、iOS 平台,同时保持和 F2 一致的图形语法实现及 AntV 可视化设计准则,为你带来开箱即用的可视化解决方案,满足你的各种可视化需求。利用图形语法的灵活性,不再采用特图特做的方案之后,图表的表达完全由业务方自行完成图形语法的组合实现,带来了丰富和灵活的图表类型。 跨平台的 2D 绘制引擎 由于原生系统没有一个标准统一的多端 Canvas 解决方案,为了保持跨平台表达的一致性,F2Native 对接了 Alibaba 开源的 GCanvas 跨端渲染引擎。GCanvas 基于 OpenGL 实现了完整的 Canvas 能力,能够同时运行在 Android/iOS 操作系统上,并且已在支付宝等应用上广泛使用。 同时 F2Native 底层实现可插拔的设计,能够灵活的对接其他的引擎。对于业界其他的解决方案可实现无缝切换。 完善的图形语法理论 同 F2 一样,我们抛弃了传统的特图特做的封装思路。基于强大的图形语法理论,以数据驱动,通过图形语法的组合灵活构建各类图表, 当前可绘制以及正在实现的图表类型有 50+ 种,覆盖各类场景(当然我们也在持续完善中)。更多细节可参考官网图表示例。 继续前进的 F2 无障碍的 F2 支付宝作为一款有着亿级用户数的APP,如何让视障人士也能更好地获取平台提供的信息,享受技术带来的便利一直是我们追求的目标。在F2 3.8.0以后,我们新增了图表的无障碍的处理,可以在代码中非常方便地开启和使用: // 示例代码 const chart = new F2.Chart({ id: 'container', pixelRatio: window.devicePixelRatio, aria: true // 开启无障碍文本生成 开启后会生成: 这种可被读屏设备阅读的表述文案。 示例参考:https://f2.antv.vision/zh/examples/column/basic#aria 方便的横竖屏切换 你是否遇到过因为数据量太大从而导致图表过密进而影响阅读的场景,然而当你想横屏展示的时候又受限于外部容器无法横屏而导致无法实现呢,F2 带来了全新的横屏解决方案,纯依赖 css3 的 transform 来实现不受容器限制的横屏解决方案: 示例参考,横屏图: https://f2.antv.vision/zh/examples/creative/case/#landscape 可拓展的渲染引擎 在移动端的大部分场景,Canvas 往往都是最优的选择,因为在小屏幕下 Canvas 的性能表现是最优的,而 F2 底层的绘制用的也是 Canvas,然而随着场景的丰富和业务的复杂,我们发现在一些特殊场景还是需要有其他的渲染引擎支持,比如 SVG 等,所以在新版 F2 中,我们独立了底层的渲染引擎,并可注册添加和使用,也可自行实现属于自己特有的渲染引擎: 以 SVG 为例,只需要简单的注册便可使用: import F2 from '@antv/f2'; import * as SVGEngine from 'f2-svg-engine'; // 引入并注册 svg 渲染引擎 F2.G.registerEngine('svg', SVGEngine); const chart = new F2.Chart({ el: container, // 指定渲染引擎 renderer: 'svg', 完成之后 F2 就会通过指定的渲染引擎进行绘制和渲染: 首先 F2Native 还是个新生儿,还有很多场景等着我们去覆盖和实现,我们会进一步地把这些场景覆盖掉,让我们在业务中能更方便地去使用,我们也会尽全力去保证 F2Native 的进一步成长。 F2 作为移动端可视化解决方案的先驱,会继续深耕在移动端数据可视化领域,后面我们会继续往 low code 方向做进一步尝试和探索,进一步提升业务研发效率。第二,我们会尝试建立一套 F2 的组件化方案,能让你方便和快捷的开发 F2 组件,从而能为业务做进一步的定制和扩展。 AntV 2020 品牌日的发布详情 利业·立业 - AntV 与业务的故事:https://www.yuque.com/antv/blog/2020story G2Plot 2.0 全新来袭https://www.yuque.com/antv/blog/2020g2 F2Native 1.0 新的起点https://www.yuque.com/antv/blog/2020f2 G6 栈:图可视分析如此简单https://www.yuque.com/antv/blog/2020g6 X6 1.0 抱歉来晚https://www.yuque.com/antv/blog/2020x6 L7 2.3 业务为本完善生态https://www.yuque.com/antv/blog/2020l7 AVA 1.0 你的图表参谋https://www.yuque.com/antv/blog/2020ava 欢迎关注我们的 GitHub 项目,点亮 star 了解我们的实时动态,期待 PR: AntV 官网:https://antv.vision/ G2:https://github.com/antvis/g2G2 是一套基于可视化编码的图形语法,以数据驱动,具有高度的易用性和扩展性,用户无需关注各种繁琐的实现细节,一条语句即可构建出各种各样的可交互的统计图表。 G2Plot:https://github.com/antvis/g2plotG2Plot 的定位是开箱即用、易于配置、具有良好视觉和交互体验的通用图表库。 F2:https://github.com/antvis/f2F2 是一个专注于移动,开箱即用的可视化解决方案,完美支持 H5 环境同时兼容多种环境(node, 小程序,weex)。完备的图形语法理论,满足各种可视化需求。专业的移动设计指引为你带来最佳的移动端图表体验。 F2Native:https://github.com/antvis/F2NativeF2Native 是一个专注于客户端,开箱即用、高性能的可视化解决方案,完备的图形语法理论,满足你的各种需求,专业的移动设计指引为你带来最佳的移动端图表体验。 G6:https://github.com/antvis/g6G6 是 AntV 旗下的图可视化与图分析引擎,G 来自于 Graphic、Graph ,意味着我们要基于图分析技术做图可视化;6 来自于《六度分隔理论》,表达了我们对关系数据、关系网络的敬畏和着迷。 Graphin:https://github.com/antvis/graphinGraphin 是一个基于 G6 封装的关系可视分析工具 ,简单,高效,开箱即用,取自 Graph Insight,图的分析洞察。 X6:https://github.com/antvis/X6X6 是 AntV 旗下的图编辑引擎,提供了一系列开箱即用的交互组件和简单易用的节点定制能力,方便我们快速搭建 DAG 图、ER 图、流程图等应用。 L7:https://github.com/antvis/l7L7 是一个基于 WebGL 的开源大规模地理空间数据可视分析开发框架。L7 中的 L 代表 Location,7 代表世界七大洲,寓意能为全球位置数据提供可视分析的能力。 AVA:https://github.com/antvis/AVAAVA 是为了更简便的可视分析而生的智能可视化框架。 G:https://github.com/antvis/gG 是 AntV 几个产品共同的底层 2D 渲染引擎,高效易用,专注于图形的渲染、拾取、事件以及动画机制,给上层 G2、F2、G6 提供统一的渲染机制。 ChartCube:https://chartcube.alipay.comChartCube 是一个可以快速完成图表制作的在线工具,只需要三步就可以创建出高品质的图表。 关注「Alibaba F2E」把握阿里巴巴前端新动向

AntV 年度发布:利业·立业 - AntV 与业务的故事

作者 | 步茗 AntV 是一个数据可视化项目,也是一个团队,蚂蚁集团数据可视化团队,一群有爱有梦的人,怀揣「让人们在数据世界里获得视觉化思考能力」的梦想前行, 希望成就智能时代全球领先的数据可视化解决方案,满足与日俱增的数据洞察需求。 AntV 目前覆盖了统计图表、移动端图表、图可视化、地理可视化、2D 绘图引擎和智能可视化多个领域,主要包含 G2栈、F2栈、G6栈、X6栈、L7栈、AVA 以及一套完整的图表使用和设计规范。得益于丰富的业务场景和用户需求挑战,AntV 经历多年积累与不断打磨,已支撑起阿里集团内外 20000+ 业务系统,通过了日均千万级 UV 产品的严苛考验,是阿里经济体数据可视化最重要的基础设施。 跟往年的品牌日一样,今天依旧会有几个底层基础类库的大量更新发布,除此之外,非常高兴的向大家介绍 AntV 产品矩阵上新添两个新成员: F2Native,开箱即用的跨平台高性能可视化解决方案,国民级应用支付宝上的图表组件; X6,底层基于 SVG,脱胎于蚂蚁实际的业务场景,专注图编辑领域的组件库; 从 2017.11.22「 开源·开放 」、2018.11.22「 知新·知心 」到2019.11.22「 知源·致远 」,这是 AntV 的第4个品牌日,今年的主题是「 利业·立业 」我们想和大家分享 AntV 将数据可视化能力赋能蚂蚁集团、阿里集团内部业务的故事。 2015 年初,刚刚具备雏形的 G2 被投入到了一些蚂蚁内部业务中去试用,但是用户反馈性能很差。于是我们开始自研底层渲染引擎 G。一年后,G2 2.0 已经支持了很多零散的内部需求。2016 年,口碑网的一个客户平台带着对图可视化的强需求找到了 AntV,于是有了 G6。自此,源源不断的业务诉求开始推动着 AntV 产品矩阵蓬勃发展。 图形语法、商业智能 G2 所负责的基础统计图表是前端可视化业务最高频的场景、最核心的战场。大量管理界面、数据产品都需要使用统计图表,但是其中最重度的业务必然是 BI 商业智能产品。2016 年底,蚂蚁集团大数据部启动 BI 产品 DeepInsight 的第三个大版本,使用社区开源的可视化方案,接入大量可视化组件,大大增强产品的数据可视化能力。然而在逐步的产品迭代和演进过程中,大量的可视化问题暴露出来,主要集中在图表的丰富度问题、图表体验问题和多维探索分析能力。为了解决这些问题,AntV 与 DeepInsight 深度合作,DeepInsight 的同学深入到 G2 栈参与技术研发。 G2 基于图形语法的可视化实现形式在内部是有争议的。固然,图形语法保证了它的灵活性,但当业务上的开发同学想要使用 G2 时却遇到了学习成本和门槛过高的问题。一直以来,AntV 都在探索灵活性与低门槛的平衡。2019 年,我们推出了基于图表分类的配置式可视化库 G2Plot,其底层依赖于 G2。自此,G2 栈拥有了两种产品形态:G2 面向追求灵活度和专业度的可视化工程师,而 G2Plot 提供更快捷、更友好的业务可视化开发能力。 G2Plot 被很多业务方寄予厚望,但它的进展并不顺利。去年我们摸索着完成了它的 1.0 版本发布,然而由于零散的细节需求从大量不同的业务涌入,AntV 的研发同学很难在各种时限的要求中做到完美的架构设计。伴随着各种各样的吐槽,反而让我们坚信这是一个对的产品方向。2020,在之前的经验和教训之上,G2Plot 不仅做了全新的设计,而且还充分发动了社区的力量来参与研发。研发团队做了大量的竞品调研、业务需求分析、细节设计打磨,力求做到我们承诺的“默认好看、默认好用”。G2Plot 2.0,今天,它来了。 近年来蚂蚁业务持续高速增长,人员紧缺。为了高效支撑各业务线前端业务开发的战场,自从去年 AntV 与 Ant Design 联姻以来,我们推出了 Ant Design Charts,可以理解为这将是整合 AntV 整个技术栈为一体的 React 版图表类库。它迎合业务而生,对内支撑着云凤碟和 TechUI, 对外和 Ant Design 形成闭环,已经是很多公司的不二之选。从对内的 0.x 版本到目前的 1.x 版本,经历了无数次打磨,基础统计图表功能上完全透出 G2Plot 的能力, 同时结合 G6 库,希望她能延续 Ant Design “低门槛,高效率”的美好特性。 在帮助业务研发提效方面,AntV 的投入可谓“不惜成本”。业务爆发增长过程中的一些创业型战场可能出现产品、设计甚至专业前端人员缺失的场景。这些业务也有数据可视化的需求,而他们更加需要 AntV 的支持。为此,AntV 开始探索智能可视化、自动可视化的场景。去年 SEE Conf 大会我们公开了 AVA 智能可视化框架,期望帮助开发人员自动推荐图表,甚至“一行代码完成图表开发”。经过一些内部场景的试水,今天我们也开源了 AVA 的 1.0 版本。AVA 也将支持 DeepInsight 的增强分析场景,期望能在前沿业务中快速成长。虽然这一条路还很长很长,但我们会持续努力,终有一天从“稚嫩”走到“智能”。 图分析、图编辑 大约在 2017 到 2018 年,随着关系网络和图分析的普及,涌现出许多有图可视化需求的业务场景。图(graph),是一种实体之间的关系网络数据,在可视化中主要以节点和连线组合成的图形形式出现。业务中往往包含大量的、错综复杂的关系数据,对它们进行可视化是一个很大的挑战,但也是一个重要的需求。 2018 年初,许多业务在做技术选型的时候开始对比国外的工具和 AntV 的新成员 G6。网商银行的新业务需要基于图的风控分析系统和基于关系的故障定位系统,于是开始尝试接触图可视化和 G6。当时 G6 3.0 还在规划,需求是通过 G6 2.0 版本来进行开发的。整个过程比较顺利,但是由于 G6 能力的限制,在需求上砍掉了两个功能:一个是布局不理想,一个是动画效果。业务方的开发同学在布局上花了很大的力气也没有找到一个合理的布局算法,最后就去看开源的布局算法代码,自己定制。当时的 G6,对于业务方开发来说仅仅是提供了图的基础渲染机制,要实现复杂的能力还需要投入非常多的精力和时间。同样对 G6 能力的局限性感到遗憾的还有一些图分析产品,许多业务使用的是 React 技术栈,但是当时 G6 还没有针对 React 提供一些开箱即用的组件。 虽然年轻的 G6 还有很多不足,但是 AntV 的同学一直在努力建设。有时业务方提出的需求,第二周就得到了特性 Demo,这给了许多业务方信心。2019 年,图可视化相关的业务爆发了。知识图谱、流程绘制、图数据库、关系分析等等相关业务和需求都开始使用 G6。蚂蚁有一个金融知识图谱相关的业务,在外部组件和 G6 之间反复横跳,但是最终因为看到了其他产品上 G6 日益精进的表现而选择了 G6,并且连业务方的设计师也投身了 AntV 参与图可视化设计规则的制定。除了蚂蚁的设计师,阿里集团的设计师也贡献了力量。阿里云的智能研发平台 DataWorks 和机器学习平台 PAI 都有大量场景,比如业务流程编辑、图数据搜索、数据血缘展示等等。这些业务设计师的领域专业经验沉淀到了 G6 3.0 版本中,AntV 和业务一起打磨和革新,G6 一直在成长。 如今,在迈向第四个版本的路上,G6 已经在功能特性、易用性及性能等方面都有了很大的提升。刚出道时被诟病布局问题,如今已经支持了各种布局算法;早期不支持 React 生态,现在也有了开箱即用的 Graphin;至于交互、动画方面,现在也有了丰富而有用的交互能力。 图编辑也是图领域一个重要方向,许多流程图、关系图绘制场景都需要它。基于蚂蚁内部的机器学习算法建模平台多年的可视编排能力打磨,我们决定把其中的图编辑内核抽取出来,成为 AntV 继 G6 图分析的另一个图可视化领域分支,图编辑 X6。经过近一年的内部业务打磨,X6 在功能、性能、生态等方面也都已经比较完整。今天我们很高兴能为可视化开源社区带来 X6 1.0 正式版本,请多关照! 除此以外,AntV 在集团内外已经发展出了蓬勃的图可视化生态,业务类型覆盖云安全、企业风控、图数据库、金融风控、知识图谱、性能优化等大量场景。汇集大量产品设计和技术研发经验,近30位产品经理、设计师和工程师的通力合作,我们积累出《AntV 图可视化解决方案白皮书 1.0》。这可能是国内出品最完整的一套图可视化解决方案白皮书,今天我们也将开放出来,希望能帮助更多业务拥有更科学高效的图可视化能力。 设计与责任 针对一些特定的场景案例,我们还做了很多细节的设计打磨。比如在监控场景中,由于真实数据的不可控性与实时性,往往存在着数据信息过于密集难辨认,或者在某一时间点突然出现极值(数值徒增),而导致整个图表难以阅读的情况。我们通过 Y 轴缩略轴和列表式图例等交互形态,从设计上解决了这类问题。再比如,在数据分析场景中,用户往往需要对某一指标进行多维监控。环绕关键指标查看衍生指标、拆分维度、观察时序趋势、作进度跟进,这些都可以通过指标卡来完成。AntV 基于业务场景提炼出一套灵活多变的指标卡,它可以演示成各种不同的指标卡类型,从而解决这一大类问题。 另外,我们今年的官网改版,把重点放在了文档和示例体验上。这是 AntV 被诟病最多的地方,我们内部认真梳理了各技术栈的文档,希望改善研发者的开发体验,让图找到使用场景,让开发者找到 API。今年官网文档全面升级为交互式文档,通过图文合一的方式,希望能给开发者带来更流畅的体验。 支付宝作为拥有亿级用户的国民应用,一直非常重视社会责任,AntV 也不例外。移动端图表库 F2 今年收到过一个用户反馈,在支付宝某页面板块中的图表不支持盲人阅读。相关的同学马上动手完成了 F2 的无障碍处理。站在业务的角度,让视障用户也能享受技术带来的便利是我们的责任。 技术研发要从业务中来、到业务中去,我们只有贴近业务,才能看清动向。技术研发还要走在业务需求的前面,当用户的诉求来临时我们早已为你做好准备。既要为业务创造价值,也要把自己做成一个好工具,AntV 一直在服务业务的道路上前行。 AntV,蚂蚁集团、阿里集团数据可视化基础设施。 AntV,一群有爱有梦的人,怀揣「让人们在数据世界里获得视觉化思考能力」的梦想前行。 AntV,利业 · 立业! AntV 2020 品牌日的发布详情 利业·立业 - AntV 与业务的故事:https://www.yuque.com/antv/blog/2020story G2Plot 2.0 全新来袭https://www.yuque.com/antv/blog/2020g2 F2Native 1.0 新的起点https://www.yuque.com/antv/blog/2020f2 G6 栈:图可视分析如此简单https://www.yuque.com/antv/blog/2020g6 X6 1.0 抱歉来晚https://www.yuque.com/antv/blog/2020x6 L7 2.3 业务为本完善生态https://www.yuque.com/antv/blog/2020l7 AVA 1.0 你的图表参谋https://www.yuque.com/antv/blog/2020ava 欢迎关注我们的 GitHub 项目,点亮 star 了解我们的实时动态,期待 PR: AntV 官网:https://antv.vision/ G2:https://github.com/antvis/g2G2 是一套基于可视化编码的图形语法,以数据驱动,具有高度的易用性和扩展性,用户无需关注各种繁琐的实现细节,一条语句即可构建出各种各样的可交互的统计图表。 G2Plot:https://github.com/antvis/g2plotG2Plot 的定位是开箱即用、易于配置、具有良好视觉和交互体验的通用图表库。 F2:https://github.com/antvis/f2F2 是一个专注于移动,开箱即用的可视化解决方案,完美支持 H5 环境同时兼容多种环境(node, 小程序,weex)。完备的图形语法理论,满足各种可视化需求。专业的移动设计指引为你带来最佳的移动端图表体验。 F2Native:https://github.com/antvis/F2NativeF2Native 是一个专注于客户端,开箱即用、高性能的可视化解决方案,完备的图形语法理论,满足你的各种需求,专业的移动设计指引为你带来最佳的移动端图表体验。 G6:https://github.com/antvis/g6G6 是 AntV 旗下的图可视化与图分析引擎,G 来自于 Graphic、Graph ,意味着我们要基于图分析技术做图可视化;6 来自于《六度分隔理论》,表达了我们对关系数据、关系网络的敬畏和着迷。 Graphin:https://github.com/antvis/graphinGraphin 是一个基于 G6 封装的关系可视分析工具 ,简单,高效,开箱即用,取自 Graph Insight,图的分析洞察。 X6:https://github.com/antvis/X6X6 是 AntV 旗下的图编辑引擎,提供了一系列开箱即用的交互组件和简单易用的节点定制能力,方便我们快速搭建 DAG 图、ER 图、流程图等应用。 L7:https://github.com/antvis/l7L7 是一个基于 WebGL 的开源大规模地理空间数据可视分析开发框架。L7 中的 L 代表 Location,7 代表世界七大洲,寓意能为全球位置数据提供可视分析的能力。 AVA:https://github.com/antvis/AVAAVA 是为了更简便的可视分析而生的智能可视化框架。 G:https://github.com/antvis/gG 是 AntV 几个产品共同的底层 2D 渲染引擎,高效易用,专注于图形的渲染、拾取、事件以及动画机制,给上层 G2、F2、G6 提供统一的渲染机制。 ChartCube:https://chartcube.alipay.comChartCube 是一个可以快速完成图表制作的在线工具,只需要三步就可以创建出高品质的图表。 关注「Alibaba F2E」把握阿里巴巴前端新动向

曾经在PC时代通过模板同步渲染实现页面秒出基本是标配,但由于移动端的网络和运行环境条件受到地域,设备的影响参差不齐,再加上手机相比于电脑的屏幕差距对页面的响应要求更高,为了减少页面大小以及配合离线技术和前后端分离,移动端H5页面静态资源分离和异步渲染逐渐成为默认的标准。 而为了满足在2G,3G的弱网条件页面可用性,提高响应速度,静态资源离线成为移动端体系下一个黑科技,并逐渐发展为各个App的通用能力,有了离线能力及时是在弱网或者无网的情况下,依然可以给到用户响应(无网下是一个打底页),离线能力在过去至少5年的时间一直是移动端H5技术体系下不可或缺的一环。 另一方面从12年all in 无线以来,移动端的环境也逐渐发生着巨大的变化,手机硬件的升级日新月异,配合着webview的优化,页面的渲染不断加速,4G的普及和5G的到来也让网络延迟降到个位数毫秒级,于此同时我们也在不断思考在未来网络和终端下前端页面的渲染应该是什么样的?后离线时代我们的备选方案是什么? 于是Serverless Faas和React/Rax SSR的结合实现页面的同步渲染成为我们的一个探索方向,Node Faas SSR同构实现一套代码两端运行解决复用的问题,Serverless的低运维,弹性伸缩解决SSR对机器Cpu消耗高的难题,所以今年9月开始我们在调研之后,选择对接淘系提供的比较成熟的营销域SSR方案在飞猪双十一会场落地实践。 当前营销体系的问题 整体链路耗时长 基于上图可以大致看出,目前飞猪营销搭建的页面真实的渲染并不是直接在接口数据返回后执行的,还需要拉取依赖的模块缓存,然后再进行页面的render,整个过程串行进行,耗时很长且不稳定。从今年国庆会场的整体性能数据上也可以看出,首屏模块load耗时Android 500-600ms、iOS 400-500ms,首屏mtop耗时均值在 300ms左右,整体首屏时间 Android 2s左右、iOS 1.5s左右,所以用户进入页面到真的能够看到页面,基本需要在1s以上,这还是在端内有接口prefetch和模块缓存的数据,在端外体验问题更加严峻 而现在基于各类数据统计都告诉我们页面加载时间增加,会导致更多的用户流失。 页面 snapshot 的不足 为了减少页面loading过长的情况,营销页面做了首屏html的本地缓存,使得用户再次进入页面时减少等待,但缓存方案存在以下问题。 缓存的方案需要用户进入过一次页面,并成功缓存了html才有效,所以该方案无法解决用户第一次进入页面时等待时间较长的问题,且由于使用缓存,若用户清除缓存或是缓存存储失败,那仍然无法减少用户后续进入时的等待时长。 缓存只能存储上一次进入的数据信息,而目前飞猪营销页面,大量的投放数据都是基于个性化算法投放,缓存数据与真实数据的不一致会使页面重新渲染,尤其是当页面模块有明显变化时,重新渲染带来的页面闪烁感会更明显。 SSR 的方案设计 基于以上的问题,我们希望能够通过SSR将html片段生成放在服务端执行,以此优化渲染时间,主要分析如下: 客户端渲染快慢非常受容器影响,也就是我们常说的高端机快,低端机慢,但是当渲染放在了服务端上,这个容器的影响就可以规避。 从飞猪链路上可以看到,容器渲染前模块load的时间消耗,而这块耗时平均在300ms上下,端侧渲染,每一次http请求的建立都会有较长的时间损耗,而在服务端渲染,这段时间的消耗可以通过服务器来避免。 由于纯粹的SSR直出页面对定位和个性化场景的改造较大以及和离线,prefetch体系的不兼容,所以我们选择借助天马的异步ssr的方案,在现有的搭建链路上,增加ssr render的链路,在mtop数据中返回首屏的Html Str直接插入到页面中,这样在端内可以借助离线和prefetch加速页面秒出的过程。 MTOP:阿里内部移动端统一的API网关 优点:链路改造成本低,模块基本复用,可使用端上现有的离线包、prefetch等优化手段,页面url无变化,走mtop链路无需额外处理数据安全。 缺点:接口耗时增加,因为在mtop中返回html,数据量和耗时都会升高。 落地过程的疑难问题 原因:飞猪模块中,有许多模块直接使用了rax的原生picture组件,基础组件在web渲染时会根据端判断是否支持webp而加上webp的后缀,而在ssr渲染时,具体的端判断为false,所以ssr下图片无webp后缀,图片链接的变化导致了图片闪烁。 改造方案:不再直接使用基础picture组件,而是使用业务定制组件,确保图片的剪裁、后缀拼接在ssr及web上保持一致。 沉浸式 titlebar 的支持 飞猪营销页面中,尤其是大促时的会场页面,会有大量的沉浸式titlebar使用场景,而前端titlebar的实现,是通过桥方法的调用,由容器告知原生titlebar以及状态栏的高度,而在ssr渲染时,服务器无法通过桥与容器进行交互拿到状态栏高度,这成为了ssr支持沉浸式的一个问题。 方案探索: 方案一(不可行):发起mtop前,在页面调用桥信息获取titlebar高度,通过mtop传递给ssr服务层,但是由于页面会有prefetch的开启,所以端上会直接请求mtop,而不是一定先经过页面的,所以会导致prefetch的页面没有titlebar信息带给mtop。方案二:从solution执行链路上发现其实ssr返回的html在注入页面后,到web的真实render之间是会有一个空隙的,而这段时间是已经在真实的web层的,是可以获取到真实的容器titlebar高度信息的。 实际改造方案 在ssr层,我们根据容器、以及沉浸式参数匹配,在ssr层注入titlebar的占位dom,并给上一个默认高度。 在web层,ssr html注入完成后,获取真实的titlebar高度,dom操作原有的默认高度,将其变为真实的占位高度,使其和web时渲染的titlebar高度一致。 // 示例代码 // server render function renderTitlebarP(type, stickyPaddingTop) { return ( <Fragment> {type === 1 ? <View className="ssr-title-bar-main" style={{ position: 'fixed', top:0, height: 0, left: 0 }} /> : null} <View className="title-bar ssr-title-bar" style={{ width: '750rpx', height: stickyPaddingTop + 'rpx',// stickyPaddingTop 为不同状态titlebar时的默认高度 position: 'relative' }} /> </Fragment> // web render if (如果有html返回) { const pageContent = document.getElementsByClassName('mui-zebra-page-content')[0]; pageContent.innerHTML = html; // ssr的html注入后页面后,获取真实的不同机型的titlebar(含状态栏)的高度stickyPaddingTop // dom操作ssr的html ssrTitlebar.style.height = `${stickyPaddingTop}px`; // 拉取模块,并render web fetchAndEvalJS(seedComboUris, { sequence }).then(() => {render(<PhoneApp />)}) titlebar 改造引发新的问题 setAttitude的使用:改造方案中由于对dom操作中使用setAttitude进行了style的改变,但是由于rax组件在生成时会有一些属性的注入,使用setAttitude会造成style的结构变化,触发重选渲染,因此出现页面闪烁。 解决:改用 A.style.xxx 来最小力度改变想改的属性,避免重排。 页面模块重复 dom不一致:titlebar的判断中,使用了大量的端判断,而端判断是基于容器的ua,而在ssr层通过mtop获取的ua是不一样的,导致titlebar的判断上端判断不一致,因此返回的dom不一致,而这里需要提到rax的hydrate,他是通过比对dom顺序进行,导致如果渲染的两份dom顺序不一致,就会出现两份dom的重复情况。 // mtop ua "MTOPSDK/1.9.3.48 (iOS;14.0;Apple;iPhone11,8)" // window "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1" 飞猪离线原理,统一渲染页html离线,ssr作为页面开关会,当命中飞猪离线时会以离线的统一渲染页的页面开关为准。 增加ssr上的白名单链接配置,确保只有指定的页面会真的进行ssr 链路的render。 会场 SSR 数据表现 根据线上页面的数据对比,我们发现开启了SSR的会场的可见时间都在1s以下,极大优于传统的首屏时间。 同一页面(wifi下)实验数据 从整体会场性能和单页面的对比可以看到,异步ssr的方案会带来mtop耗时的上升,因为html在接口中返回,增加了接口数据大小,但是由于直接返回了html,节省了原有的模块拉取再render页面结构的时长,所以整体的页面可见时间仍然较原来有了提升,基本都能达到1s内可见。 iphone8 安卓(p30 pro) 服务端相关:性能和稳定性 RT:SSR服务耗时之前压测时平均在30 - 40ms,线上由于页面复杂度不同稍有变化,目前日常在49ms 。 CPU:SSR是密集计算型操作会比较耗CPU,所以相比普通函数,会给SSR函数提供更多的机器量。 弹性伸缩:第一次压测有验证弹性缩扩容的能力,在弹起的瞬间失败率上升较快,而且由于CSE双十一降级自动扩容能力,所以我们最终使用机器固定容量,并采用单机限流的方式。 超时容灾:SSR作为会场性能的增强能力,为了在极端情况下不影响页面的功能,我们设置了SSR的60ms超时,也就是超过60ms的请求走正常的CSR渲染链路。 降级预案:为了应对突发情况,配置了关闭整体SSR的预案开关,用作紧急情况的降级。 同步 SSR 支持目前方案的首屏可见时间虽有优化,但仍然受限于接口传输的影响,而端外场景无法使用任何其他优化手段减少接口传输的时长,后续会在端外尝试直接服务端渲染方案,而不是通过接口返回html方案。 页面 AB 效果目前页面ssr功能开启仅通过开关开启,并未支持同一页面同时开启ssr/关闭ssr的ab能力,后续AB能力的支持来做更有效的业务效果对比。 SSR 能力搭建基础化作为页面性能优化的基础能力提供给搭建页面使用,减少现在白名单配置以及人肉check的成本。 性能优化SSR在服务端执行的速度还需要持续优化,另外函数迁移到FC利用其弹性扩容的能力解决机器不足和浪费问题。 在目前多端多适配前端技术体系下,客户端预渲染、Weex、Flutter 可能难以成为解决多端秒出的方案,通过拥抱原生html渲染技术配合Faas SSR面向未来网络条件布局,是前端页面性能往前再走一步的尝试突破,而这也是在Serverless概念热火朝天的当下云+端的最佳实践之一,从试点到通用再到普惠,刚刚走出第一步,前路漫漫仍需努力。 第十五届 D2 前端技术论坛开放报名,速抢!

双十一会场体验 SSR 优化 - 走向更复杂的渲染架构

作者 | 霸剑、步峰 会场是每年双十一的主角之一,会场的用户体验自然也是每年最关注的点。在日趋复杂的业务需求下,如何保障我们的用户体验不劣化甚至能更优化是永恒的命题。 今年(2020)我们在不改变现有架构,不改变业务的前提下,在会场上使用了 SSR 技术,将秒开率提高到了新的高度(82.6%);也观察到在用户体验得到优化的同时,业务指标如 UV 点击率等也有小幅的增长(视不同业务场景有不同的提升,最大可达 5%),带来了不错的业务价值。 本文将从服务端、前端两个角度介绍我们在 SSR 上的方案与经验 前端在解决工程化、业务效果评估上的具体实践与方法论 服务端在解决前端模块代码于服务端执行、隔离和性能优化上的具体实践与方法论 页面体验性能的核心指标 在正文开始前我们先介绍一下衡量的相关指标,从多年前雅虎 yslow 定义出了相对完整的体验性能评估指标,到后来的谷歌的 Lighthouse 等新工具的出现,体验性能的评估标准逐渐的统一且更加被大家认同。 会场的评估体系 基于 Web.Dev 以及其他的一些参考,我们定义了自己的简化评估体系。TTFB(Time to First Byte): 第一个字节的时间 - 从点击链接到收到第一个字节内容的时间 FP(First Paint): 第一次绘制 - 用户第一次看到任何像素内容的时间 FCP(First Contentful Paint): 第一次内容绘制 - 用户看到第一次有效内容的时间 FSP(First Screen Paint,首屏可视时间): 第一屏内容绘制 - 用户看到第一屏内容的时间 LCP(Largest Contentful Paint): 第一次最大内容绘制 - 用户看到最大内容的时间 TTI(Time To Interactive): 可交互时间 - 页面变为可交互的时间(比如可响应事件等) 大体上来说 FSP 约等于 FCP 或 LCP。 会场的现状 我们的会场页面是使用基于低代码方案的页面搭建平台产出的,一个由搭建平台产出的会场页面简单而言由两部分组成:页面框架(layout)和楼层模块。页面框架有一份单独的构建产物(即页面的 layout html 以及基础公共的 js、css 等 assets 资源)。每个楼层模块也有单独的一份构建产物(模块的 js、css 等 assets 资源,基础公共 js 的依赖版本信息等)。 页面框架的任务比较繁杂,负责页面的 layout、根据页面的搭投数据加载具体哪些楼层模块并组织分屏渲染模块。 会场原有的 CSR 渲染架构如下图,可以分成三部分: 客户端,包括手机淘宝等阿里系 App 文档服务,用于响应页面的主文档 HTML 清求 数据服务,用于响应页面的数据请求 原有的CSR渲染流程如下图针对会场的性能,除了基础的大家都知道的前端优化手段之外,还结合客户端能力做过很多优化方案,比较具有代表性的有两个: 客户端主文档/Assets 缓存 在客户端内,我们利用了端侧提供的静态资源缓存能力,将 HTML 和基础公共的 JS 等资源,推送下发至用户侧客户端缓存。当客户端的 WebView 请求资源时,端侧可根据规则来匹配已下发的缓存包,在匹配成功后直接从本地缓存中读取对应的 HTML 和 JS 资源,而无需每次都请求网络、大大缩短了页面的初始化时间。 数据预加载 从用户点击跳转链接到页面开始加载数据,中间还要经过客户端动画、WebView初始化、主文档 HTML 请求以及基础公共 js 的加载和执行这些过渡阶段,加起来有 几百ms 的时间被浪费掉。通过客户端提供的数据预加载能力,在用户点击后就可以立即由 native 开始页面的数据加载,等页面的基础公共 js 执行完需要使用页面数据时,直接调用 jsbridge 接口即可从 native 获取已经预先加载好的数据。 在这些优化工作的基础上会场的体验性能已经可以达到不错的水准。 随着时间的推移,基于我们 CSR 渲染体系下的优化存在一些瓶颈: 在线上复杂网络环境下(低网速、虚假的 WiFi)、Android 中低端机上的页面体验还是不尽人如意,特别是模块的加载和执行时间比较长,且这部分用户的占比有增长趋势 作为拉新的一个重要手段,外部唤起淘宝或者天猫客户端因为需要时间来初始化一些功能组件,比如网络库等,页面的体验从体感上不能追平端内的会场 会场是营销活动性质的业务,页面的复访率相对较低,且页面内容全面个性化。离线的 HTML 快照等用户侧缓存手段会因为缓存的数据过期导致出现重复渲染(打开更慢)、页面元素跳动(渲染闪烁、重排)等伤害体验的问题 还有没有优化手段呢?以一个 2020 年双十一会场页面,使用 PC 上的 Chrome DevTools 的 performance 离线分析结果为例,我们看一下重点的问题。 可以看到页面从 FP 到 FCP 这段过渡的时间较长且只有背景色。FCP 到 LCP 这段时间处于等待图片加载的时间,优化空间较小,且难以衡量。 离线分析尚且如此,线上更有着复杂的网络环境/差异化的手机机型等,这样的“背景色”时间对用户的体验有很大的伤害,可能会让用户更加容易跳失。 我们的 CSR 渲染体系依赖前端+客户端的能力,从工作机制上已经很难再有比较大的提升。怎么才能让会场页面的体验更上一层楼呢,我们想到了服务端渲染(SSR), 针对 FP 到 FCP 这段时间进行攻坚优化。 SSR 的线下测试结果,FP 到 FCP 从 825ms -> 408ms 。 SSR 要怎么做? SSR 本身意为服务端渲染,这个服务端可以在 任何地方 ,在 CDN 的边缘节点、在云上的中心机房或者就在你家的路由上。 实现一个 SSR 的 demo,熟悉的人应该都知道套路: 搞一个 Rax Server Renderer,传入一个 Rax Component,renderToString,完事了 业界也已经有很多实践的案例,但就像“把大象装进冰箱里”一样,看似简单的事情在双十一所要求的复杂场景稳定性下,需要有稳妥可实施的执行方案。 如何在现有的这套模块化、成熟的渲染架构之上使用SSR呢,一开始我们往常规的思路去想,直接在文档 HTML 响应中返回服务端渲染完成的 HTML,看下来存在几个问题: 改造成本高,对现有的服务端架构改动比较大(CDN 缓存失效,文档服务的要求更高) 无法复用现有的客户端性能优化能力,比如客户端主文档/Assets 缓存和数据预加载能力,会劣化完全可交互时间 CDN 缓存无法利用,TTFB 的时间增加,带来了新的 “完全白屏阶段” SSR 服务不稳定因素较多,自动降级为CSR的方案复杂,无法保证 100% 能够降级 主文档 HTML 的安全防护能力较弱,难以抵御黑产的恶意抓取 基于以上的问题,我们考虑是否还有其他的方案可以 低风险 、 低成本 地实现SSR呢?经过短暂且激烈的讨论,我们设计了「数据 SSR」架构方案,分享给大家。 数据 SSR 渲染架构如下,文档服务返回的内容保持静态化不变,数据服务新增调用一个独立的 SSR FaaS 函数,因为数据里有这张页面包含的模块列表和模块需要的数据,SSR FaaS 函数可以直接根据这些内容动态加载模块代码并渲染出 HTML。 这套方案在客户端内的场景下可以很好的将 前端 + 客户端 + 服务端三者的能力结合到一起。 有人可能会问,为什么这个方案会带来性能提升呢?不就是把浏览器的工作移到了服务端吗?我们举个例子(数据仅为定性分析,不代表真实值)。在正常 CSR 渲染流程下,每段消耗的时间如下,首屏可视时间总共耗时1500ms。在SSR渲染流程下,在「调用加载基础js」之前的耗时都是一样的,由于下面两个原因,在服务端渲染的耗时会比客户端低几个数量级。 服务端加载模块文件比在客户端快很多,而且服务端模块资源的缓存是公用的,只要有一次访问,后续所有用户的访问都使用这份缓存。 服务端的机器性能比用户手机的性能高出几个数量级,所以在服务端渲染模块的耗时很小。根据线上实际耗时统计,服务端单纯渲染耗时平均 40ms 左右。 由于 HTML 被放到了数据响应中,gzip 后典型值增加 10KB 左右,相应的网络耗时会增加 30~100ms不等。最终 SSR 的渲染流程及耗时如下,可以看到 SSR 首屏的可视时间耗时为660ms,比CSR提升了800ms。总而言之,「数据 SSR」的方案核心哲学是:将首屏内容的计算转移到算力更强的服务端。 大方向确定了,我们再来看看 SSR 应用到生产中还存在哪些核心问题 如何做到 CSR/SSR 的平滑切换 开发者如何开发出“能 SSR”的代码 开发者面向前端编写的代码在服务端运行的不可控风险 低代码搭建场景下,在服务端解决楼层模块代码加载的问题 服务端性能 怎么衡量优化的价值 别急,我们一个一个的来看解法。 如何做到 CSR/SSR 的平滑切换? 在我们的页面渲染方案中,有两个分支: 页面未开启数据SSR,则与原有的 CSR 渲染流程一样,根据数据中的模块列表加载模块并渲染 页面开启了数据SSR并且返回的数据中有 SSR HTML,则使用 SSR 的 HTML 塞入到 root container 中,然后根据数据中的模块列表加载模块最终 hyrdate。 优点很明显 风险低,能够无缝降级到CSR,只需要判断数据接口的响应中是否成功返回 HTML 即可。如果 SSR 失败或者超时(未返回 HTML),通过设置合理的服务端超时时间(例如 80ms),不会影响到用户的最终体验 能够利用端上成熟的性能优化能力,比如客户端缓存能力,数据预加载能力。有客户端缓存能力,页面的白屏时间与原CSR一致;有了数据预加载能力,能够在页面加载之前就开始请求数据服务 在线上服务时,我们可以通过 HASH 分桶的方式对流量进行划分,将线上的流量缓慢的切换到 SSR 技术方案,既能保证稳定性,同时还可以方便的进行业务效果的进一步评估。 比较好的字符串转换为数字的 HASH 方法有 DJBHash,验证下来分桶效果较为稳定。 开发者如何开发出“能 SSR”的代码? 很多做 SSR “demo”分享的往往会忽略一个重要点:开发者。 在双十一的场景下,我们有百+的开发者,三百+的楼层模块,如何能推动这些存量代码升级,降低开发者的改造适配成本是我们的一个核心方向。 我们原有的楼层模块构建产物分为 PC/H5/Weex 三个,业界通用的是针对 SSR,单独构建一个 target 为 node 的构建产物。在实际 POC 验证过程中,我们发现其实绝大部分的模块并不需要改造就可以直接适配 SSR,而新增构建产物会牵扯到更多的开发者,于是想找寻别的解决方案。复用现有 Web 构建产物的一个问题是,Webpack 4 默认会注入一些 Node 环境相关变量,会导致常用的组件库中的类似const isNode = typeof process !== 'undefined' && process && process.env 的判断异常。不过还好这个是可以关闭的,开发环境下其他的类似devServer 等的注入也是可以关闭的,这给了我们一点慰藉,最终复用了 Web 的构建产物。像更新的 Webpack 5 中把 target 的差异给弱化了,也可以更好的定制,让我们未来有了更好的社区化方向可以继续靠拢。 解决完构建产物的问题,在本地开发阶段,Rax 团队提供了 VSCode SSR 开发插件,集成了一些 best practice 以及 lint 规则,写代码的时候就可以发现 SSR 的相关问题,及时规避和修复。同时我们模拟真实线上的环境,在本地提供了 Webpack 的 SSR 预览调试插件,直接 dev 就可以看到 SSR 的渲染结果。 针对开发者会在代码中直接访问window 、location 等变量的场景,我们一方面开发了统一的类库封装调用抹平差异,另一方面在服务端我们也模拟了部分常用的浏览器宿主变量,比如window 、location 、navigator 、document 等等,再加上与 Web 共用构建产物,所以大部分模块无需改造即可在服务端执行。 接下来的模块发布阶段,我们在工程平台上增加了发布卡口,若在代码静态检查时发现了影响 SSR 的代码问题就阻止发布并提示修复。 由于实际的业务模块量较大,为了进一步缩小改造的范围,测试团队联合提供了模块的批量测试解决方案。具体的原理是构造一个待改造模块的 mock 页面,通过比较页面 SSR 渲染后的截图与 CSR 渲染后的截图是否一致,来检测SSR 的渲染结果是否符合预期。 开发者面向前端编写的代码在服务端运行的不可控风险 尽管我们在开发阶段通过静态代码检查等方法极力规避问题,实际上仍然存在一些针刺痛着我们的心: 开发者把全局变量当缓存用造成内存泄露 错误的条件结束语句导致死循环 未知情况页面上存在不支持 SSR 的模块 这些疑难点从 SSR 的机制上其实很难解决,需要有完善的自动降级方案避免对用户的体验造成影响。 在说更详细的方案前要先感谢我们自己,前端已经提前做到了 CSR/SSR 的平滑切换,让服务端能每天不活在恐惧里 = = 对于机制上的问题,可以引申阅读到之前分享过的 《在 Node.js 中 ”相对可靠” 的高效执行可信三方的代码》。我们这里主要聚焦在如何快速止血与恢复。FaaS 给服务端降低了非常大的运维成本,“一个函数做一件事”的设计哲学也让 SSR 的不稳定性局限在了一块很小的部分,不给我们带来额外的运维负担。 低代码搭建场景下,在服务端解决楼层模块代码加载的问题 业界分享的一些 SSR 场景基本都是整页或者 SPA 类型的,即 SSR 所使用的 bundle 是将整页完整的代码构建后暴露出一个 Root Component,交由 Renderer 渲染的。而我们的低代码搭建场景,由于整个可选的模块池规模较大,页面的楼层模块是动态选择、排序和加载的。这在前端 CSR 情况下很方便,只要有个模块加载器就可以了,但是在服务端问题就比较复杂。还好我们的模块规范遵守的是特殊的 CMD 规范,有显式的依赖关系声明,可以让我们在获取到页面的楼层组织信息之后一次性的把页面首屏的全部 Assets 依赖关系计算出来。 示例的 CMD 规范显式依赖关系(seed) "packages": { "@ali/pcom-alienv": { "path": "//g.alicdn.com/code/npm/@ali/pcom-alienv/1.0.2/", "version": "1.0.2" "modules": { "./index": [ "@ali/pcom-alienv/index" 在服务端加载到代码后,我们就可以拼装出一个 Root Component 交给 Renderer 渲染了。 服务端性能 性能上主要是有几个方面的问题 由于楼层模块很多,在实际执行的过程中发现存在一些机制上的性能问题 代码的 parse 时间较长且不稳定 流量较低情况下难以触发 JIT 优化方案的话比较 tricky 缓存 vm.Script 实例,避免重复 parse 期望一致性 HASH 或自动扩缩容(本次未实现) 巡检的时候还观测到存在小范围的 RT 抖动问题,分析后定位是同步的 renderToString 调用在微观上存在排队执行的问题在这种情况下会造成部分渲染任务的 RT 为多个排队任务的渲染 RT 叠加,影响单个请求的 RT(但不影响吞吐量)。这种问题要求我们需要更精确的评估备容的资源。机制上有效的解法推测可以让 renderToString 以 fiber 的方式执行,缓解微观排队造成的不公平的问题。 性能问题的分析当然免不了 CPU Profile,拿出最爱的 alinode 进行分析,很快的可以找到热点进行针对性优化。上图中标蓝的方法为 CMD 加载器计算依赖的热点方法,对计算结果进行缓存后热点消除,整体性能提升了 80% 怎么衡量优化的价值 这么多的投入当然需要完善的评价体系来进行评价,我们从体验性能和业务收益两个分别评估。 基于兼容性较好的 PerformanceTiming (将被 PerformanceNavigationTiming 替代),我们可以获取到前端范畴下的一些关键的时间 navigationStart firstPaint 其中 navigationStart 将会作为我们的前端起点时间所使用。在前端之外,对用户的交互路径而言真正的起点是在客户端的点击跳转时间 jumpTime ,我们也联合客户端进行了全链路埋点,将客户端 native 的时间与前端的时间串联了起来,纳入到我们的评价体系中。 在最开始的核心指标中,我们看到有 FCP、TTI 这几个指标。目前的 Web 实现中,还未有兼容性较好的可以线上衡量的方案(线下可以使用 DevTools 或者 Lighthouse 等工具),因此我们通过其他的方式来做近似代替。 componentDidMount innerHTML to Body componentDidMount componentDidMount 线上取到的数据通过 tracker 的方式进行无采样上报,最终我们可以通过多个维度进行分析 是否命中 SSR 是否命中其他前端优化 主要的衡量指标有 从用户点击到 FCP 的时间(FCP - jumpTime) 从 NavigationStart 到 FCP 的时间(FCP - NavigationStart) 这部分很忐忑,体验的优化是否会带来真金白银的收益呢?我们直接通过 AA 和 AB 实验进行业务数据的分析。 基于之前的切流分桶,我们可以通过类似 hash 值 % 10 的方式将流量分为 0~9 号十个桶,首先通过 AA 实验验证分桶是否均匀 这一步是保证分桶的逻辑本身不会有数据的倾斜影响置信度。接下来我们再进行 AB 实验,逐步增加实验桶验证业务数据的变化。 最终的效果 搞了这么多,得看看产出了。在这次双十一会场中,我们切流了多个核心的页面,拿到的第一手数据分享给大家。 潮流女装会场 从用户点击到 FSP 的时间小于 1s 的比例 iOS 66%Android 28% iOS 86% +30%Android 60% +114% UV 点击率提升 为了更好的用户体验,当然会了!我们可以简单的看看短期和长期的一些事情。 电商体验指标的统一定义 长期以来,业务在用户侧的实现有 Web、Native、Hybrid 混合开发等多种选择,每个体系都有着自己的封闭体验衡量标准,这就造成了一些“鸡同鸭讲”的问题。而 Web.dev 中所定义的 FCP、LCP 通用评价体系也并不适合电商场景,能展示出核心的商品/店铺其实对一张页面来说就完成了它的使命。 后续我们可以将体验指标评估标准对齐,将起点时间、绘制完成时间等在多个体系对齐概念与实现,达到互相之间可以横向比较良性竞争的状态。 工程上还有更多的事情要做... 在 Webpack 5 的 Release Note 中,我们可以看到 Webpack 正在弱化 target 的一些特殊处理,将 Web 描述为了 browserlike 的环境。同时还提供了自定义 browserlist 的能力,可以给予开发者更方便处理跨端的兼容性问题的能力。这一变化将推动我们更快的拥抱社区,获得更好的开发体验。 现有的 SSR 静态代码检查方案会有一些漏网之鱼,还有没有更完善的方案能从工程上前置解决代码风险(性能、安全)问题也是未来的一个方向。 ServiceWorker Cache 离线缓存快照 复访率高,变化不太大的页面可以利用 ServiceWorker Cache 等方案,将之前的渲染结果缓存下来,命中缓存直接用,未命中缓存 SSR。降低服务端压力的同时可以让体验更好。 SSR 的性能优化与安全 现阶段的 Node.js 或者说 V8,对于动态加载代码的情况支持并没有特别的完善,缺失了安全相关的保护逻辑。并且从性能上来说,SSR 属于 CPU 密集型的 workload,纯异步的优势并不明显,也可能需要一些特殊的解决方案来配合。 外部投放场景的覆盖 「数据 SSR」的方案是端内的最佳方案,却是外投场景的最劣方案。外投场景下由于用户是在第三方 App 中打开页面,相应的缺失了客户端的定制化优化能力,SSR 调用会造成数据服务的 RT 增加,反而推后了 FCP。 这时候古老的 HTML 直出方案又可以再捞回来了。核心在于 利用 CDN 的边缘计算能力,可以较好的做到“动静分离”以及容灾 使用中心化的 SSR 函数,可以将 SSR 的不稳定性与 CDN 的可靠性分离,保证近端链路的可靠,避免出现近端直接不可用导致的无法恢复 近端的流式方案经常被提及,但是在实际的使用中会遇到当流式输出遇到错误时,用户侧无法有效容灾的问题(HTML 损毁,无法补救)。通过“动静分离”可以将页面分为仅将 Root Container 进行动态化,进而在享用流式输出带来的 TTFB 提前的好处的同时又能兼顾容灾 SSR 的不稳定。和业务团队更可以一起探讨下如何将页面更好的从业务上做到“动静分离”,而不是仅从技术的角度出发。 渲染架构的不断改进实质上是我们在有限且变化的环境下(终端性能、复杂网络和多变业务)自发做的适应,也许有那么一天,环境不再是问题,性能优化的课题将会消失。我们项目组有时候还开玩笑,等明年手机叒换代了,5G 100% 普及了,是不是这些优化都可以下线了 但是!现在看理想还有点远,在 2020 的双十一会场我们走进了一个新的深水区,期待未来技术与业务结合能带给广大用户更棒的体验! 第十五届 D2 前端技术论坛开放报名,速抢! 关注「Alibaba F2E」把握阿里巴巴前端新动向

4982亿背后的前端技术—2020天猫双11前端体系大揭秘

作者 | 双11前端PM-海文 今年双11的整体节奏从之前的“光棍节”变为“双节棍”,具体业务上也有很多变化和调整,应了阿里的土话“唯一不变的是变化”。面对这些变化,是挑战也是机会,我们要做的就是,“既要”高效支撑保障业务先赢,“又要”确保体验和稳定性带给用户极致体验,“还要”追求创新让前端持续演进。为了实现“既要、又要、还要”,包括技术方案、流程机制、人员组织等各方面都进行了大量的设计和保障。最终第一次双峰的双11圆满结束,淘系前端也实现了自己的目标,包括应用大量优化手段和创新方案带来业务转化提升;将FaaS、PHA、ESR等技术应用在更多场景,分别向服务端、客户端、CDN节点进一步拓展了前端的能力和边界;应用视觉还原、一体化研发等提升研发效率,大幅缓解资源瓶颈等等。下面会整体介绍一下淘系前端在今年双11的思考和沉淀,希望对大家有所助益。后续也会有各个专项的系列文章,希望大家持续关注。 变化 & 挑战 今年的双11,首先感受到的就是源源不断的变化。 单峰变双峰:双11从之前的一个波段变成今年的两个波段,大促的三个阶段预售、预热、正式也都对应的翻倍。首先带来的是研发工作量的大幅增加,在时间排期不变、工作量增加、人员不变的情况高效的完成需求研发是第一重挑战;其次面对6个阶段的状态变化,如何保持准确切换、稳定运行、体验流畅是在双峰期间要重点保障的内容;最后面对超过20天的超长作战期,安全生产、人员状态保持、快速反应都需要有强力的组织和机制进行保障。 图:双11节奏 首页大改版:最新的淘宝首页首屏内容有颠覆性的变化,比如首屏内容简化,推荐提前,频道作为内容嵌入推荐等。各个业务在缺少固定的流量入口的情况下,包括运营策略、产品策略、设计方案、技术方案都需要积极调整。同时在各个场景的推荐能力也需要持续增强,今年双11通过将坑位数扩展到1000+,理论可达无限扩坑;通过智能UI提升用户点击率。业务变化:业务创新和新玩法层出不穷,包括mini详情、旗舰店、价格表达、笔笔返、芝麻购等在内的很多业务都是全新的表达、颠覆式的升级。即是业务上新的尝试,在技术上也要解决架构选型、对账、一致性表达、排期等问题。 首先要做的就是做好本职工作,保障需求研发和稳定性。需求研发方面,我们通过D2C实现了大部分UI模块自动开发、通过建设Eva互动体系降低互动研发成本、通过Serverless的一体化研发提升研发和运维效率,使前端不再成为资源瓶颈。稳定性上,也通过一系列机制和工具体系进行保障。同时增加一块大家平时可能不太关注的资损防控的策略和方案。 D2C 研发提效 去年双11我们设立了研发效率专项,核心就是通过 设计稿生成代码(Design to Code, D2C)平台 Imgcook 来提升研发效率。最终在去年的双11大促会中承接了 78.94% 的新增模块代码自动生成,代码可用率达到 79.34%。 今年前端智能化助力前端研发模式升级,数个 BU 共建前端设计稿识别算法模型和数据集,设计稿生成代码技术体系全面升级,如对 UI 多态、直播视频组件、循环的智能识别增强等。今年双11会场承接了 90.4% 的新模块代码智能生成,代码可用率达到 79.26%(对比去年升级设计稿智能检查能力,视觉稿无需人工辅助调整)。得益于D2C的研发提效,今年并没有出现往年借调资源投入会场开发的情况。相比传统模块开发模式,使用设计稿生成代码技术后编码效率(模块复杂度和研发耗时比值)提升68%,固定人力单位时间模块需求吞吐量增加约 1.5 倍。 图:D2C操作流程 互动研发升级 在电商领域,互动是一个重要的用户增长方案,在提升用户黏性、活跃以及拉新上都发挥着重要的作用。今年双11,淘系互动团队推出了“超级星秀猫”,我们不盖楼、不开车,全民参与养猫出道,3只风格各异的萌猫咪一经问世,瞬间俘获了无数消费者的心。通过 EVA 互动体系一整套解决方案,大幅提升研发效率,支撑全民养猫猫在手淘、猫客、支付宝等多个 APP 互通。借助客户端能力及 EVA 互动体系将性能与内存良好控制,让多数用户体验高清稳定的互动,实现 0 故障及秒开,同时星秀猫参与人数再创新高。后续的系列文章将具体阐述淘系互动前端团队是如何做到双11互动又快又好又稳,内容涵盖互动基础、EVA研发体系和全局稳定性方案3个方面。 图:互动效果图 Node FaaS 一体化研发 Serverless云+端研发模式通过打通页面代码和服务代码进行一体研发,使得前端可以从前台页面到后端服务完整支撑,节省中间沟通和联调成本。在天猫榜单以及V榜的落地,使得双11 Node FaaS 相关业务整体研发效率提升38.89%。行业导购双11需求也在云+端的新模式下支撑外包快速入场,使得整体提效约20%。 稳定性保障 稳定性保障贯穿从项目启动到结束的整个双11周期,下面从几个重点方面进行简单的介绍: 变化评估:每年的双11都是站在巨人的肩膀上,都经过了上一次双11的考验。主要的风险就变成新增的部分以及变化的部分,这里的变化既包括技术上的变化也包含人员上的变化。要做到对变化的充分评估,在99大促进行验证,并且保证99大促后不再进行变化,以一个稳定的状态迎接双11。 压测:首先要进行流量评估,借鉴去年数据的同时结合今年的变化,进行相应的机器、带宽等资源准备。完成单线路压测,保证在预估流量模型下,自己的服务和上下游都能够运转正常。进行全链路压测,核心验证在0点高峰时各业务并发的情况的运转情况,尤其是一些底层公共服务,以及优先级的保障情况。 兜底&预案:兜底一般指在大流量或其他不可控因素的情况下,如何将用户体验和业务损失降低到最小。预案需要评估可能遇到的各种情况,以及对应的处理方案。 验收:功能预演,按照用户的所有使用路径进行操作,目前这个工作仍是人工。时间穿越,将页面和系统的状态都调整为活动时间来验证,需要打通上下游的各个系统并形成联动。机型验收,基本分为高端机、中端机、低端机,分别进行验收,很多业务都需要针对低端机做功能降级。稳定性验收,单独页面的性能和稳定性各自保障,但业务叠加后很可能存在问题,尤其像会场、互动、直播、旗舰店等内存消耗大户,互相之间都有引流,切换后很难保证,需要整体全链路验收。 变更&应急:历次的故障数据表明,大部分的问题都是由于变更导致的,如何做好变更管控尤为重要。根据时间分为弱管控、强管控期;根据业务等级分为集团核心应用、BU核心应用、非核心应用等;建立变更的CR和审批的机制。应急主要指在核心活动期间,问题、舆情、故障等流转机制,针对问题发现、定位问题、修复问题时间作出要求,不同等级如何决策作出安排。 监控:淘系前端持续进行监控能力的建设和升级。需要保障大促高峰的可用性以及报警的实时性,覆盖所有的业务场景。针对越来越复杂的场景,需要端到端的监控和数据分析平台。灰度过程缺少度量和定点监控。根据这些问题和需求,jstracker提供了安全生产的整体解决方案,打造端到端的前端监控与数据分析平台,打造实时监控、多端覆盖、数据分析、智能化的数据平台。同时根据页面情况、错误日志、源站数据、FaaS日志等打造了双11的前端数据大盘。 一直以来前端资损防控是平台非常薄弱的一环,前端触发的资损和舆情问题不在少数。之前全靠开发同学的经验和意识来保证,缺少体系化的资损防控能力。去年开始组织了团队层面的集中筛查和人工预演,对人力和时间的消耗非常巨大,并且很难保证质量并进行积累和沉淀。所以为了能有一种成本更低、预防效果更好的方式进行资损防控,2020年 S1 伊始,就重点对资防做相关产品化的设计和实现。同时今年也重点增加了商家、运营中后台侧的资损防控。 我们将资损防控氛围了三个阶段,研发阶段、操作阶段、运行阶段。研发阶段给存在资损风险的仓库打标,将常规的价格、优惠、默认文案等case进行枚举,通过静态扫描、UI测试用例扫描等方式进行防控。操作阶段,主要是指商家、运营进行优惠、权益等设置的阶段,通过表达方式统一(避免5折、0.5折造成理解差异)、二次确认、限定边界值、低价预警等进行防控。运行阶段有快照对比、服务端数据对账等方式,运行阶段的防控相对滞后,发现时很大概率已经造成实际的影响。 然而,目前仍是预防为主,不能百分之百保障没有资损故障发生,接下来我们还在构思链路级别的、生产环境上的防控手段,建设一些告警和自动止血为平台保驾护航。 做好本职的基础上,我们希望给业务带来增量价值。本章从会场性能优化提升转化、基础链路新方案提升转化、唤端技术定制策略提升精准率、智能UI为不同人群提供不通过UI提升点击等4个方面来介绍。 会场是每年双11的主角之一,会场的用户体验自然也是每年最关注的点。在日趋复杂的业务需求下,如何保障我们的用户体验不劣化甚至能更优化是永恒的命题。今年分别使用了预渲染方案和SSR方案进行优化,首先是重新定义了秒开的标准,从原来的前端时间升级到从用户点击经过跳转到页面可视的时间,增加了客户端路由、webview启动等时间,使体验的衡量更贴近用户真实的体感。覆盖了包括主会场、行业会场、外投会场等数十个场景。 预渲染是在今年双11会场中使用的技术方案,用于提升用户打开会场的体验。将原有H5页面渲染流程中的WebView的初始化、页面资源加载、部分JS的执行等耗时的操作,提前执行,在离屏状态下完成页面“渲染”。当用户真正点击进入会场的时候,复用这个提前“渲染”的页面,大大节省打开会场的时间。用户打开会场的整体平均耗时缩短了200ms~700ms左右,秒开率提升10%-14%。优化对中低端机绝对收益更高,已实现在低端机上实现秒开会场。让用户逛会场体验更流畅了,尤其中低端手机效果更加明显。在后续的文章也会讲述包括预渲染、数据快照、并行请求等性能优化方面的实践与思考。 图:中低端机型预渲染效果对比图 今年在不改变现有架构,不改变业务的前提下,在会场上使用了 ServerSideRendering 技术,将秒开率提高到了新的高度(82.6%);在用户体验得到优化的同时,业务指标如点击率等也有明显的增长,带来了不错的业务价值。后续的系列文章汇中会详细介绍前端在解决工程化、业务效果评估上的具体实践与方法论;服务端在解决前端模块代码于服务端执行、隔离和性能优化上的思考和方案。 图:中低端机型 SSR 效果对比图 基础链路是电商核心的链路,包含首页、商品详情、微详情、交易(下单、订单、购物车、支付成功)、信息流、我的淘宝等基础业务。现有的技术方案是手淘内使用Native版本,追求极致的体验和稳定性;站外流量、包括支付宝在内的阿里系App使用H5版本,追求灵活性和可用性。随着支付宝容器化体系的完善,在其他App中的内聚,基础链路新的容器化版本具备了孵化的土壤;同时H5的一些弊端,比如资源都在远端、Native能力使用限制等也可以得到优化。 借助之前的“新奥创”和“DinamicX”方案(主要解决业务定制以及安卓、iOS、H5的三端一致,实现一处开发、三端生效),容器化版本得以快速扩展,实现四端一致。性能数据上,加载时间对比H5版本有2s的提升,基本达成秒开的目标;业务数据上,容器化版本对比H5版本UV转化率提升70+%。 目前已覆盖支付宝、特价版、优酷、高德、淘小铺、一淘等App,以及通过百川SDK集成在众多外部媒体App。业务上也接入了每日必抢、大牌直降、淘宝特价、淘宝直播、百川媒体、优酷、小铺、轻店、花呗等业务。 随着流量见顶、电商大战进一步升级,如何做好用户增长是各大公司必须完成的命题。用户增长涉及的面非常广泛,今年淘系前端聚焦在唤端技术,即外部流量拉起手淘App的技术体系。唤端技术的门槛很低,简单到只需要拼一个类似 URL 的 scheme 就可以触发唤端。唤端技术又很复杂,不同的渠道、不同的OS、不同的 App 都有可能针对唤端协议有限制,并有各种各样的兼容性问题;唤端链路中不同业务可能都有自己的业务定制需求,例如参数的透传;唤端链路的效率更是被关注的核心点,不同场景不同业务在效率上可能都不一样,因此还需要对唤端效果进行监测和对比。为了解决这些复杂的问题,我们在唤端技术上进行了又一次升级,建设了可定制的唤端策略,打造了详细的唤端AB测试链路。从本次双11 的效果看,不同场景下的唤端效率(唤端成功率)相对提升了 25~40%不等。 图:唤端策略图 随着移动互联网和推荐系统的发展,人和商品的精准匹配为业务带来了效率的大幅提升。越来越多的精细化手段逐渐应用于个性化推荐领域,比如场景化推荐、人群定投技术等。同时商品的信息比以往任何时候都要丰富(买家秀,品牌背书,无忧购服务等),不同的用户对于内容的UI表达有着差异化的诉求,因此通过为不同人群找到合适的UI表达一定能带来业务效果的提升。 项目的最早期,我们通过AB实验直接定量测试,明确了相同的UI方案在不同的场景会产生差异,不同的UI方案在相同场景下也会产生差异。也就是说,针对不同场景使用不同方案是有意义的。2020年双11大促我们第一次大规模采用智能UI产品化方案落地了多个前端模块,包括猜你喜欢模块、商品模块、店铺模块等,覆盖了双11的预售和正式开卖阶段,承受了流量洪峰的考验,且带来了稳定的增长。覆盖300多个会场,最高的会场PV点击率相对提升10%+。 伴随业界的技术演进和业务的发展,我们在技术上相比去年也有了新的尝试和迭代升级,其中典型的包括FaaS的深度使用、PHA渐进式的体验增强、边缘节点渲染的应用等。 Serverless,一块深水的坚冰,逐步从深海付出了水面,阿里淘系从去年在大促实践开始,逐渐将 Serverless 应用到前端领域方方面面。今年双11首先是在覆盖场景方面,FaaS从淘宝行业拓展到会场和营销业务,业务的复杂度得到极大的丰富。能力进一步提升,支撑的业务量级也从2k QPS提升到5W QPS,CPU水位从去年的高 QPS 规模时,精力花费降低约50%。在研发体验方面,打造解决方案体系,单元保障、大促管控、专家系统、函数盘点等能力,运维提效约50%。在研发体验方面,打造解决方案体系,降低研发门槛,支持外包快速入场。 PHA 全称 Progressive Hybrid App,是提升 Hybrid 体验的一种应用框架。提升页面加载速度和交互体验的渐进式 Web 应用,使用 PHA 开发的应用本质上没有脱离前端开发和 W3C 标准,但依然拥有原生应用的特性和体验。或许你有想到 PWA,但 PHA 有比 PWA 更强的 UI 能力和更快的加载速度。目前已经在手淘、特价版、Lazada、CBU 等多个客户端落地,支持了618、双11等多个大促。PHA联合客户端、前端团队、数据分析团队,跨栈协同,在性能优化方向上也做了很多优化工作,梳理全链路性能埋点、定义新的性能口径(从用户点击到可视),使用了预加载、预渲染、资源加速下载、离线资源等优化手段。 现在的渲染节点主要是在终端或是服务端,对应CSR(Client Sider Rendering)和SSR(Server Side Rendering),分别有适用的场景以及优势和弊端。现在借助阿里云的能力可将渲染转移到CDN节点,也就是我们要介绍的ESR(Edge Side Rendering),即能为前端提供渲染能力,同时也能将大量CDN机器上的计算资源利用起来。 阿里云推出了CDN轻量编程环境——EdgeRoutine,这为我们提供了一个新的尝试方向。我们可以在CDN节点去做提前渲染的事情。CDN的访问策略是会去寻找离用户最近的节点,就像快递运输的最后一公里一样,总会派送到离客户最近的分拨点。这么看来页面的网络调度时长是非常有优化空间的。并且我们还可以利用CDN节点资源共享的特性,将部分数据缓存到CDN节点上,减少远程的数据请求。 这套方案对于数据刷新率不高、访问量极大的页面,ESR搭配CDN的缓存能力是非常适合用的。以达人页为例,首屏时间约能提升50%左右。现在ER的技术才刚刚起步,应用场景比较局限,能力上还有很多不足,体系也需要不断地建设,但这个新技术为前端提供了更多可能,需要我们不停的去探索和完善。 双 11 PM 初体验 双11作为电商年度最核心的节日,各方面投入的力度和资源都是最大的。作为参加过8次双11的老兵,作为前端PM是第一次,有很多不一样的感受。 复杂:首先是业务上,有双11定制和特有的主会场、主互动、猫晚等,还有淘系内部本身就有导购、行业、营销、直播等数十个业务,同时联动支付宝、优酷、本地生活、阿里妈妈、菜鸟等多个集团BU,与商家、ISV、物流、媒体等的协同和合作。技术上同样复杂,前端的页面从开发、搭建、源站、CDN的全部链路,以及Node FaaS的容器、中间件、容量准备、流量调配、机房部署等。管中窥豹,对于整个体系的认知还需要更进一步的探索。 流程:双11作为电商业务每年的大考,已经摸索出一套成熟的流程机制。包括人员的组成、沟通机制、时间排期、组织保障等各个方面都有很细致的机制进行保障。 协同:双11是非常好的节点,可以让各团队、各岗位、各BU之间形成联动,集中力量将如此庞大的体系进一步完善。很多技术的升级和突破都是在双11落地并进一步推广的。这次预渲染的方案就是客户端和前端紧密协同,在很短的时间内实现并验证的。 多维:看问题的视角可以更多维,不同技术岗位视角,全链路视角,业务的视角。以一次变更的审批为例,之前更多关注变更的代码实现上,对上下游的影响、对稳定性的影响、对业务的影响、是否引入新的风险、影响的范围等等都需要进行综合衡量,做一个判断往往需要从中进行取舍,而不单单是技术上的1和0。 淘系前端由淘宝前端、天猫前端、手淘前端三大前端团队融合而成,在业务上负责淘宝、天猫的所有业务,如:双11&双12大促、聚划算、天猫新品、有好货等营销导购产品、淘宝直播&短视频业务、商业千牛以及开发、用户增长、互动&游戏等等,囊括了新零售域下最复杂、最多形态的业务场景;在技术上在前端工程、多端架构、Node架构、互动架构等基础体系上有着深厚的沉淀,同时在多媒体、前端智能化、云手机等新兴体系上布局&发展,在搭建&投放、小程序开放、工作台等应用体系上直接助力业务。 第十五届 D2 前端技术论坛开放报名,速抢!

免费下载!《玩转ECS从入门到精通》进阶手册一本通

复制该链接到浏览器完成下载或分享:https://developer.aliyun.com/topic/download?id=990《玩转ECS从入门到精通》本书分为入门、进阶两册,本篇内容直达进阶。适合对ECS云服务有一定熟悉认知的开发者。ECS,不只云服务器,进阶篇从入门与选型、自动化运维最佳实践以及架构优化思维三方面来介绍。本书通过多种服务化工具使用助你轻松管理云服务器ECS,手把手教你ECS最佳实践,揭秘你不了解的黑科技。新手入门了解,请戳这里下载(入门篇):https://developer.aliyun.com/topic/download?id=947免费下载《玩转ECS从入门到精通(进阶篇)》目录精彩导读入门与选型如何选择ECS云服务器实例规格本文主要大概分为4个部分,第一部分介绍云服务器ECS的基本概念;第二部分对ECS的实例规格族进行一个详细的解读;第三部分给大家实战讲解如何去做ECS实例的选型;最后一部分简单介绍一下如何去省钱省力的来使用ECS。>>点击查看详情自动化运维服务器自动化迁移中心 SMC 最佳实践及新特性介绍 本次分享由阿里云技术专家白辉万(百宝)为大家介绍免费的服务器迁移上云最佳实践方案和新功能特性,包括一键迁云、自动定期同步、一键验证。>>点击查看详情云上自动化部署和运维的正确姿势本次分享由阿里云资深技术专家吴君印为大家介绍介绍上云最正确的部署和运维方式,结合阿里的最佳实践,打造快速、安全、可复制、标准化的DevOps体验。>>点击查看详情ECS云助手,实现云上运维自动化本次内容由阿里云技术专家朱士松 (锐奇)为大家介绍使用 ECS 云助手,不但免除公网环境的限制需求,而且能通过阿里云 OpenAPI 完全自动化地实现文件发送与执行命令,适用于在 ECS 实例内部署与更新应用、监控系统或应用的运行状态、以及批量操作多个实例内部系统的这些场景。本篇内容适合于 ECS 系统运维人员。>>点击查看详情ECS自助服务之智能诊断和自动化修复本次分享由阿里云高级技术专家滕圣波(云普)为大家介绍ECS自助服务之智能诊断与智能修复,解密背后的AI与实现细节,剧透ECS自助服务的未来。>>点击查看详情ECS数据保护-数据备份新特性与最佳实践阿里云智能弹性计算专家余初武(悟元)将结合阿里云近期推出的数据备份新特性(快照极速备份、一致性快照组)来介绍云上环境如何做数据备份的最佳实践;适合需要构建云上架构的工程师,架构师和云上实施从业人员收看。>>点击查看详情架构优化云上高弹性、低成本解决方案 本次内容由阿里云智能高级技术专家贾少天为大家介绍弹性伸缩和弹性供应的产品力和功能概要,帮助您快速了解弹性的能力和应用方式,方便快速在业务场景中使用弹性来解决日常业务变化对于资源的弹性需求。>>点击查看详情基于弹性计算网络能力提升容器密度最佳实践本次分享由阿里云高级技术专家姜文锋(令吾)为大家介绍三种基于阿里云弹性计算网络能力提升容器密度的主要方法和最佳实践。>>点击查看详情ECS安全组最佳实践及新特性介绍本次内容由阿里云智能技术专家王帝(丞浩)为大家介绍如何正确使用安全组、最佳实践以及新特性;详细了解安全组为何是云端的虚拟防火墙,以及为何是重要的网络隔离手段。>>点击查看详情Region化部署和跨可用区容灾介绍本次分享由阿里云弹性计算架构负责人李钟(谢顿)为大家介绍阿里云region化部署和跨可用区容灾的实践经验,说明多Region部署场景中使用阿里云弹性计算的最佳实践,并结合弹性计算的实践经验探讨如何基于阿里云多可用区实现跨地域容灾。>>点击查看详情藏经阁系列电子书阿里云开发者社区——藏经阁系列电子书,汇聚了一线大厂的技术沉淀精华,爆款不断。点击链接获取海量免费电子书:https://developer.aliyun.com/ebook

免费下载!玩转ECS从入门到精通(入门篇)

复制该链接到浏览器完成下载或分享:https://developer.aliyun.com/topic/download?id=947《玩转ECS从入门到精通》本书分为入门、进阶两册,本篇先来了解入门篇。阿里云的1024种玩法之ECS云服务器,从基本组件概念、实例规格选型到资源计费介绍,本书精简了阿里云云服务器ECS的入门知识,以图文形式带您快速了解ECS, 上手阿里云服务。附《玩转ECS从入门到精通》(进阶篇)下载:https://developer.aliyun.com/topic/download?id=990>>点击免费下载《玩转ECS从入门到精通(入门篇)》目录精彩抢鲜看什么是ECS云服务器ECS(Elastic Compute Service)是阿里云提供的性能卓越、稳定可靠、弹性 扩展的IaaS(Infrastructure as a Service)级别云计算服务。云服务器ECS免去了您 采购IT硬件的前期准备,让您像使用水、电、天然气等公共资源一样便捷、高效地使用 服务器,实现计算资源的即开即用和弹性伸缩。简而言之,云服务器就是把固定配置的 服务器升级为随时可以调整配置的云端服务器。为什么选择云服务器ECS选择云服务器ECS,您可以轻松构建具有以下优势的计算资源:无需自建机房,无需采购以及配置硬件设施。分钟级交付,快速部署,缩短应用上线周期。快速接入部署在全球范围内的数据中心和BGP(Border Gateway Protocol,边界网关协议)机房。成本透明,按需使用,支持根据业务波动随时扩展和释放资源。提供GPU和FPGA等异构计算服务器、弹性裸金属服务器以及通用的x86架构服务器。支持通过内网访问其他阿里云服务,形成丰富的行业解决方案,降低公网流量成本。提供虚拟防火墙、角色权限控制、内网隔离、防病毒攻击及流量监控等多重安全方案。提供性能监控框架和主动运维体系。提供行业通用标准API,提高易用性和适用性。常见应用场景Web开发与测试数据库与分布式缓存大数据集群AI机器学习超算更多详情下载电子书:https://developer.aliyun.com/topic/download?id=947藏经阁系列电子书阿里云开发者社区——藏经阁系列电子书,汇聚了一线大厂的技术沉淀精华,爆款不断。点击链接获取海量免费电子书:https://developer.aliyun.com/ebook

阿大:“我们将在 D2 首次对外披露阿里前端在安全生产建设上的思考和成果”

作者 | 阿大关于阿大09年加入淘宝网,花名:阿大。刚入职时负责淘宝机票和彩票业务,两个业务后来均交接到了北京团队,期间还参与过淘宝交易、搜索、二手(闲鱼)等业务。12年随团队调整到一淘,开始关注前端工程化领域,并在一淘做了小范围尝试。13年回到淘宝前端团队,开始深耕前端工程化领域,推动了前端 Git 化并孵化了淘宝前端工程平台:DEF,涵盖研发工具、流程管控和静态源站等全链路前端研发能力。后经过两年时间升级为阿里集团前端工程中台,服务集团几千前端工程师的日常业务研发,平台日活跃内部开发者达 2500+。19年在阿里集团前端技术委员会提出 IDE 战略,组队自研了阿里内部的 IDE Framework:KAITIAN(开天),先后在集团内部众多 IDE 业务场景落地,奠定了一站式前端研发平台的技术基础。连续多年参与阿里集团前端技术委员会的横向建设,是委员会核心委员。目前负责委员会前端工程方向,今年的主要精力是在工程的角度横向推进集团前端的安全生产建设。阿大介绍D2安全生产专场随着前端领域边界的不断拓展,前端工程师的日常工作内容已经与几年前有着巨大的不同。Serverless、微前端、智能化等新兴技术使得前端的技术闭环越来越完整而又错综复杂,前端交付的也早已不再只是简单的 HTML 页面,前端已经参与到业务的核心逻辑和关键链路。如何提升团队安全意识和保证交付代码质量?如何做到秒级线上监控和故障快速响应?这对前端而言是一个熟悉而又陌生的挑战。安全生产本身也是一个工程问题,所以今年 D2 的前端工程专场将聚焦安全生产,我们将首次对外披露阿里经济体在前端安全生产上的建设成果,相信大家能在这个专场收获不一样的惊喜。快问快答D2小编收集了同学们比较疑惑的、和一些犀利的问题,邀请阿大回答一下。点击查看视频D2 小编:今年在D2上首次看到了前端安全生产这个专场,为什么会有这样一个专场出现?阿里经济体技术线今年有四大战役,两个是业务方向的战役,一个云原生战役,还有一个战役就是安全生产。如果我们把业务比做水的话,云原生就是装水的水桶的材质,升级成果更好材质的桶了。那安全生产是什么呢?是那个桶底!以前我们常说补短板,但往往忽略了这个桶底,底漏了桶再好也没用。第二点我想大家最近几年一定有感受,就是现在外部环境越来越复杂,各种不确定性和黑天鹅频发。在技术上也同样,前端是最近接用户的,是保证体验和可用性的最后一道关卡,没有其它技术可以为前端技术兜底。所以前端的稳和可用性对产品至关重要,当突发情况出现时前端是否有快速的应急响应能力和完备的预案,这是对前端工程师们全新的考验。D2 小编:前端安全生产和普意的安全有什么区别?怎么定义前端安全生产的范畴?安全的范畴太广了,比如你不能把你的登录密码告诉别人,这就不属于安全生产范畴。在阿里内部安全和安全生产是两个独立的团队,当然两个团队是有非常紧密的协同的,安全生产算是安全的一个子领域吧。安全生产核心在“生产”,是面向生产这个过程的,这个过程就是研发过程。所以前端安全生产建设跟前端工程紧密相关,绝大部分都是都需要借助工程落地。前端安全生产覆盖前端研发的全生命周期,包括且不限于:规范意识,编码质量、流程保障、监控报警、应急响应等。D2 小编:下一个问题有点尖锐【笑】。安全生产一般会带了很多额外的工作量,特别是流程和审批等方面,导致了工作量的增加,有没有很好的后续优化策略?首先还要明确一下安全生产的目的是为了保护开发者,保证业务稳定,而不是为了给大家添堵。但是不可否认,在特殊时间阶段,安全生成附带的规范、流程等确实会有一定的成本增加,这个需要辩证的看。我举个例子:一开始的时候路上没有车人也少,人们可以径直地从路的东边走到路的西边。后来人多了,还出现了摩托车、汽车等,在路上随便走变得很不安全。这个时候人行道和红绿灯就出现了,行人只允许在人行道上行走,红灯的时候你得等。这是非常有必要的是不是,不然就不安全嘛。不过红绿灯有也不完善的地方,比如有些红灯时间很短,有些又很长都是有问题的,需要按照现实情况优化。安全生产也一样,它的必要性毋庸置疑,但是在执行落地的时候要根据实际情况做好调整,另外就是意识问题了,当大家能清晰地认知到一件事情的利弊,对抗就会变成理解。针对审批这个场景,在阿里内部目前形式上确实有点重的,这也是特殊时期取舍的结果。审批背后的逻辑就是需要人工介入,说明安全能力的平台化做的不够完善,是一种早期防控的有效手段,我相信随着时间推移这种手段一定是会越来越弱化的。D2 小编:安全生产对于业内都比较重视的资损防控是怎么做的?有什么比较好的实践?资损防控是安全生产建设中很重要的一环,资损的危害非常直接,就是经济损失。在阿里这样以交易为核心的业务场景中时时刻刻都存在着资损的风险。诚然大部分的资损问题是不在前端领域的,但不是说前端就没有资损的问题。近几年阿里由于前端问题导致的资损故障不在少数,前端主要从三方面做资损防控建设:首先我们对历史前端资损故障和所有可能出现资损的线上场景进行了梳理,盘点分析前端资损问题特点,并制定相关的规范、红线等,通过考试提升前端资损防控意识。然后我们在研发链路通过静态扫描能力对所有上线的源代码进行检查,识别可能的危险操作,比如对获奖结果的判断,金额计算等逻辑,都是不允许的。最后还会通过机器学习的能力对页面 UI 进行扫描,通过 UI 测试用例快照对比防控资损风险。D2 小编:在阿里像618、双11这样的大促,才会严抓安全生产。如何让安全生产的意识,融入到平时的开发中?恰恰相反,历史经验告诉我们,越是严重的问题往往越是出现在容易疏忽的时候,双十一这样的大促时间,大家都紧绷着那根神经,各方面的要求都比平时要高,反而出问题的概率很低,不过大促等重点时间段肯定有特殊的保障手段。提升意识的前提一定是记忆深刻的,比如让你出一个线上故障,你的安全生产意识一定立马提到最高警戒线了,但这肯定不现实。另外一种记忆深刻的方式就是不停重复,所以我们会定期给全集团前端发送前端安全生产月报,线上问题复盘等邮件,另外还会不定期的进行内部技术分享、直播和技术社区文章等。另外阿里前端在工程化建设上是比较完善的,我们就把前端安全生产融入到日常的研发流程中,比如你的代码开发完后一定会需要 Code Review,Code Review 不认真我们还会攻防你。代码发布上线之前必须经过各种源码扫描、性能评估等。正式上线时还要提交变更申请单及灰度放量验证。上线后一小时内还要求大家关注监控数据情况,并且可能会有变更监控的攻防,所有的攻防没有有效防守都会记录分数。D2 小编:安全生产目前的产品化到什么程度?人肉成本有多高?针对目前人肉化的,是否还有进一步的优化空间?阿里经济体前端委员会下属的前端安全生产小组是今年 6 月份正式组建的,经过差不多半年的时间完成了基础能力平台的建设,推进建设了统一的前端监控平台、前端攻防平台和前端安全环境。这些平台能力未来都会高度集成到日常研发链路,大部分的使用能做到非常低成本的接近无感。包括我们研发链路中的灰度放量发布、线上数据监控和回滚应急预案等都已经比较完备。要说还需要优化的我想应该就是对数据价值的挖掘了,我们在研发过程积累了大量的数据,包括一些线上服务的日志数据,这些数据中是可以挖掘出非常多有用的东西的。举个例子:我们经常遇到一个线上 URL 有问题后问了一圈没人知道这个 URL 是谁负责的,对应的源码仓库是哪个,什么时候发布过,是在哪个平台发布的等。但其实这些关系数据我们都有,只是可能分散在不同的地方而已。所以今年我们的前端安全生产小组还在推进经济体前端研发元数据平台,目的就是要拉通经济体所有变更平台的数据,通过数据标准对齐和数据统一开放,解决前端提到的问题。D2 小编:最后一个就是大家最关心的问题了。本次 D2 的安全生产专场话题,会倾向于哪些重点方向,会邀请哪些专业讲师来分享呢?大家听完会有什么收获呢?阿里集团是 18 年 9 月份正式在技术线成立安全生产小组的,同时安全生产又是今年阿里经济体技术线四大战役之一,可见安全生产的重要性和持续性。今年 D2 设置了《前端安全生产》专题,我们将首次对外披露阿里前端在安全生产建设上的思考和成果,具体内容大家到现场就知道了,我这里就不先透露了。另外我们还会邀请一线互联网公司的前端同仁到 D2 上来讲讲不同商业场景下的安全生产建设思路。如果你的前端团队已经具备一定规模,并且正在高质量研发和高效业务迭代之间矛盾苦恼,那么我相信在这个专题一定能有所收获。D2 小编:感谢阿大的有问必答,大家快来 D2 一起学习吧!🥳👇👇🔥第十五届 D2 前端技术论坛开放报名,速抢!关注「Alibaba F2E」把握阿里巴巴前端新动向

如何在 Node.js 中 ”相对可靠” 的高效执行可信三方的代码

作者 | 淘系-霸剑在开始正文之前,解释下标题,以免给读者们带来误解。可靠:一方面是单次执行维度的安全可信,另一方面是多次执行可能带来的内存泄漏等问题。可信三方:公司内部的其他团队、经过审核的外包开发代码和久经考验的开源社区库(锁定版本)。相对可靠:具备持续稳定运行的能力,特别注意这里不包括安全相关的考虑。在本文的最后也会扩展介绍一些与安全相关的东西。什么样的场景有这样的需求?常见的有:SSR(组件的代码需要在服务端执行)分布式定时任务系统(内部用户提交的轻量级代码)规则引擎(匹配条件等的代码)等等。在可信三方的条件下使用容器隔离等技术会带来较大的 overhead,影响性能。要解决哪些问题?典型问题:内存泄露(变量隔离)CPU 时间限制(死循环、长时间运行的代码)外部资源控制Node.js 的代码执行环境模型我们都知道 Node.js 是单进程且默认情况下是只有一个 V8 执行线程的,但是这是由什么决定的呢?从上图中可以看到几个概念,这里先解释一下:isolate :顾名思义就是一个独立的世界。一个 isolate 就是一个独立的 V8 实例,其中包括了内存管理、GC 收集器等等。isolate 和实际的一个 OS Thread 成绑定关系。context:一个 isolate 并不足以执行你的代码,我们可以看到在 Node.js 中有 global,在浏览器中有 window,context 可以指代它们。实际上 context 就是在一个 isolate 的堆上定义的一个全局对象,并且在一个 isolate 中可以存在很多个 context,它们互相之间可以安全的访问。具体的方案从上一节中我们可以根据不同的隔离级别找到不同的方案。new Functionconst func = new Function(`console.log('hello')`).bind({});这种方式在前端动态加载代码的时候比较常用,优势是速度较快,函数中所操作的局部变量会局限在 func 的作用域中。缺陷比较明显,如果加载的代码中使用const global = Function('return this')();就可以很方便的逃逸出去了> new Function('const global = Function("return this")(); return {global, a: this};').bind({})() global: Object <a href="https://nodejs.org/api/vm.html">global] { global: [Circular], clearInterval: [Function: clearInterval], clearTimeout: [Function: clearTimeout], setInterval: [Function: setInterval], setTimeout: [Function: setTimeout] { [Symbol(util.promisify.custom)]: [Function] queueMicrotask: [Function: queueMicrotask], clearImmediate: [Function: clearImmediate], setImmediate: [Function: setImmediate] { [Symbol(util.promisify.custom)]: [Function] a: {} }这种方案的问题在于寄希望于通过函数的 scope 来做到变量的隔离。Node.js VMAPI 文档VM 是一个在 Node.js 0.3.0 出现的模块,相对于new Function 能做到更好的变量(内存)隔离。const vm = require('vm'); const script = new vm.Script('globalVar = "set"'); const contexts = <a href="https://nodejs.org/api/worker_threads.html">{}, {}, {}]; contexts.forEach((context) => { script.runInNewContext(context); console.log(contexts); // Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]从 API 命名中就可以看到,VM 模块可以创建 context ,让代码在非 Node.js Main Context 中执行,避免了类似new Function 的变量逃逸。缺点在于 context 的创建是一个相对慢的过程,对于需要频繁执行的代码,每次创建 context 对性能的影响比较大。const vm = require('vm'); const suite = new (require('benchmark').Suite); const code = 'var square = n * n;' const fn = new Function('n', code); const script = vm.createScript(code); const n = 5; const contextObj = { n }; const context = vm.createContext(contextObj); console.log(process.version); suite.add('vm.runInNewContext', function() { vm.runInNewContext(code, { n }); .add('script.runInNewContext', function() { script.runInNewContext({ n }); .add('script.runInContext', function() { script.runInContext(context); .add('new Function', function() { fn(n); .on('cycle', function(event) { console.log(String(event.target)); .on('complete', function() { console.log('Fastest is ' + this.filter('fastest').map('name')); .run({ 'async': true }); v14.13.0 vm.runInNewContext x 2,332 ops/sec ±2.85% (77 runs sampled) script.runInNewContext x 2,609 ops/sec ±2.84% (86 runs sampled) script.runInContext x 571,992 ops/sec ±0.93% (89 runs sampled) new Function x 826,079,093 ops/sec ±1.61% (81 runs sampled) Fastest is new Function **/VM 模块在基本的 context 之外还提供了更多的功能,比如timeout 和microtaskMode 的设置。但是这里的控制在最坏的情况下会把 Nodejs MainContext 卡住timeout 时长的时间,导致应用执行出现卡死,依然不是好的方案。Node.js Worker ThreadsWorkerThread 是在 Node.js 10.x 出现的模块,它通过创建多个 isolate 做到了多线程执行代码,我们也可以使用它结合 Node.js VM 来做到在 Node.js 进程内最完整的隔离与控制。缺点在于 Worker Threads 的创建是非常慢的,实际使用时需要常驻,并且主线程与 Worker Threads 之间只能通过 IPC 传递满足 HTML structured clone algorithm 的数据结构。总结方案变量隔离内存限制isolated 隔离执行时间限制异步操作限制new Function部分隔离❌❌❌❌vm✅❌❌✅✅workerthreads✅✅✅✅✅社区中基于 isolate 隔离的实现还有 isolated-vm 等,可以进一步参考。读者如果有更好的思路可以跟笔者探讨交流,非常感谢。扩展:安全上述的方案均不能实现面向恶意代码的安全,针对安全方面的要求笔者倾向的是两个级别的方案:可信容器以及 WebAssembly 容器。可信容器一类是基于在已有的成熟 VMM,进行裁剪,通过虚拟化技术解决安全隔离性问题,比如 AWS 的 Firecracker。而另一类则完全不使用虚拟机,以 Google 的 gVisor 以及一些 Unikernel 技术为代表。将虚拟化的边界移到了系统调用层面。基于容器方案的对性能都或多或少有一定影响,且业务应用开发使用的门槛较高,如果不从 Infra 级别上就支持很难以应用到业务应用开发中。WebAssembly 容器这是笔者比较看好的方向,通过将代码编译到 WebAssembly 的方式,WebAssembly 容器既可以限制指令执行速度也可以限制内存、通过 WASI 限制访问外部资源等。缺点是目前没有成熟的方案,V8 对 WebAssembly 的支持主要聚焦在了执行性能上,对管控等还没有更好的支持。🔥第十五届 D2 前端技术论坛开放报名,速抢!关注「Alibaba F2E」把握阿里巴巴前端新动向

Web Vitals :Google 如何定义性能指标及帮助开发者调优前端性能 ?

优化用户体验质量是所有网站取得长期成功的关键。通过与数百万网络开发者和网站所有者的持续交流和协作,我们在 Google 开发了许多实用指标和工具,以帮助企业所有者、市场营销人员和开发者发掘改善用户体验的机会。然而,丰富多样的指标和工具也给许多人带来了各种优先级、明晰度和一致性方面的挑战。今天,我们为各位介绍一项名为 Web Vitals 的新计划,此计划的发起方为 Google,旨在提供各种质量信号的统一指南,我们相信这些质量信号对提供出色的网络用户体验至关重要。Core Web Vitals 评估用户体验质量涉及多个指标,尽管部分用户体验是跟网站和内容相关,但还是有些共通信号,所以 Core Web Vitals 体现了最关键的几项指标。此类核心用户体验需求包括页面内容的加载体验、交互性和视觉稳定性,这些方面共同组成 2020 Core Web Vitals 的基础。最大内容绘制评估页面主要内容可能已完成加载时的感知加载速度,并在页面加载时间轴上标记时间点。首次输入延迟评估用户首次尝试与网页交互时的网页响应速度,并量化用户感知体验。累积布局偏移评估可见页面内容的视觉稳定性,并量化内容的意外布局偏移量。所有上述指标均捕获以用户为中心的重要体验结果,可现场测量,并具有支持性实验室诊断等效指标和工具。例如,虽然「最大内容绘制」是最重要的负载指标,但其也高度依赖于首次内容绘制 (FCP) 和首字节响应时间 (TTFB),这些指标对监控和优化均具有非常重要的意义。评估 Core Web Vitals我们的目标是创建简单且易于访问和评估的 Core Web Vitals,让所有网站所有者和开发者在 Google 界面及其自己的仪表板和工具中都能轻松使用。Chrome UX Report 让网站所有者能够快速评估其网站的各项 Web Vital 性能,获取实际 Chrome 用户的真实体验数据。BigQuery 数据集已经能够展示所有 Core Web Vitals 可公开访问的数据,同时我们正在开发全新的 REST API,以实现对 URL 和原始级别数据的轻松访问,敬请期待。我们强烈建议所有网站所有者针对每项 Core Web Vital 收集自己的真实用户评估分析结果。为此,包括 Google Chrome 在内的多个浏览器已实施并提供对所有当前 Core Web Vitals 规范草案的支持:最大内容绘制、布局不稳定性和事件时间。此外,今天我们还将推出一个 web-vitals 开源 JavaScript 库,该库提供可立即投入生产的小型包装器,可与支持自定义指标的任何分析提供程序搭配使用,也可用作准确捕获网站用户各项 Core Web Vitals 的参考。// 使用 web-vitals 评估和报告 CLS、FID 及 LCP 的示例。 import { getCLS, getFID, getLCP } from 'web-vitals'; function reportToAnalytics(data) { const body = JSON.stringify(data); (navigator.sendBeacon && navigator.sendBeacon('/analytics', body)) || fetch('/analytics', {body, method: 'POST', keepalive: true}); getCLS((metric) => reportToAnalytics({ cls: metric.value })); getFID((metric) => reportToAnalytics({ fid: metric.value })); getLCP((metric) => reportToAnalytics({ lcp: metric.value }));我们在测试和开发过程中发现,在开发环境和生产环境轻松访问每项 Core Web Vital 的功能非常有用。为帮助当下的开发者发掘优化机会,今天我们还要推出全新 Core Web Vitals 扩展程序的开发者预览版。在浏览网页的过程中,此扩展程序会在 Chrome 浏览器中显示有关每项 Vital 的视觉标识,将来还可以通过此程序来查看汇总的真实用户数据分析(由 Chrome UX Report 提供),以了解当前网址(URL)和来源(origin)的每项 Core Vital 状态。最后,在接下来的几个月里,我们将更新 Lighthouse、Chrome DevTools、PageSpeed Insights、Search Console 的速度报告和其他主流工具,以重点强调并提供统一的可执行指导,进而改进 Core Web Vitals。不断发展 Core Web Vitals2020 Core Web Vitals 着重于三个主要衡量指标,暂未捕获完整的Web用户体验。我们预计每年对 Core Web Vitals 进行一次更新,并定期更新未来候选指标、动机和实施状态。展望 2021 年,我们将投资构建针对页面速度及其他关键用户体验特征的指标,以增强理解和评估能力。例如,扩展对所有交互中 (而不仅仅是第一次交互) 输入延迟的评估功能;构建用于评估和量化平滑度的新指标、可实现即时且保护隐私的网络体验的原语和支持指标等等。第十五届 D2 前端技术论坛,来自 Google 的 Palances Liao 将带来 《以全球 Web 角度谈前端性能的更新与趋势》主题演讲,与大家分享关于 Core Web Vitals 的最新指标及每个指标的更新。相关链接Web Vitals:https://web.dev/vitals/核心用户体验需求:https://web.dev/user-centric-performance-metrics/#defining-metrics最大内容绘制:https://web.dev/lcp/首次输入延迟:https://web.dev/fid/累积布局偏移:https://web.dev/cls/首字节响应时间:https://web.dev/time-to-first-byte/真实用户评估分析结果:https://web.dev/user-centric-performance-metrics/#in-the-field布局不稳定性:https://wicg.github.io/layout-instability/事件时间:https://wicg.github.io/event-timing/Core Web Vitals 扩展程序:https://github.com/GoogleChrome/web-vitals-extension/关注「Alibaba F2E」把握阿里巴巴前端新动向

全面拥抱 Reactivity: RxJS, RSocket & Svelte

在 Reactive 方面,有两个非常知名的工程师,他们是来自 Netfix 的 RxJava 作者Ben Christensen 和 RxJS 作者 Ben Lesh,两人在 Reactive 方面都做出了非常多的贡献。在 2019 年初 Reactive 社区有两个非常令人振奋的消息,RSocket 步入了大众视野,RSocket 是二进制异步化通讯协议,完全兼容 Reactive 语义,提供了多种通讯模型,而且是对等通讯;此外就是 Svelte 3.0 发布,Svelte 作者 Rich Harris 做了知名的 “Rethinking Reactivity” 的演讲。Svelte 通过编译器的方式让Reactive 使用更简单,没有 Virtual DOM 等性能损失,代码更小性能更高。当然在 Reactive 社区,RxJS 还是最核心的底层框架,始终发挥着重大作用。这篇文章,我们就讨论一下如何基于 RxJS 衔接 RSocket 和 Svelte, 在前端开发中全面拥抱 Reactivity,那么就从 Svelte 开始吧。SvelteSvelte 框架的核心理念是 Reactive,但是和其他前端框架不太一样的是,Svelte 是通过静态编译实现 Reactive,同时并减少框架运行时的代码量,这点你可以在 Svelte 作者 Rich Harris 的 《Svelte 3: Rethinking reactivity》 文章和演讲中了解到。Svelte 语法简洁,帮助您编写更少的样板代码。虽然同样是实现 Reactivity,对比RxJS,Svelte 的入门门槛非常低,你几乎不需要理解和 Reactive 相关的知识,就可以编写全响应式的 UI 应用。Svelte 包含对 RxJS 的支持,如 RxJS 的 Observable 变量,另外体现在自定义Store 上,如和 RxJS 的 BehaviorSubject 的整合。Svelte 主要是关注在 UI 层面的 Reactivity,如 state 管理,事件处理等,但是涉及到逻辑处理,如后台交互的 fetch,WebSocket,流式数据等,可能 RxJS 会更方便,这方面也是 RxJS 非常擅长的。让我们看一下典型的几个例子:RxJS 的 interval 应用你可以通过 RxJS 的 interval 进行定时状态更新,同时可以实现非常复杂的逻辑:<script> import { interval } from "rxjs"; import { map, take,startWith} from "rxjs/operators"; const counter = interval(1000).pipe( map(i => i + 1), startWith(0), take(10) </script> <h2>Count to 10</h2> {$counter}RxJS BehaviorSubject对象RxJS 的 BehaviorSubject 可以在 Svelte 中直接使用,和 Svelte 的状态管理发挥着同样的作用。<script> const store1 = new BehaviorSubject(0); store1.set = store1.next; </script> <button on:click={()=>{store1.next(1)}}>increment 1</button> <button on:click={()=>{$store1 = 2}}>increment 2</button> {$store1}RxJS的fromFetch结合 RxJS 的 fromFetch ,可以非常容易地和后端进行交互,完全是响应式的。<script> const data = fromFetch('https://httpbin.org/ip', { selector: response => response.json() </script> <h2>Your IP: </h2> {$data.origin}当然你可以可以结合 RxJS 的 WebSocket 特性完成和 WebSocket 的交互。详细细节可以参考 https://rxjs-dev.firebaseapp.com/api/webSocket/webSocket。RSocketSvelte 和 RxJS 交互解决 UI 和基本的后端通讯是没有问题的,如 HTTP REST API 和 WebSocket 等,那么为何还需要 RSocket?让我们先看一下 RSocket 的通讯模型:request/response: 这也是典型的 HTTP 请求模型,也适用于 RPC 场景,当然这个通讯是异步化的,也适用 Promise 模型。request/stream: 流式数据请求,如 Pub/Sub 模型,可以非常方便地后端的数据流,如来自 Kafka 消息等。fireAndForget: 不需要返回确认的场景,如数据采集后提交后端的场景,这样速度更快。Channel:双向通讯,如 IM 聊天场景,可以同时实现消息的发送和接收。标准的请求响应,如 HTTP REST API,可以使用 request/response;数据采集,我们可以使用 fireAndForget 做到性能极致;如果是消息订阅或者流式数据处理,你可以使用 request/stream;如果你要在 web 页面中添加即时消息(IM)聊天场景,使用 Channel 即可。一句话,借助于 RSocket 这一协议,可以让你实现各种通讯场景的需求。RSocket 完全是基于 Reactive 语义的,这样和 RxJS 和 Svelte 可以无缝衔接,不需要额外的转换操作。此外 RSocket 还支持对等通讯,也就是通讯的双方或者多方,同时可以为 client 或者 server。我们都知道 Svelte Store 都是针对组件通讯的,如果 Svelte Store 和RSocket 整合,则可以实现不同页面之间的通讯,页面之间的协作场景就可以非常容易完成。目前 RSocket 对 JavaScript 支持主要包括三个方面:RSocket Browser,在浏览器中连接后端 RSocket 服务;RSocket Node.js 可以快速创建后端 RSocket 服务;RSocket Deno 可以创建基于 Deno 的后端 RSocket 服务。关于 Svelte 和 RSocket 通讯,可以参考 https://github.com/linux-china/svelte-rsocket-demo,详细的结构图如下:RxJS 7RxJS 起着衔接 Svelte 和 RSocket 的功能,主要是 RxJS 本身的强大功能。所以接下来我们介绍一下即将发布的 RxJS 7.0 的新特性和功能。RxJS 7.0 采用最新的 TS 版本(当前为 4.0.x),这样可以使用 TypeScript 最新的特性,这样代码就整洁很多,当然可靠性和稳定性也提高很多。RxJS toPromise 的调整RxJS 的 Observable 是可以转换为 Promise 对象的,但是 API 让一些人有些模糊,主要的原因是 Observable 是流式的数据,所以在 RxJS 7.0 中使用 firstValueFrom, lastValueFrom 来替换 toPromise 函数,代码如下:import {firstValueFrom, lastValueFrom} from "rxjs"; let result = await firstValueFrom(observable);基于 AsyncIterable 构建 ObservableAsyncIterable 在异步化越来越重要, 如熟知的 for await...of 语句,就是在异步可迭代对象上创建一个迭代循环。在 RxJS 7.0中,我们可以基于 AsyncIterable 创建 Observable 对象,然后就可以利用 Observable 强大的功能来处理异步可以迭代对象列表。from(iterable).subscribe(x => console.log(x))当然如果你想将Observable转换为AsyncIterables,可以参考Ben Lesh的 https://github.com/benlesh/rxjs-for-await 项目。fromFetch 函数提示fromFetch 做了提升,添加了一个 selector 函数,这样可以支持直接从 response 提取对应的信息,如转换为文本或者 json 对象等,之前需要进行 map 转换的,现在方便非常多。fromFetch("http://httpbin.org/ip", {selector: response => response.json()});RxJS 和 DenoDeno 作为一个新的 JS 运行引擎,因其的安全性、内置 TypeScript 支持和分布式的 module 加载机制,越来越受到 JavaScript 开发者的关注。RxJS 是基于 TypeScript 编写的,所以 Deno 的原生 TypeScript 支持没有问题。此外 Deno 的 API 设计遵循 Web APIs 规范,如 fetch 函数、WebSocket 类,这就让 RxJS 的 fromFetch 和 WebSocket 可以在 Deno 使用,可以直接在 Deno 中使用 RxJS 网络通讯相关的功能,此外 RSocket 也包括对 Deno 的支持,也可以使用 RSocket 进行网络通讯。在 Deno 中使用 RxJS fromFetch 样例如下:import {firstValueFrom} from "https://esm.sh/rxjs@7.0.0-beta.8?no-check"; import {fromFetch} from "https://esm.sh/rxjs@7.0.0-beta.8/fetch?no-check"; const ip = await firstValueFrom(fromFetch("http://httpbin.org/ip", {selector: response => response.json()})); console.log(ip.origin);RxJS 7.0 其他如内存优化,使用内存更小,添加更多 operator 方法。当然大家也不用太担心兼容性的问题,目前 RxJS 7.0 只是增加一些 API,只会将一些 API 调整为废弃 (Deprecated) 状态,还不会删除掉,可能在 RxJS 8 中会进行删除,所以 RxJS 7.0 的兼容性不用太担心。当然 RxJS 7.0 还有更多更新,详细信息请参考:https://github.com/ReactiveX/rxjs/blob/master/CHANGELOG.md总结对比语法层级的 Promise(async/await),Reactive 确实复杂不少,可能需要花费你不少时间去掌握。但是也不是完全无法掌握的,Svelte 让 Reactive UI 变得非常简单,你几乎不需要了解什么是 Reactive;RSocket 基于 Reactive语义对通讯模型进行抽象化,通讯模型简单很多且能覆盖多种业务场景;而 RxJS 强大的功能,可以很好地粘合多项技术,如 Svelte 和 RSocket,拥抱 Reatctivity 毫无压力。第十五届 D2 前端技术论坛,将会邀请 RxJS 作者 Ben Lesh 进行《重构 RxJS 架构:我们如何让其更小、更快》的主题演讲,Ben 会就其 RxJS 的开发经验和大家分享一下他的经验,相信大家一定会有新的收获。关注「Alibaba F2E」把握阿里巴巴前端新动向

潮流最前端 第 6 期:Technical debt as a lack of understanding

“潮流最前端,每周一新鲜而至”  Technical debt as a lack of understanding、🧐一周精读🧐《设计模式 - Adapter 适配器模式》、企业级数据可视化应用有哪些机遇与挑战?Revolution incoming: CSS Houdini and the future of frontend development、电影院能挺过疫情吗?本周最新前端资讯请查收。本周热点栏目主编:平侠Technical debt as a lack of understandinghttps://daverupert.com/2020/11/technical-debt-as-a-lack-of-understanding/If you develop a program for a long period of time by only adding features but never reorganizing it to reflect your understanding of those features, then eventually that program simply does not contain any understanding and all efforts to work on it take longer and longer.7GUIs: A GUI Programming Benchmarkhttps://eugenkiss.github.io/7guis/There are countless GUI toolkits in different languages and with diverse approaches to GUI development. Yet, diligent comparisons between them are rare. Whereas in a traditional benchmark competing implementations are compared in terms of their resource consumption, here implementations are compared in terms of their notation. To that end, 7GUIs defines seven tasks that represent typical challenges in GUI programming. In addition, 7GUIs provides a recommended set of evaluation dimensions.What's the deal with SvelteKit?https://svelte.dev/blog/whats-the-deal-with-sveltekitWe're rethinking how to build Svelte apps. Here's what you need to know. Releated: The Next Svelte May Be Serverless-First -- Rich Harris at Svelte Summit.Why not use GraphQL?https://wundergraph.com/blog/why_not_use_graphqlHypermedia APIs played and still play a big role for server rendered web applications. However, the web is moving forward. Users expect an experience as native as it could be from websites. The Jamstack is taking over on the frontend. Hybrid models with server side rendering and dynamic Javascript clients are the enablers of these applications. RESTful APIs excel at a different set of problems. They will not go away, quite the opposite! They’re just not the right tool for this style of applications the industry is currently shifting towards. I think REST APIs are a perfect tool for internal APIs, partner APIs and server to server communication. This is an area where GraphQL doesn’t really bring any benefits over REST. Alongside RPC it will have a great future in this area. GraphQL on the other hand is more than happy to wrap resource- and RPC-based APIs.Adobe XD for Visual Studio Code - Create and consume Design System Packageshttps://letsxd.com/vscodeDesign systems are the link between Design and Development. To build a successful, tailored, and widely-adopted system, both designers and developers need to have a seat at the table. The new Adobe XD extension for Visual Studio Code allows developers to visually map design sources, created in XD and available in Creative Cloud Libraries, to platform-specific code using design tokens. DesignOps teams will be able to create shareable Design System Packages (DSPs) that contain all the information developers need to consume while coding, including code snippets and documentation.深度阅读栏目主编:侑夕、紫益🧐一周精读🧐《设计模式 - Adapter 适配器模式》https://github.com/dt-fe/weekly/172.精读《设计模式 - Adapter 适配器模式》.md通过三个生动的例子与 JS 示例代码,帮助前端的你理解设计模式,让我们一起积累不过时的知识!Adapter(适配器模式)属于结构型模式,别名 wrapper ,结构性模式关注的是如何组合类与对象,以获得更大的结构,我们平常工作大部分时间都在与这种设计模式打交道!适配器模式是最简单的结构型模式之一,其目的是把接口不兼容问题抹平,一起来学习吧!企业级数据可视化应用有哪些机遇与挑战?https://mp.weixin.qq.com/s/ZNzjVII-ZggCjHKgR5Gofw蚂蚁@御术在外滩大会关于企业级可视化的分享文字版,从为什么需要、当前挑战和问题和未来趋势来阐述,很适合前端同学一读。CodeSandbox 是如何让 npm 上的模块直接在浏览器端运行的https://www.yuque.com/wangxiangzhong/aob8up/uf99c5How we make npm packages work in the browser 的一篇翻译文章,译者加入了自己的理解,利用这个思路其实对于一些线上开发的场景可以做不少事情。What the fuck JavaScrip t 中文版?https://github.com/denysdovhan/wtfjs/blob/master/README-zh-cn.md哈哈哈哈,原来 "b" + "a" + +"a" + "a" = "baNaNa",还有[1, 2, 3] + [4, 5, 6]; // -> '1,2,34,5,6',你知道是为啥吗?还是不要写这样的代码。我可能连 GitHub 搜索都不会用https://juejin.im/post/6891056415440535565原来 Github 上面搜索还有这么多神仙技巧...不过我还是觉得简单的才是比较好记住的。开源资讯栏目主编:侑夕Nat - 可以替换你 ls 命令的工具https://github.com/willdoescode/nat比原有 ls 的展示效果要丰富漂亮不少,安装后可以替换原有 ls,执行cargo install natls,然后code .zshrc加上alias ls='natls'就好了。Tesseract.js - 支持 100 多种语言的纯 JS OCRhttps://github.com/naptha/tesseract.js对应前端想识别图片中的文字可以用这个库来做,不过我一直用 Bob 这个 Mac 开源软件来做识别和翻译工具。Denoify-让 NPM 模块支持 Deno 且不需单独维护https://github.com/garronej/denoify一个将 NPM 模块构建 Deno 模块的包,结合着 Github Action 其实就能做到无需手动去维护了,官方是这样介绍的 For NPM module authors that would like to support Deno but do not want to write and maintain a port for itCSS Spider-一个抄网页 CSS 实现的 Chrome 扩展https://cssspider.fresalabs.com/home试用了下效果还不错,开启后,鼠标放到元素上,对应的样式就出来了,可快速 Copy 使用。Gitify-一个 github 消息通知的菜单栏工具https://github.com/manosim/gitify用 Electron 实现的一个支持多端的实时通知软件,比较适合开源软件的维护同学。Asciinema - 方便录制命令行会话过程并通过链接分享https://asciinema.org/平时我们分享一个命令行的使用,一般是录制视频然后 mp4 文件方式分享给他人,这个工具可支持直接录制生成对应 url 给到他人同时支持所有人可见。CSS 前沿栏目主编:大漠研究下 Houdini 中的 CSS Layout APIhttps://www.zhangxinxu.com/wordpress/2020/09/houdini-css-layout-api/CSS Layout API 开启自定义布局模式,只有你想不到的,没有你做不到的。只不过CSS Layout API以后注定是小部分开发者的玩具,最终出现的局面一定是少部分人创造,大部分人直接使用。CSS Houdinihttps://iamvdo.me/en/blog/css-houdiniCSS Houndini 是 CSS 世界中的魔法师。CSS Houdini 是精心设计的一种新的标准,为开发者提供自由和灵活性来构建他们自己的特性。其目的是定义底层 API ,访问浏览器的核心,从而让开发者参与到创新过程中,而不受历史标准的限制。Revolution incoming: CSS Houdini and the future of frontend developmenthttps://tsh.io/blog/css-houdini-future-frontend-development/一场革命即将到来,它将决定前端的未来。它将带来更快的用户界面,更丰富的视觉效果和全新的可能性。此外,在遥远的未来,前端甚至可能消除浏览器的兼容性问题!Bootstrap or TailwindCSS: How to decide a framework for your next project?https://blog.surjithctly.in/bootstrap-or-tailwindcss-how-to-decide-a-framework-for-your-next-projectBootstrap 号称是 CSS UI 框架中的不老神话,而新秀 TailwindCSS 却是 Atomic Design 中的战斗机。如果你是强度依赖于 CSS UI 框架来构建你的 UI 界面的话,那么这篇文章值得你花一点时间学习一下。Secrets of drawing with CSS and a single DIVhttps://levelup.gitconnected.com/secrets-of-drawing-with-css-and-a-single-div-ce9930ec9050每期 CSS 前端的末尾都会有一个关于“一个 div 的 Demo ”。那么这篇文章将告诉你,CSS 在一个 div 上是如何绘制出一些复杂的图形。一个div的Demo:A Single (Spooky) Div with Lynn Fisherhttps://codepen.io/jlengstorf/full/vYKRBwW墨者修齐栏目主编:十吾流动的边界http://flowingboundary.com/该作品运用可视化方式记录此次新冠重大疫情的不同维度数据,并用互动叙事的网页形式和隐喻修辞的视觉语言对“流动的边界”进行探讨,包含“尘埃”、“灯火”、“泪雨”、“春华”四个版块。作品尝试用艺术语言对疫情数据进行处理,打破大众对数据冷静、中立、准确的刻板印象,展开对沉浸式数据叙事体验的可视化探索。美国各州对妇女和儿童权利保护https://ccdl.claremont.edu/digital/collection/p15831coll5/id/616Holman 在 1918 年绘制的关于美国各州对妇女和儿童权利保护的可视化图形,图中径向每个切换代表一个州,外层每一个圆环为一种妇女儿童权利,如第一层圆环为有妇女儿童权利工会、第二层圆环的童工 14 岁年龄限制等,图中共 10 层圆环表示了妇女儿童相关的十项权益;在每一项上白色表示有权利保护,黑色表示没有保护或者很差。电影院能挺过疫情吗https://public.tableau.com/zh-cn/gallery/no-more-movie-theaters-decline-box-office?tab=viz-of-the-day&type=viz-of-the-day在 2020 年的疫情中,电影院及其相关产业经历了有史以来的最大危机。美国有大量的电影院票房利润大幅下降,还有无数家电影院已经倒闭。何时才能让这一切恢复正常似乎成为了一个谜题。除此以外,电影院的市场还一直在被流媒体服务抢占。查看更多墨者修齐:https://www.yuque.com/mo-college/weekly/upq75n它山之石栏目主编:平侠、侑夕腾讯文档 | 全平台系统设计https://isux.tencent.com/articles/multiplatform.html  全平台系统设计也许会成为下一代应用的基础规则,正如当初的响应式设计。Is the Internet Different?https://stratechery.com/2020/is-the-internet-different/  More broadly, the pre-Internet world, governed as it was by gatekeepers, was certainly a more unified one, at least as far as conventional wisdom was concerned — this applied to law and economics just as much as anything else. At the same time, that does not mean the pre-Internet world had a better overarching grasp on the truth, given how much more difficult it was for dissenting voices to gain distribution.Data is not the new oil: a call for a Butlerian Jihad against technocrat data ding dongshttps://scottlocklin.wordpress.com/2020/11/05/data-is-not-the-new-oil-a-call-for-a-butlerian-jihad-against-technocratic-ding-dongs/  I tire of the dialog on “big data” and “AI.” AI is an actual subject, but as used in marketing and press releases and in the babbling by ideologues and think tank dipshits, the term is a sort of grandiose malapropism meaning “statistics and machine learning.” As far as I can tell “big data” just means the data at one point lived in something other than a spreadsheet.Raspberry Pi 400: the $70 desktop PChttps://www.raspberrypi.org/blog/raspberry-pi-400-the-70-desktop-pc/  https://martinpeck.com/blog/2020/11/06/Raspberry-Pi-400/  Raspberry Pi has always been a PC company. Inspired by the home computers of the 1980s, our mission is to put affordable, high-performance, programmable computers into the hands of people all over the world. And inspired by these classic PCs, here is Raspberry Pi 400: a complete personal computer, built into a compact keyboard.国家“双循环”重大战略调整背后的5个核心逻辑https://36kr.com/p/953193853974149  “以国内大循环为主体、国内国际双循环相互促进的新发展格局”内涵是什么?意味着什么?大家真的争论得比较多,我理解新发展格局有5个核心的内容。01 未来会继续开放,但是开放的最终目的是围绕满足国内市场需求;02 开发和提升国内市场,是我们未来的重点;03 尽快补中国经济的短板;04 尽快推进中国的高质量发展;05 进行更高层次的开放,核心是互利共赢。未来的机会都在这个战略里了。把闲鱼 APP 长列表流畅度翻了倍https://mp.weixin.qq.com/s/dlOQ3Hw_U3CFQM91vcTGWQ咸鱼关于 Android 原生、flutter 页面的长列表优化经验分享,一个良心教程。网易云音乐 iOS 14 小组件实战手册https://mp.weixin.qq.com/s/gFd8fkJBkQd5RpFSD0P8Ig国内终于有厂商在慢慢跟进这个功能了,来看看网易音乐是怎么做的。抖音品质建设 - iOS 启动优化https://mp.weixin.qq.com/s/3-Sbqe9gxdV6eI1f435BDg一个 App 的启动速度给用户的印象很重要,也是让用户喜欢用的的一个因素,抖音 iOS 的启动优化从此文看做了不少事情也说明了原理所在。Flutter 之全埋点思考与实现https://juejin.im/post/6892371163859976199埋点对于阿里前端的同学应该再熟悉不过了,不过假如我问你 Flutter 埋点的原理你知道吗?QQ 音乐 Android 编译提速之路https://juejin.im/post/6891957803813584909一直觉得 QQ 音乐整体 App 做的不错,借此文来学习一波 QQ 音乐团队在增量编译组件研发上的探索与实践。语雀产品经理的成长之路https://www.yuque.com/fangqiao/oe8iog/vk6m19为什么感觉语雀的产品越做越好,同时有一条主线执行下去呢?因为它的产品经理几年都没有换过。视觉设计中发现的 11 种视错觉https://mp.weixin.qq.com/s/zGdXBq4RDLaPYduEHJiHFg日常中大家都可能会碰到一些神奇的场景,让人产生视觉错觉,本文来告诉你原因所在。Notion 的思想来源和投资人https://mp.weixin.qq.com/s/eatQQa-ArDI96wROtX66dQ好吧这个软件之前就被“吹”得很火,我也反复几个月内至少试用过三次还是觉得有些复杂最后给放弃了,不过还是有很多人用上后就特别喜欢了。查看更多:https://www.yuque.com/awesome/fe_weekly/20201109关注「Alibaba F2E」把握阿里巴巴前端新动向

如何打造一款标准的 JS SDK ?

岳鹰全景监控,是阿里UC官方出品的先进移动应用线上监控平台,为开发者及企业提供一套完整的移动应用线上质量监控解决方案。岳鹰WEB前端监控,可实时监控页面性能、JS异常、资源加载异常、API成功率、自定义错误等异常情况。本文通过岳鹰前端监控SDK的实际案例,介绍如何基于JavaScript来开发SDK,并分享一些设计原则以及实现技巧。SDK 是什么SDK全称是“Software Development Kit”,直译就是软件开发工具集。说的再通俗点就是一个面向开发者,针对特定领域的软件包。比如Java SDK(JDK),就是一个Java领域的软件包。基于它,开发人员就可以快速构建自己的Java应用。比较规范的SDK一般都会包含若干的API、开发工具集和说明文档。JS SDK也无外于此,不过鉴于JS语言本身的特性,基于Ta封装的SDK更多常见于UI组件库、统计分析、web服务接口封装、前端稳定性和性能监控等场景。岳鹰前端监控SDK[1]即属于前端稳定性和性能监控这一领域范畴的SDK。设计原则如何设计SDK,其实更多取决于你的场景,或者SDK最终的用途。比如实现一个给网页调用的SDK与用于服务端的SDK就有明显的差异,但这之间确实存在着一些共通的原则,或者方法论:最小可用性原则,即用最少的代码,如无必要勿增实体。最少依赖原则,即最低限度的外部依赖,如无必要勿增依赖。进一步阐述,即我们打造的SDK要符合以下的要求。满足功能需求SDK一般都是偏于面向某个领域,所以,同时在设计和实现的时候明确职责和边界很重要,同时还应该足够精简,专注领域内的业务。足够稳定绝不能导致宿主应用崩溃,这是最基础也是最严格的要求。较好的性能,比如SDK体积应尽量小,运行速度尽量快。可测试,保障每一次变更。向后兼容,不轻易出现 Breakchange。少依赖,易扩展最小程度的第三方依赖,尽可能自行实现,确实无法避免则最小化引入。插件化,最大限度支持扩展。Hook机制,满足个性化诉求。如何实现下面我们将通过剖析岳鹰前端监控SDK的设计过程,来看看上述的设计原则是如何应用到实际的开发过程中的。明职责,定边界前面章节提到,岳鹰前端监控SDK是前端稳定性和性能监控的SDK,主要面向前端H5领域。因此,稍加分析即可得出以下结论:前端领域,稳定性方面主要的关注点JS异常资源加载异常API请求异常白屏异常性能方面,核心的关注点白屏时间可交互时间(TTI)首屏时间FP / FMP / FCP 等上述监控内容实际上都相对独立,因此我们可以把它们横向划分为如下几大部分:明确了SDK的边界以及各部分的职责,结合前端监控的特性,我们可以开始设计SDK的整体框架了。筑框架,夯基础俗话说千里之行始于足下,因此筑牢基础十分重要。总得来说,我们需要做好下面几点:确定SDK的引用形式SDK整体而言是一个大模块,前端模块有多种表现形式:ES Module、CommonJS、AMD/CMD/UMD,而在引用方面则大体分 CDN和 NPM两种。即无论我们实现的是哪种形式的模块,最终都是通过CDN或者NPM的方式提供给用户引用。// ES Module import wpkReporter from 'wpkReporter' // CommonJS const wpkReporter = require('wpkReporter') // AMD,requireJS引用 require.config({ paths: { "wpk": "https://g.alicdn.com/woodpeckerx/jssdk/wpkReporter.js", require(['wpk', 'test'], function (wpk) { // do your business })乍看有点眼花,但事实上今时今日的前端工程领域,已有很多利器可以帮助我们达到目的。比如webpack,通过简单的配置就可以构建出一个UMD的bundle。// webpack.config.js module.exports = { output: { filename: '[name].js', path: `${__dirname}/dist`, globalObject: 'this', library: '[name]', libraryTarget: 'umd' 综上,我们可以通过webpack将SDK构建为一个UMD bundle,这样可以自动适配所有形式的模块。同时我们也将同时提供CDN和NPM两种引用方式,给用户更多选择。确定SDK的版本管理机制现有较成熟的版本管理机制当属语义化版本号[2],表现形式为 {主版本}.{次版本}.{补丁版本},简单易记好管理。一般重大的变更才会触发主版本号的更替,而且很可能新旧版本不兼容。次版本主要对应新特性或者较大的调整,因此也有可能出现breakchange。其他小的优化或bugfix就基本都是在补丁版本号体现。看到此处,是否有点似曾相识的感觉?没错,所有NPM模块都遵循语义化版本规范,因此结合第一点,我们可以将SDK初始化为一个NPM模块,结合webpack的能力就可以实现基础的版本管理及模块构建。确定SDK的基础接口接口是SDK和用户沟通的桥梁,每一个接口对应着一个独立的SDK功能,并且有明确的输入和输出。我们可以先来看看岳鹰前端监控SDK的核心接口有哪些?// 上报相关 wpk.report(logData) wpk.reportJSError(error) wpk.reportAPIError(apiData) // 配置变更 wpk.setConfig(data) // SDK诊断 wpk.diagnose() // 添加插件 wpk.addPlugin(plugin)总结接口的设计原则,如下:职责单一一个接口只做一件事情命名简单清晰,参数尽量少但可扩展好的接口命名就是最好的注释,一看即明其用处参数尽可能适用Object封装做好参数校验和逻辑保护领域分析,模块划分定边界的时候,我们已经清楚划分了SDK的几个关键的部分:全局异常、API异常、页面性能和白屏,实际上监控SDK通常也会内置对页面流量的监控,以方便用户对异常的影响面做出评估。这几个核心的关键组成部分,每一块都对应一个专业的领域,因此对应到SDK也是每一个独立的模块。除了这些核心的偏领域的模块,SDK还需要有更基础的与领域无关的模块,包括SDK内核(构造方法、插件机制、与下游服务的交互、上报队列机制、不同环境的管理等等)和工具类库。我们可以先看一下岳鹰前端监控SDK最后的整体模块划分:SDK底层提供基础的能力,包括上面提到的内核、插件机制的实现、工具类库以及暴露给用户的基础API。可以看到,我们前面提到的所有模块都以插件的形式存在,即各领域的功能都各自松散的做实现,这样使得底层能力更具通用性,同时扩展能力也更强,用户甚至也可以封装自己的插件。Biz部分更多是对于不同宿主环境的多入口适配,当前支持浏览器、Weex以及NodeJS。测试覆盖,线上无忧SDK是一个基础服务,相对于前台业务而言可能更底层些。其影响面跟应用的范围是正比的关系,更多的用户意味着更大的责任。所以SDK的质量保障也是很重要的一个环节。岳鹰前端监控SDK的质量保障策略很简单,只有两条:核心接口100%的单元测试覆盖率发布卡点:再小的版本发布也需要走集成测试回归事实上,除了核心接口,工具类库的所有功能我们都实现了100%的单元测试覆盖,我们采用的前端测试工具是轻量好用的Jest[3]。// 小巧精炼的 Jest,笔者力荐 test('isError: real error', function () { var err = new Error('this is an error') expect(util.isError(err)).toBeTruthy() })细节打磨,极致体验快捷引入极尽所能提高用户引用的效率一行代码,快速引入,享用监控全家桶功能<script> !(function(c,i,e,b){var h=i.createElement("script");var f=i.getElementsByTagName("script")[0];h.type="text/javascript";h.crossorigin=true;h.onload=function(){c[b]||(c[b]=new c.wpkReporter({bid:"dta_1_203933078"}));c[b].installAll()};f.parentNode.insertBefore(h,f);h.src=e})(window,document,"https://g.alicdn.com/woodpeckerx/jssdk/wpkReporter.js","__wpk"); </script>动态采样即通过云端下发数据采样率的方式,控制客户端上报数据的频率更好的保护监控下游自我诊断除了接口,SDK整体对用户而言就是一个黑盒,因此用户在遇到问题时很容易蒙圈 (如:为啥没有上报数据)SDK可以提供一个自我诊断的接口,快速排除基础问题。比如,SDK是否已正常初始化、关键参数是否正常设置等。增加调试模式,输出更详细的过程日志,方便定位问题渐进式的指引文档图文并茂,循序渐进入门,一步步引导用户初识SDK,领略概貌,学会基本的使用进阶,安利SDK的深度用法,帮助用户更好的使用SDK结语实际在SDK的设计和开发过程中,要处理的问题还远不止本文所述的内容,比如NPM模块开发时本地如何引用,构建的bundle大小如何调优等等。不过还是希望阅完此文,对你有所启发。同时文中若有不对之处,还望不吝赐教。相关链接[1]https://yueying-docs.effirst.com/api-usage.html[2]https://semver.org/[3]https://jestjs.io/🔥第十五届 D2 前端技术论坛开放报名,速抢!关注「Alibaba F2E」把握阿里巴巴前端新动向

Chrome 86 重要更新解读

作者 | 彼洋Chrome 86 在2020年10月推出了稳定版,现已全面应用于Android、Chrome OS、Linux、macOS 和 Windows等平台,我们一起来看下这次的重要更新。若要看全部更新,请移步。新增稳定功能文件系统访问还记得Chrome 83中的本地文件系统吗,当时的试验功能,现已稳定。通过调用 showOpenFilePicker 方法,你可以唤起文件选择窗口,进而通过返回的文件句柄对文件进行读写。代码如下:async function getFileHandle() { const opts = { types: [ description: 'Text Files', accept: { 'text/plain': ['.txt', '.text'], 'text/html': ['.html', '.htm'] return await window.showOpenFilePicker(opts); }在写文件之前,浏览器会检查用户是否已授权写文件,若未授权,会先弹窗提示用户,再进行后续操作。特别的是,调用 showDirectoryPicker 方法会打开文件目录,允许你获取多个文件,或者在目录中创建文件。这很适合IDE、媒体播放器等应用。全面阻止所有非HTTPS混合内容下载HTTPS混合内容错误是指初始网页通过安全的HTTPS链接加载,但页面中其他资源,比如图像,视频,样式表,脚本却通过不安全的HTTP链接加载,这样就会出现混合内容错误,也就是不安全因素。攻击者可拦截不安全的下载地址,将程序替换成恶意软件、甚至访问更多的敏感信息。为管控这些风险,谷歌最终还是决定在Chrome中禁止加载不安全资源。从 M82 开始,Chrome 就逐步警告及阻止混合内容的下载,到 M86,会完全阻止下载,时间表如下:要想排查网站的混合内容,使用 Chrome 访问网页,打开开发者工具,选择“Security”-"Non-Secure Origin",就可以看到Mixed Content(小编身边的网站都是安全的,暂时没找到例子,请各位自行发掘)。另外,从 M86 开始,图片类型的请求,会自动升级到 HTTPS,并且没有 HTTP 的降级,Audio/Video 类型的请求早在 M80 就开始进行了自动升级。ParentNode.replaceChildren目前,要想替换某DOM节点下的全部子节点,必须要先通过 innerHTML 或 removeChild 删除全部子节点,然后再逐个添加,比较麻烦。为此,Chrome 支持了 replaceChildren 方法,可以用参数中的子节点列表替换原有的全部子节点,代码如下:parentNode.replaceChildren(newChildren);更多信息,请移步https://www.chromestatus.com/feature/6143552666992640。更醒目的 HTTP 安全警告在我们访问 HTTPS 网页时,地址栏最左侧会显示一个锁定图标来表明当前网站是安全的,但如果 HTTPS 网页中嵌入的是并不安全的 HTTP 表单,浏览器则不会给出任何提示信息。而实际上已经有钓鱼网站通过这种方式来盗取用户的敏感信息了。所以在 Chrome 86 中,如果 HTTPS 的网页中嵌入了不安全的 HTTP 表单,表单字段下方会有极为醒目的「此表单不安全」文本提示。如果你无视提示警告继续提交表单信息,则会看到一个确认警告页面,告知你即将提交的信息并不安全。后台标签页更省电如果一个标签页在后台运行了五分钟以上,这个页面就会被暂时冻结,相应的 CPU 使用也会被限制在 1% 左右;如果页面支持自动刷新,唤醒时间被限制在每一分钟一次。新增试用功能WebHIDHID(Human Interface Device),人机界面设备。有很多长尾的HID,或者太新,或者太旧,或者不常见,导致无法被系统驱动支持。WebHID API,提供了通过JavaScript访问这些设备的方法。这会大大便利web游戏的操作性,可以使用摇杆、手柄、传感器、震动反馈等等设备。调用的代码如下:butOpenHID.addEventListener('click', async (e) => { const deviceFilter = { vendorId: 0x0fd9 }; const opts = { filters: [deviceFilter] }; const devices = await navigator.hid.requestDevice(opts); myDevice = devices[0]; await myDevice.open(); myDevice.addEventListener('inputreport', handleInpRpt); });当然,这些强大的API必须要用户授权才能调用。更多详情请移步https://web.dev/hid/多屏 Placement API目前,你可以调用 window.screen() 来获取浏览器所在屏幕,但如果你有多个屏幕,只能获取当前所在的屏幕。API调用方式及返回结果如下所示:const screen = window.screen; console.log(screen); // availHeight: 1612, // availLeft: 0, // availTop: 23, // availWidth: 3008, // colorDepth: 24, // orientation: {...}, // pixelDepth: 24, // width: 3008 // }新推出的多屏 Placement API,允许你枚举电脑连接的所有屏幕,并且可以把浏览器窗口放置在特定的屏幕上。这会大大便利幻灯片以及金融相关应用。在使用API之前,需要先请求许可,第一次请求时会向用户弹窗。async function getPermission() { const opt = { name: 'window-placement' }; try { const perm = await navigator.permissions.query(opt); return perm.state === 'granted'; } catch { return false; }获得授权后,调用 window.getScreens() 会返回 Screen 对象列表。const screens = await window.getScreens(); console.log(screens); // {id: 0, internal: false, primary: true, left: 0, ...}, // {id: 1, internal: true, primary: false, left: 3008, ...}, // ]:focus-visible新的CSS选择器,允许你修改默认的focus样式,代码如下:/* Focusing the button with a keyboard will show a dashed black line. */ button:focus-visible { outline: 4px dashed black; /* Focusing the button with a mouse, touch, or stylus will show a subtle drop shadow. */ button:focus:not(:focus-visible) { outline: none; box-shadow: 1px 1px 5px rgba(1, 1, 0, .7); }对于列表项的数字或原点,可以使用 ::marker 伪元素,来改变其颜色、尺寸、形状等信息。除此之外,还可以在设置界面选择「设置 > 高级 > 无障碍 > 短暂地突出显示焦点对象」,选择之后,焦点元素周围会有闪烁的蓝光,提供更为醒目的信息提示。废弃&删除的功能删除 WebComponents v0Chrome 80版本已经在桌面和安卓端移除了 WebComponents v0,Chrome 86 进一步把它从WebView移除。这项移除包括Custom Elements v0, Shadow DOM v0, 和 HTML Imports。移除对FTP的支持Chrome FTP功能的使用量较低,而且实现有bug,存在安全隐患,何况各平台都有更好用的FTP客户端,不值得继续维护。所以从 M72 开始,Chrome 便已着手阉割 FTP 功能,先是去掉了 HTTP 代理,现在又开始完全移除 FTP 支持,据计划,到 Chrome 88,FTP 功能会被彻底禁用。参考文献https://developers.google.com/web/updates/2020/10/nic86https://blog.chromium.org/2020/09/chrome-86-improved-focus-highlighting.htmlhttps://sspai.com/post/63084https://blog.p2hp.com/archives/7490https://web.dev/file-system-access/🔥第十五届 D2 前端技术论坛开放报名,速抢!关注「Alibaba F2E」把握阿里巴巴前端新动向

前端智能化 2020 年中总结和反思

文/甄子,阿里经济体前端委员会智能化方向负责人,淘系前端 D2C 智能团队负责人。道:为什么做前端智能化最初,前端智能化方向的提出是为了给前端技术带来变革,借助 AI 和机器学习的能力拓展前端,就像拥有望远镜人类就有了神话中的千里眼,拥有了 AI 前端也会在自身能力的基础上产生更强的“超能力”。随后,在保持这个目标推动的时候,发现很难落地。通过思考 AI 的能力特点、前端的生存现状,决定从“解决一线研发人员问题,提升一线研发人员幸福感。”为出发点,重构智能化的战略和战术体系。最后,切入点就是设计生成代码。搭建体系日臻成熟、模块化开发方式深入人心的今天,大量需求变更和复杂的业务环境,造成前端无法用“复用”的思想简单解决问题,所以,用前端智能化进行设计稿识别和理解,再通过规则生成代码,Design to Code(D2C)能够良好的解决日常模块开发的问题。术:怎么做前端智能化道生一D2C 在淘系电商C端业务上应用,支持双促会场模块 0 研发,再结合智能 UI 和智慧会场,基于会场规划的约束、场模板和运营投放配置,智能化生成会场,并针对不同圈层用户提供不同的 UI 和交互方式,再加上端智能的智能插卡、智能权益弹出挽留等能力,多管齐下,真正做到前端智能化技术赋能业务,在研发提效的基础上,做出用户价值和业务价值。Design+ to Code(D+2C)在原有设计稿识别和理解的基础上,融入 PD 对设计稿上数据、功能、交互的描述(原 PD 的线框图和交互稿等工作),从而进一步完善模型的输入,从而生成更多逻辑代码,以应对更复杂的业务场景。Pipcook用于解决前端使用机器学习成本的问题,0成本帮助前端快速掌握和使用机器学习 OTA 算法能力。同时,帮助业务落地的团队训练自己的模型,保证模型在自己业务场景能够自我迭代、更加精准。二生三做好宣传:因为大家对 AI 的陌生,所以对前端智能化产生顾虑和质疑,难以规模化推广。从淘系业务、拍卖、健康、蚂蚁、支付宝、体育、CBU……已落地场景中收集和梳理实践经验和案例,形成通俗易懂的系列文章,帮助大家了解 AI 和前端智能化。进一步落地推广,使前端智能化可以在前端领域里成为普惠技术,让一线前端研发人员获得幸福感。做好应用:模仿是高效的学习方式,机器学习本质上也是从人类的经验中模仿。在更多领域内实践,形成更多的样板工程是做好应用的重点事项。要有清晰明确的业务领域版图、技术领域版图、工程领域版图,通过涂色的方式,一点点在版图上扩大应用的领域。扩大的方式也要从我们做大家用,变成我们做样板,大家模仿并衍生出更多优秀的应用案例。同时,加强应用领域和核心领域之间的链接,充分回流应用思想、应用方法、应用能力……反哺核心领域,用来自实际应用场景的客观需求,数据化驱动核心领域的精益迭代。做好技术:持续对智能化技术体系进行深耕,也是未来的重点之一。今天的智能化技术体系仍然有很多问题,跑的太快、为了解决问题,很多应用和核心技术之间耦合,很多技术的开放能力和客制化能力不足,很多技术的理论基础不扎实,很多技术的工程化体系不完备。此外,在“人机协同的编程方式”大方向下,如何跟PD、设计、运营、用户产生标准化、数据化、自动化的链接?真正支持应用体系降低理解和使用技术的成本,做到:需求暨代码、需求暨生产、协同在线化,从而进一步、全链路、端到端的提升业务交付能力。三生万物前端技术体系升级:D2C 技术体系升级,引入 S2C 能力,形成 P2C 端到端业务交付平台:在无状态简单UI代码和简单前端业务逻辑代码生成基础上,升级到复杂UI代码和复杂业务逻辑代码生成,同时,复杂UI代码里对状态进行识别和处理,生成带状态变化的UI逻辑代码,端侧调用JSBridge、数据和服务接口的业务逻辑胶水层代码,服务端调用数据和服务接口的业务逻辑胶水层代码。智能 UI 技术体系升级,能力下沉同时支持频道业务的智能 UI 个性化,技术内敛将偏业务部分交给 P2C 端到端业务交付体系,算法自建将搜索推荐海神的算法收回前端智能化团队自己设计维护。三管齐下,保证智能 UI 技术体系普适、内聚、可控,从而做好归因分析在广泛业务场景里数据驱动的方式进行迭代。前端智能化算法工程体系升级,引入云原生能力使智能化算法框架 Pipcook 可以从数据侧、模型侧、训练侧、部署侧支持云原生,能够更便捷的融入云原生体系,保障使用者可以直接上线模型算法支撑业务,打通业务的全链路。业务研发模式升级:P2C 业务研发平台打造:需求暨代码、需求暨生产、协作在线化的全新业务研发模式。打通需求、设计、研发的全链路,保证信息流转的完整性、迅捷性、连贯性,确保最终交付物和需求的结构化信息的一致性,需求迭代的数据化驱动。设计下沉和异步化,从以往针对需求的设计进化到针对业务的设计,从设计趋势和社会发展、技术进步三个角度出发,以设计语言为依据,以设计系统为规范,提供设计范式,由模型根据设计范式进行自动化设计生产,从一个 UI 方案衍生出 N 个 UI 方案、从一个 Element 衍生出 N 个Elements。服务端下沉和抽象化、原子化,提供标准的、原子的领域能力,由 S2C 体系进行能力的理解,并通过需求的约束对调用逻辑:胶水层代码 进行生成。前端能力模型升级编程思想升级确定性首先,智能化思维解决问题的过程很简单,简单的过程就代表了确定性:一定会有答案。其实,这就像人生的困惑,每个人都有自己的答案,即便我们告诉模型所谓的正确答案,模型训练后对未知问题也不一定给我们期待的答案,但是,模型一定会给我们一个答案。其次,从经验的角度看,只要是行业里解决的很好的问题,在自己的领域里应该也能解决的很好。比如,使用图像分类模型,人家在严谨的实验中验证了图片里只要有猫或狗,图像分类模型就能准确识别出来。如果我把自己拍摄的猫猫狗狗的图片标注好喂给模型,模型训练后一定能识别出别人拍摄的猫和狗的图片,这就是确定性的另一个层面。最后,用个现实的例子,比如你来到一个新的团队,无法把所有人的面孔和名字对应上,经过一段时间的相处,你们天天交流、一起吃喝玩乐,最终你能把每个人都记住,看到其中任何一个人都能叫出ta的名字。模型也是一样,起初模型也无法记住不同人的面孔,但是,把每个人、每个角度、每种光线条件下大大小小的图片标注上每个人的名字,模型经过恰当的训练,就能跟我们一样喊出每个人的名字,这就是确定性。鲁棒性首先,智能化思维解决问题的方法很简单,告诉模型正确答案后,模型自己在样本数据里训练模型的参数和权重,自己归纳总结答案背后的思想,这就很鲁棒了。再回到“达芬奇”用OpenCV遇到的问题:阈值谬误,要总结和提炼出所有情况下image、Text、Controller成为image、Text、Controller的特征很难,然鹅,当拥有足够大规模样本数据的正确答案,模型就能提炼出足够鲁棒性的答案。其次,对算法有兴趣的同学可以Google一下遗传算法和蚁群算法等,你会发现凡是鲁棒性很强的算法都超出我们的意料,说简单点儿就是人很难总结提炼出这些算法背后的模式和思想,但是,这不妨碍我们写出遗传算法和蚁群算法去在模拟或现实的环境中训练出这些具备鲁棒性的模式和算法,这种写程序的方法本来就很鲁棒了。回忆一下,以往我们在写代码的时候都是想清楚了再写,今天,用智能化思维解决问题的时候想不清楚就能写代码,这种软件开发的方式还不够鲁棒么?进化性今天在面对服务端高可用问题的时候,至少10年前我就跟同事讨论过系统的“自愈性”问题,10年过去了,讲真没几个公司接近这个目标,然鹅,今天用智能化思维就可以做到!我先从智能化思维的进化性讲起,最后来分享一下我对系统“自愈性”的一些探索和思考。智能化思维的进化性体现在我们解决问题的方式上,以往在开发之前就确定了解题思路,开发过程中把解题思路实现掉,说白了就是Hardcode。在面对超出灵活性设计的问题时,我们还是要去写新的代码,不断给自己之前所谓的“解题思路”打补丁。用智能化思维解决问题的时候,我们并不提供解题思路,模型自己从正确答案里提炼解题思路,一旦遇到新的情况我们可以把这些情况当作新答案喂给模型,模型就能自我进化了,再遇到类似问题自行解决,这个过程就实现了自我进化,我们唯一要做的就是形成这个进化的闭环:模型答案的评估、新答案生成正负样本、构造在线训练的通路。机器学习能力的升级会用 Pipcook 或 Python 技术生态的机器学习相关框架、库、包……会数据获取、数据处理、模型配置、模型训练、模型验证、模型部署、数据回流闭环,能够用Pipcook 配置Pipline 进行流式计算,处理海量数据。会调试模型,知道如何评估模型、定位模型问题、调优模型、压缩剪枝和知识蒸馏降低模型算法复杂度提升模型性能。智能化关键指标模型功能指标之模型选择:业务是用来服务用户的,对用户的理解可以帮助我们审查业务理解的正确性。通过用户理解,可以确定用户的任务;通过理解用户的任务,可以确定模型的任务;通过理解模型的任务,可以确定模型的功能。只有确定了模型的功能,才能正确选择模型。通过对模型功能指标的梳理,后续可以监控这些指标来判断模型选择是否正确。模型理解之模型准确率:理解了模型应该做什么?才能通过模型在业务上反馈的数据设定评估指标。根据指标暨存业务、类似业务和全新业务上的指标表现,可以分别判断模型在应对已知问题、类似问题和全新问题的准确率,而类似问题和全新问题的准确率是模型的泛化能力。通过模型自身的准确率数据,结合业务上反馈数据的评估指标情况,能够更全面判断模型准确率指标。准确率理解之模型泛化能力:应对类似问题和全新问题的准确率就是模型的泛化能力。类似问题较好理解,诚如字面上“同类型”和“相似”的问题。全新问题的准确率应该理解为:未被发现、不直观、难以理解,背后却有共性的问题。不应该理解为:肆意创造且和经验完全无关的问题。因为,今天的机器学习还属于弱人工智能,对未知领域的感知、理解和创造能力缺失。使用准确率和泛化能力指标的时候,必须对各指标的边界有清晰定义。准确率指标是用于评估模型发现(召回)和解决问题能力(模型的演绎能力),泛化能力指标是用于评估模型解决非训练集问题的能力(模型的总结归纳能力)。前端智能化方向仍在不断的快速发展着,我们也仍然在路上。我们会不断的探索使用智能化的能力解决一线研发人员问题,提升一线研发人员幸福感,我们充满信心。🔥第十五届 D2 前端技术论坛开放报名,速抢!关注「Alibaba F2E」把握阿里巴巴前端新动向

企业级数据可视化应用有哪些机遇与挑战?

作者 | 林峰 在前不久的上海外滩大会上,蚂蚁集团资深技术专家林峰分享了企业级数据可视化应用的机遇与挑战,以及蚂蚁是如何实践的,我们将内容整理出来与大家分享。 大家好,很荣幸有机会能在这给大家做个分享,今天准备的主题叫做“企业级数据可视化应用的机遇与挑战”,偏向于设计体验和工程实现,主要来自于过去这些年自己在这个领域内的一些实践体会和思考,希望作为引子能给大家带来一点灵感或启发。 AntV 是蚂蚁集团的数据可视化解决方案,甚至可以说是整个阿里数据可视化的基础设施,从15年发起至今已经迭代了5年,支撑着集团内外2万+企业级应用。在这些年里我们也走过弯路,踩过很多坑,也逐渐看到些这个领域未来的趋势,所以会有今天想跟大家分享一些我们的实践和思考。 企业级应用为什么需要数据可视化 对于这个问题,在我看来最主要是两方面的原因,第一方面是因为企业级数据的特征,在当下,我们的身边,IoT 设备,云上无时无刻不在高速的产生着海量的数据,不仅是数字、文本还有各种各样的图片、音视频,这些数据内还蕴含着复杂的多维交叉、时序关系、空间信息等等,互联网企业无一例外,都需要挖掘这些数据做经营决策分析,产品改进等等,但在这快速海量多样价值稀疏的数据中萃取价值的难度不亚于淘金。 而另一方面,数据可视化对我们来说恰好是一个不错的淘金工具。我想主要有三点: 第一点是图形图像识别是人类本能,我们知道阿拉伯数字在1200年前后才被广泛使用,中国的甲骨文数字出现在公元前1600年,世界上最早的楔形文字大概出现在公元前3000年,而最早的洞穴壁画在4万年前就有了,人类习惯用图形图案去表达比用文本、数字早了4万年,科学的实验证明我们对图形图案的处理速度比文本、数字高出1到2个数量级。 而更重要的是人类花了370万年的才习得这个技能,更别提30亿年的生物进化,人类大脑有超过50%的组织用于视觉处理相关,眼睛是人类最快也是最主要的信息输入通道,我想人类基因再怎么突变在我们有生之年都不会改变人类对于图形图案高效识别本能。 第二,在可视领域里我们管这个特性叫隐喻,不管是从300年前发明的折柱饼还是当代的一些新型表达,大家会发现,能流行起来的一定都是那些跟我们生活、常识紧密相关的视觉表达,就像这些。原因很简单,易理解,在可视化领域里对认知效率的追求就像写程序时对性能的追求一样的原始、朴素。 最后一点是统计学加成,不管是简单的加和、平均还是复杂的聚类、回归,统计学是让一组数据变成一个洞察的催化剂,而且随着计算机领域的算法、算力增强,会进一步放大数据可视化的优势,因而也间接增强了人类的认知能力。 所以总结来说,数据可视化是数据淘金的必备工具,而且看起来会在未来很长很长的时间里都还会是一个不错的工具。 也正因为这些原因,我们可以看到在数据行业的版图里,有大量数据可视化强相关的产品、应用,特别是在数据分析、商业智能领域,数据可视化成为了这些产品的核心竞争力,有着数千亿美元的市场规模。 回到蚂蚁集团,在我团队参与的数百个企业级应用里超过8成需要数据可视化的能力,占比远远高于toC类的产品,从最普遍的业务系统上的各类报表,到垂类的数据场景应用,比如像性能监控系统、流量分析应用,再到复杂的如算法搭建、数据加工等研发平台,以及重度依赖可视化的商业智能,蚂蚁集团有着极其丰富的数据可视化土壤。 这就是为什么我们需要数据可视化,为什么我们会投入那么多时间,人力去打造这样一个数据可视化基础设施。 数据可视化面临的三大问题与挑战 第二部分,想和大家分享一下在数据可视化产品设计,应用研发上我们面对哪些主要的问题与挑战,以及我们是如何应对的一些思考。 第一个挑战是设计陷阱,有过这方面系统研发的朋友应该都会深有体会,理想很丰满,但现实很骨感,我们很多产品设计图上都很好看,俨然一个指挥作战中心一样,总览全局,洞察鲜明,但上线后却发现各种别扭,真实应用环境中的畸形的数据分布,类目过多等等都会让原本看起来还不错的设计变得一团糟。 一眼就能看出来的问题通常都比较好解的,为了避免研发上线后再返工,通常我们会要求在产品设计阶段就尽可能拿到真实数据作为输入,了解到真实的数据特征后再做设计,我称这个要求叫“始为真”,真实数据,真实特征; 但更难或者说更不易被发现和解决的问题是那些看起来还行,但总觉得别扭的case,我们发现这图没啥用,但这图所要展现的数据又十分重要不能没有,比较常见的就像一些一年都非常平滑的性能指标、汇总数据,角色构成等等,这些线图、饼图你什么时候来看都长得差不多,细微的变化差别你根本发现不了,而且更可怕的是就算能把变化展现出来,很多数据可视化产品设计上并没考虑分析目标,用这样一个图去表达这份数据究竟想看到什么,如果这条曲线上去了或下来了我们的用户会进一步想知道什么,会从哪些角度进一步分析,相关的决策动作是哪些?如果不往前再想一步,或者说不从终点倒推回来做设计,产出往往就会变成很多报表模块的通病“so what?Useless” 比如在这个图分析相关的项目中,用户会从一个目标节点开始查询,不断查看和展开与该节点直接或间接关联的节点进行探索分析。一开始大家也不知道该如何展现这样一个复杂的关系网络,使用了最常见的力导向算法做布局,但不管如何调整布局参数,依然一片混乱,传递不了有效的信息。但当我们反过来去探寻用户的分析目的关键是要做团伙发现,关键扩散路径,有了这个分析目标的输入,很快就有了相对应的基于特定属性的聚类布局去做团伙发现,用方便查看一度二度邻居关系的径向布局去找寻关键扩散路径。我称这个要求叫“终为实”,实际分析意图,实际决策依据。 甚至更进一步,单一的静态设计已经不能满足动态数据和分析意图变化的需求,我们还会去做运行时的动态增强,比如我们发现饼图出现大量长尾类目时会自动提醒做类目合并减少干扰,条形图自动排序,图表类型切换建议等等。 始为真,终为实,运行时增强这是我们应对设计陷阱的三个主要对策。 第二个挑战是研发困境,正如外滩大会的主题,支付宝希望推动全球金融普惠,背后所依靠的是我们的技术普惠,不仅仅是我们的产品能够服务更多的人,同时也希望我们的基础技术可以赋能给到更多的人使用。然而数据可视化这个方向本身还是有比较高的门槛,掌握各种数据分析、几何计算、图形语法等技能的专家们手里有 D3、Highchart、Tableau等各种武器,他们懂得用什么样的可视表达能解决什么样的分析需求。然而对于更多并不需要成为这个方向专家的平民来说,他们用的是Excel、PowerPoint甚至Photoshop,大量的研发实现都是找到一个看起来跟需求差不多的demo,复制粘贴。但事实上很多看起来差不多的实现可能技术选型都是有问题的,比较常见的比如一个图分析用了一个统计图表库,用离线的地理数据去做一个面对公众的应用,移动应用上用了一个给大屏用的框架等等。 我们希望给大家提供一套完整的,面向各类细分应用场景,专业的企业级数据可视化解决方案,所以会有了 AntV 这个产品矩阵,这是一个按数据特征水平分域,按能力封装垂直分层的开源产品矩阵。常规统计数据域上我们有前端领域内最完备的图形语法实现 G2,这就是刚才主持人介绍的那个获得图形语法奠基人Wilkinson肯定的项目,这是最主要的数据域,而且为了满足支付宝这种国民级的移动端应用对性能和体积的苛刻要求,我们定制了移动端的实现 F2,大家在支付宝上看到的很多财富收益变化、基金走势等等背后都是 F2,今年的 11.22,AntV 品牌日上,F2 应该还会有一个惊喜给到大家。 第二个重要的数据域是关系数据,这是反映现实世界的特征数据,不管是我们人与人之间的关系,企业间的往来,点对点的物流通通都可以用关系数据表达,今天上午,就在咱们这个会场举办的正是“图智能”的分论坛,讲了很多实时图计算,时序图智能方面的技术,图数据的应用对金融领域来说实在太重要了,不管是风控、推荐还是反洗钱等都需要用到图数据,蚂蚁不仅有图数据库 Geabase,有金融知识图谱平台,还有大量的图分析应用,这部分的需求我们用 G6 去支撑。与此同时,基于图编辑的交互方式去做业务领域建模,流程任务编排,机器学习的算法搭建近两年成为了主流的交互方式,我们其实 4 年多前就有深度依赖图编辑的应用存在,去年我们决定把这个模块的内核抽取出来去应对这个越来越旺盛的需求,在今年 11.22,我们会正式开源这个项目 X6。 第三个重要的数据域是地理空间数据,可能大家对这个数据领域并不陌生,我们早已熟悉各类 LBS 应用,但我想说的是单从数据可视化角度来说,这是一个风险极高的领域,市面上大量离线地图应用基本都是不合规的,不说满足一图一审的要求,一份完全合规的离线地理数据就已经有非常严苛的标准,AntV 的每一个产品都被成千上万个的应用所依赖,这点我们不敢掉以轻心,这就是典型的看起来都差不多,但背后的专业度可能相差十万八千里的项目,在地理空间数据域上我们有 L7. 分层是平衡灵活性和易用性的常用手段,构建在这些基础类库上我们有更高度能力封装的项目,像 G2Plot、Graphin 等等就不多介绍了,这些都可以在 AntV 官网上找到。 但有了一个比较完整的产品方案还远远不够,我们希望研发门槛能够进一步降低,在平衡灵活性和易用性上分层封装能让我们100行原始代码变成50行,但我们仍需要通过学习大量使用文档才写得出这50行代码,我们希望我们的用户不需要看文档,也不需要50行那么多,是否可以就一行代码,这不是什么天荒夜谈,我们已经在做了,半年多前的SEE Conf上我们演示过 AVA 的原型,感兴趣的朋友可以线上找到 AntV 的这个分享。我希望 AntV 的产品矩阵和智能研发能解决掉大部分的研发实现上问题。 最后一个更大的挑战,是解读诉求的升级,过往企业级的数据可视化诉求更多都只是简单直接的叙述,描述性分析,但随着越来越多可视分析的人才和理念从学术界走到工业界,出现了大量灵活多变的探索需求,圈取、联动、下钻,探索性分析逐渐成为标配,这方面我们目前也没有很成熟的解法,应对这挑战,一方面我们会从业界,特别是学术界引进可视化方向的专业人才,另一方面结合业务诉求我们自己也做了大量创新尝试,就像KPI指标的可视化拆解,波动分析等等,如果大家有这方面的想法欢迎更多的交流。 数据可视化未来趋势 关于未来趋势,我想和大家分享一个我对数据可视化发展的思考模型,过去的一些技术判断以及对未来方向的预判其实都是从这个模型而来。 正如刚才所说,数据特征对数据可视化来说是一个很重要的维度,大家看到 AntV 目前的产品矩阵设计其实只是这个模型的一个切面,跟数据特征同样重要的还有两个维度。 其中一个是时间,从时间的维度观测数据可视化的能力你会发现,我们绝大部分的应用都在展现过去的数据,一个时刻的单一数据和一个时间段上的汇总数据,本质上并没有区别,都是单点数据,比如用一个饼图去看某个组成。而当多个这样的点按照先后关系排列出来就会进入离线序列的阶段,对离线序列的可视表达跟对单点数据的表达方式是很不一样的,因为观测点更多会落在变化上面,就像我们会常用折线图去看趋势,会用动画去表达变化本身。离线序列再往前走会走到实时序列,这里面很关键的一个技术推动力是 5G/IoT 时代的到来,他会让实时计算成为主流,同样也会对实时数据可视提出新的要求,特别是在性能上,对响应时间、算法处理都会有更高的要求,另外,我认为对实时序列观测点更多会落在异动上,视觉呈现会有更多变化残影的设计去体现实时的状态。 第三个维度是分析,Gartner 给出了分析发展的几个阶段,描述性分析、诊断性分析,这包含刚才我们提到过的探索性分析,这是我们当下的主流阶段,随着 AI 技术的发展,AI 跟可视化的结合我们会把我们带入到预测性分析和规范性分析,这不仅会大大降低我们获得数据洞察的成本,提高效率,而且还会带来更具决策建议的洞察从而产生更大的价值。 所以从这几个切面去看企业级数据可视化的未来发展,能看到几个比较明朗的趋势:第一个趋势是智能化,从设计、研发、展现到分析,每一个阶段都有跟AI结合的地方,就像阿里云 DataV 从手绘设计稿自动生成代码的功能已经在生产环境上投放,刚才提到过的 AVA 在研发阶段的智能辅助,图表推荐也验证了可行性,我们内部的 BI 系统正在探索洞察的自动解读,自然语言查询和增强分析,今年初我写过一篇文章,讲的就是智能数据可视化时代的到来(传送门:欢迎进入 2020 数据可视化智能研发时代),相信接下来的几年会有突破性的进展。第二个趋势是平民化,这是我手机里的几张照片,第一张是我支付宝上买的一个基金的走势,第二张我家附近菜市场的门口的大屏,第三张是在杭州到千岛湖路上某个高速公路服务区厕所门口的引导牌。有充分的理由相信,随着IoT设备的增多,数字生活服务普及,数据可视化会在我们生活中无处不在,可视化不再只是给数据科学家用的工具,我们要有更多让老百姓一看就懂的设计。第三个趋势是决策集成,想想假如我们的数据能实时到来,决策建议能自动产生,需要我们做的就是判断是否执行,就像一个陌生来电系统提醒你这是一个被200人标记为电话推销号时一样,你闲着没事可以选择听听卖啥,也可以果断挂掉。所以以终为始的看,数据可视化的价值是决策执行后带来的,他前置依赖辅助决策时给的行动建议,而能给出行动建议的一个很关键技术能力是增强分析。我想未来的数据可视化应用都会有决策集成,就像一个数字驾驶舱一样,不仅只是看,更重要的是连接起各个系统,下发行动指令。 这是今天分享的全部内容,可能只是企业级数据可视化应用机遇与挑战的冰山一角,欢迎大家补充,数据可视化是一个即古老又年轻的领域,期待有机会跟大家有更多的交流,谢谢大家。 第十五届 D2 前端技术论坛开放报名,速抢! 关注「Alibaba F2E」把握阿里巴巴前端新动向

潮流最前端 第 5 期:纯 CSS 实现瀑布流布局已纳入 W3C 网格规范

“潮流最前端,每周一新鲜而至” If not SPAs, What? 、一周精读《设计模式 - SingleTon 单例模式》、Gazepass - 无密码的登录 API、纯CSS实现瀑布流布局已纳入W3C 网格规范、诺贝尔奖可视化、人口普查究竟查什么?本周最新前端资讯请查收。(更好的阅读体验请查看原文至语雀文档) 栏目主编:平侠 If not SPAs, What? https://macwright.com/2020/10/28/if-not-spas.html A few months ago, I wrote an article about how the SPA pattern has failed to simplify web development. The SPA pattern (Single-Page Apps), I tried to define, was about the React model, which also covers, to a large extent, the model of Vue, Angular, and other frontend frameworks. Like any critique, it begs for a prescription and I didn’t give one, other than gesturing toward server-side frameworks like Rails and Django. But I think there are some trends starting to form. I had queued up some time to really dive into the frameworks, but things like walking in parks have taken priority, so here’s just a grand tour. If you’re not a fan of the SPA approach, what else can you do? Turns out there are numerous modern alternatives from Stimulus to RedwoodJS. Building a multi-platform Figma/Sketch plugin with React https://blog.prototypr.io/building-a-multi-platform-figma-sketch-plugin-with-react-2172137a1a56 Overlay is a design-to-code tool we’ve been working on to create production-ready web components from design tools. In short, it’s a plugin that compiles design data (as JSON) into code. Releated: Anima 4.0: Go Straight From Design to React in the Design Handoff. 微信小程序入门教程 http://www.ruanyifeng.com/blog/2020/10/wechat-miniprogram-tutorial-part-three.html 阮老师教大家开发小程序,说明这项技术正在平民化,而且正被市场大范围接受。虽然很封闭,不过不得不说它的出现有望让应用开发重回曾经哪个人人可做应用的时代。 Lobe - Machine learning made easy https://lobe.ai/ Lobe has everything you need to bring your machine learning ideas to life. Just show it examples of what you want it to learn, and it automatically trains a custom machine learning model that can be shipped in your app. Lobe is a free, private desktop application that has everything you need to take your machine learning ideas from prototype to production. Releated: How AI will change software development, Experimenting with Automatic Video Creation from a Web Page. The Pragmatic Programmer 20 Years Later https://www.youtube.com/watch?v=0AzkH8SYyOc Dave Thomas and Andy Hunt conquered the world in the late 90s with the best-selling book The Pragmatic Programmer, which quickly became a staple for every programmer. This book came straight from the programming trenches, cutting through the increasing specialization and technicalities of modern software development to examine the core process - taking a requirement and producing working, maintainable code that delights its users 20 years later, they are back with a new edition that has major revisions and new material reflecting changes in the industry since its first release. 栏目主编:侑夕、紫益 一周精读《设计模式 - SingleTon 单例模式》 https://github.com/dt-fe/weekly/171.精读《设计模式 - Singleton 单例模式》.md 通过三个生动的例子与 JS 示例代码,帮助前端的你理解设计模式,让我们一起积累不过时的知识! SingleTon(单例模式)可能是最简单,最容易理解的设计模式了!但其实它并不简单,你知道什么时候不该使用单例模式,以及单例模式有哪些替代方案吗?还不了解的话就点进来学习一下吧! 我的前端成长之路:内观自在,外观世音,追寻内心平静 https://mp.weixin.qq.com/s/lq7XQGM56CovF2Q_Y8Ht4A 来自飞猪前端圣司的一篇关于自我成长的总结文章,校招毕业 4 年时间从 P5 到 P8,内观自在,外观世音,推荐前端同学一读。 对开发人员有用的定律、理论、原则和模式 https://github.com/nusr/hacker-laws-zh 值得收藏和多次阅读的程序员定律,里面收集很多抽象经验的解释,比如说「过早优化是万恶之源」、「九个女人不能在一个月内生一个孩子 」。 解释 JavaScript 的内存管理 https://felixgerschau.com/javascript-memory-management 我们平时写代码的时候几乎不太考虑 JS 的内存管理,因为浏览器已经帮忙做了,但是有时候假如碰到内存泄露,那懂一些原理会有便于你排查问题。 聊一聊二维码扫描登录原理 https://juejin.im/post/6844904111398191117 可先想后看,假如让你实现一个二维码扫码登录的功能你会怎么做? 为什么 IPv6 难以取代 IPv4 https://draveness.me/whys-the-design-ipv6-replacing-ipv4/ 西电学弟的文章,从网络原理角度来解释为什么 IPv6 难以取代 IPv4,整体博客质量超级高,值得关注。 栏目主编:侑夕 Gazepass - 无密码的登录 API https://gazepass.com/ 上周周刊中《Meet Face ID and Touch ID for the Web》,刚想去玩玩,就有人给产品化出来了,效果实现很赞,说不定不久将来在 Web 中输入框密码类型就变成可选状态了。 iOS 上的 Linux shell 工具 https://github.com/ish-app/ish/ iOS 上面的命令行工具,想想可以用它来玩什么? 使用 TensorFlow.js 进行 NSFW 检测 https://github.com/infinitered/nsfwjs NSFW 指 Not Safe For Work 的意思,这个库叫 nsfwjs,通过 TensorFlow.js 在浏览器快速识别有点点那个啥的图像,别多想,还是去看看如何实现的~ Eta - 又来了一个新的模版引擎 https://eta.js.org/ 其实 tpl 挺好用的,就是感觉有些上古时代的产物了,Eta 相比就潮流一些了,可以同时在 Node、Deno 和浏览器中使用,性能不错很轻量配置性更强一些。 使用 GitHub Actions 等生成你的跑步主页 https://github.com/yihong0618/running_page 思路很不错,借助 GitHub Actions、Gatsby、Vercel 自动部署、Mapbox 地图等能力可以将你的平时的跑步记录(Keep、Nike、Garmin 等)生成一个自动更新的主页。 CSS 前沿 栏目主编:大漠 纯 CSS 实现瀑布流布局已纳入 W3C 网格规范 https://drafts.csswg.org/css-grid-3/#masonry-layout 在不久的未来,你就可以使用纯 CSS 的特性实现瀑布流布局了。 The Dark Side of the Grid https://www.matuzo.at/blog/the-dark-side-of-the-grid/ CSS 网格布局是目前Web布局中最强大,最灵活的一个布局模块。因为它具有灵活性、广泛性和强大功能。它让我们的生活变得如此简单,但它也在用户体验和可访问性方面带来了新的危险。作者围绕着这个话题通过三篇文章的篇幅和大家探讨了网格布局和可访问性之间的关系,以及网格布局中黑暗的一面。 Thinking Outside the Box with CSS Grid https://frontend.horse/articles/thinking-outside-the-box-with-css-grid/ 现代主流浏览器对 CSS 网格的支持越来越好了,这也意味着 CSS 网格可以为 Web 布局提供前所未有的可能性,与 Flexbox 相比,我们可以用更少的元素创建更复杂的布局。但当你使用 CSS 网格布局时,不能仅仅局限于矩形布局模式下,我们应该跳出这个思维。 Responsive Grid Design: Ultimate Guide https://medium.muz.li/responsive-grid-design-ultimate-guide-7aa41ca7892 注意,这篇文章并不是介绍 CSS 网格模块的使用。而是详细介绍了网格设计给我们 Web 布局带来的帮助。网格有助于保持不同布局之间的一致性,并更快地做出设计决策。网格可以更精确地控制不同屏幕大小上的对齐和布局。本文强调了响应式网格最重要的方面,以及产品设计师如何在设计工作流中调整网格。 Fundamentals of layout in user interface design (UI) https://uxdesign.cc/fundamentals-of-layout-in-interface-design-ui-3a9dba31f1 布局是支持界面的可视组件的结构。它的工作原理是用户打开网站后,用户视线可以合理的转移到分组,排列和理解信息上。另外它还有助于网站上重要数据的突出显示。因此,布局功能对用户是不可见的,但与导航相关。一个好的布局设计与目标有关,反映在一个好的用户体验上。这就是为什么我们可以说一个正确的布局能让用户以最少的时间找到他想要的东西。这也反映在用户可以用更少的时间在网站上完成做更多的事情,以及用户更愿在网站上花更多的时间。 Are APNGs the GIFs of the Future? https://medium.com/@victorsanabria/are-apngs-the-gifs-of-the-future-ee12b95876b0 在互联网的历史上,新业务和技术不断颠覆旧的,动图(带有动效的图)就是一个很好的例子。比如我们最早的动图格式, .gif ( GIFS )图它诞生于 1987 年,是一种可移植的图像格式,支持基本的动画,是网站和社交媒体的必备工具,就像表情符号一样,它甚至被用来替代文本。然而,与其他图像格式相比,GIF 只能说它在 Web 中年龄很老。对于复杂的动图它的显示的质量是偏低的,而且加载的时间也很长(文件大)。随着技术的革新,在现代 Web 中,APNGs 图(也可以是动图)可以替代 GIFs 图,而且 APNGs 图质量高,体积小。是现代 Web 中使用动图不二选择。 Comparing Various Ways to Hide Things in CSS https://css-tricks.com/comparing-various-ways-to-hide-things-in-css/ 您可能会认为用 CSS 隐藏内容是一个简单明了的问题,但是有多种解决方案,每种解决方案都是唯一的。开发人员最常用的是 display: none 来隐藏页面上的内容。不幸的是,这种隐藏内容的方式并不是万无一失的,因为在屏幕阅读器“无法访问” 这些内容。事实上,在 CSS 中有很多“隐藏”内容的方法,每一种方法的优缺点很大程度上取决于它的使用方式。我们将在这里回顾每一种隐藏的技术,并在结束时给出一个总结,以帮助我们决定何时使用哪种隐藏技术。 一个div可以做什么:绘制蛋糕 https://codepen.io/lynnandtonic/full/bGegozj 今天要分享的 CSS 的 Demo 是使用一个 div 绘制蛋糕。 主编:十吾 诺贝尔奖可视化 https://www.informationisbeautifulawards.com/showcase/204-nobels-no-degrees 该可视化探索了多年来的诺贝尔奖故事。展示了每个获奖者的奖项类别,获奖年份,当时获奖者的年龄以及主要学术单位和家乡。每个点代表一个诺贝尔奖获得者,每个点的位置根据获奖的年份(x 轴)和获奖时的年龄(y 轴)而定。 Diagram Maker https://awslabs.github.io/diagram-maker/ Diagram Maker 是亚马逊开源的一个图编辑库,可以在外观和行为方面进行完全的自定义。它还公开了一个声明性到的接口,以减少将库集成到任何应用程序中所需的代码,并内置许多交互式功能。 Languages in the World http://snip.ly/pJsZ#http://www.puffpuffproject.com/languages.html 这是一个分析目前世界上语言体系现状的可视化项目, 用户可以探索常见的语系,查看世界各地使用的语言。数据集来源为 WALS,是一个由 55 名作者组成的小组收集到的语言结构特性汇总的资料库。 查看更多墨者修齐:https://www.yuque.com/mo-college/weekly/ggmvwv 栏目主编:平侠、侑夕 It’s time to recognise internet access as a human right https://webfoundation.org/2020/10/its-time-to-recognise-internet-access-as-a-human-right/ It’s clear that we must build a better, safer, more empowering digital world. We need governments, companies, civil society, and citizens to work together now to create this digital future. A future where internet access is understood — and realised — as a basic human right. The Contract for the Web will help us get there — through an ambitious, inclusive, and collaborative approach. IFTTT - Do more with the things you love https://ifttt.com/ https://benjamincongdon.me/blog/2020/10/30/Goodbye-IFTTT/ Connect your apps and devices in new and remarkable ways. Make the things you love more powerful. Ifttt is a free platform that helps all your products and services work better together. Microsoft overhauls Excel with live custom data types https://www.theverge.com/2020/10/29/21539844/microsoft-excel-custom-data-types-power-bi-wolfram-alpha-power-query-data Excel now goes far beyond text and numbers. Microsoft is overhauling Excel with the ability to support custom live data types. Excel users have been using Microsoft’s spreadsheet tool for decades to import, organize, and analyze data, but the basic data types have always been limited to text and numbers. While Microsoft has added dynamic arrays and some custom stocks and geography data types previously, the company is now updating Excel to let people import their own data as a custom data type. What It's Like Being a jQuery Maintainer https://github.com/readme/michal-golebiowski-owczarek Michał Gołębiowski-Owczarek is one of those heroes who drives and maintains a library that can seem either essential or passé, depending on what company you keep: jQuery. Here’s a look at how he approaches this responsibility. Native 地图与 Web 融合技术的应用与实践 https://mp.weixin.qq.com/s/RKGJOtRMjTetTZRIGzqH_Q 同层渲染是移动端 H5 的一种性能体验“黑科技”优化技术,也即将 WebView 与 Native 组件叠加到一起共处一个页面,如打车的地图用 Native 的,操作部分用 H5 来实现,美团的解决方案可供输入 iOS 性能优化实践:头条抖音如何实现 OOM 崩溃率下降 50%+ https://mp.weixin.qq.com/s/4-4M9E8NziAgshlwB7Sc6g OOM (Out Of Memory)指的是在 iOS 设备上当前应用因为内存占用过高而被操作系统强制终止,在用户侧的感知就是 App 一瞬间的闪退,Crash 对于客户端同学很好理解但是对于前端却很头疼,来看看头条的解决思路是怎么样的? 如何进行 iOS Widget 开发? https://mp.weixin.qq.com/s/xXEWWHXt4oKDSboogTbTZA 盒马同学基于盒马小镇的 Widget 开发,分享在登录授权、数据更新、界面渲染以及审核上的实践经验 产品经理如何做产品架构设计 http://www.woshipm.com/pd/4231285.html 对于产品经理来说,发展到一定阶段后,日常的工作内容往往离不开产品架构设计。这是一个极其细致的活,需要产品经理有很强的架构能力。那么产品经理如何才能摸清产品的底层逻辑、提升对产品的认知,做好产品架构呢? 到底几点睡觉才算是不叫熬夜? https://daily.zhihu.com/story/9729486 最好还是别熬夜?不如今天就早点睡吧。 人口普查究竟查什么? https://mp.weixin.qq.com/s/Hc6TR83XRpwxW_g3vIdZXw 回形针近期的一篇科普文,在中国,人口普查是如何进行的?前几次的普查究竟查到了什么? 查看更多:https://www.yuque.com/awesome/fe_weekly/20201102 第十五届 D2 前端技术论坛·无界,开放报名,速抢! 关注「Alibaba F2E」把握阿里巴巴前端新动向

在Ant Design 4.0里,我们如何追求快乐的工作?

作者 | 林外 在前不久的上海外滩大会上,蚂蚁集团高级体验设计专家林外分享了Ant Design4.0背后的设计理念,我们将内容整理出来与大家分享。 今天,我和大家分享的话题叫做,创造快乐工作。 Ant Design 的基本假定 在我开始所有话题之前,我有问题想问大家,大家工作快乐吗? 我听到了特别积极的反应,说非常的快乐。 但是呢,其实,工作并没有我们想象中那么快乐,是所有的活动当中快乐指数最低的,跟躺着带来的快乐差不多的,有些人躺着什么也不干,也比工作快乐。 什么原因导致了工作的不快乐?大部分人认为工作是为老板服务,所以很难受。另一类人是因为反馈,很多工作的结果依靠于外界,依靠于老板,所以你跟直属上司的关系,决定了工作的体验。 第三类是我们认为挑战和技能的不匹配,导致了我们工作的不快乐。当挑战大于技能的时候,你就会焦虑,当技能大于挑战的时候,你就会觉得无聊,你的工作就会在焦虑和无聊之间来回地徘徊,这是我们理解的世界。 这个问题,在数字世界中会变得更加的明显。70 年前,第一台计算机出来之后能解决的问题非常的简单,但是 70 几年过去了,数字世界得到了非常大的发展,我身边任何一个小设备都远远大于 70 年的。而现在的我们和 70 年前的前辈们没有本质的区别,我们有 7+2 的记忆法则,最多只能记住9个数字,这就导致了在数字世界当中,我们所面临的挑战远远大于人类所掌握的技能。数字世界往往给我们带来了挑战大于技能,所以你的体验是负能的。如果你的工作更加有趣,挑战能够匹配技能的时候,工作就会变得很好玩。工作就像打游戏一样,你通过了一关,技能得到了提升,工作就会变得持续好玩,所以我们在无聊和焦虑中间寻找平衡,这个平衡就是快乐的通道。 说起工作,大家多多少少会有快乐的体验,但是和躺在沙滩上睡觉的体验完全不一样。某一个下午或者晚上,需要处理一件稍微有难度的事情时,你需要集中所有的注意力,专注于你和你的事情,一抬头两个小时过去了,这是一种极度饱满、极度被满足之后的快乐,它是一种成长的快乐,也是一种挑战和技能匹配的快乐,也是全情投入的快乐,所以我们所说的快乐工作指的是全情投入的工作。 基于这样的思考,我们将每个人都追求快乐工作,作为Ant Design 的基本假定。第一个原因是,我们认为人或多或少都有这样的快乐体验;第二个很重要的原因在于,对于大多数人而言,我们醒着的绝大部分时间都要工作,如果你无法在工作中体验到快乐,人生将会在焦虑和无聊中度过。 基于这样的思考,我们找到了 Ant Design 的基本假定。就像光速不变基于相对论一样,我们想基于这样的假定,表达 Ant Design 的体系。 这就是 Ant Design 的基本假定,每个人都追求快乐工作,Ant Design 中每个人是谁?我们分成两种不同类型的用户:第一类是用户,第二类叫做设计者。所谓的设计者是创造这些应用性能的人,也就是在座的大多数。 Ant Design 的设计价值观 我们将快乐拆成两部分,一部分是快感,一部分是乐趣,基于此,我们衍生出了 Ant Design 四个价值观,设计首先是自然的,其次是确定的,第三,设计是要有意义的,第四,设计是能让用户和产品不断成长的,它是具有生长性的。 所以接下来的分享当中,因为时间的关系,我会重点分享其中的两块。第一块叫做确定性。分享一个小案例,我刚入行的时候,就碰到了社会的毒打,我想找到我的合作伙伴进行验收发布的环节,因为设计师对细节有非常强的管控情系,我用略微虔诚的态度说:“亲,能稍微调整一下列宽吗?”,他可能没理解我的意思,说“我觉得挺好”,我说“都换行了,哪里好?”,我以为会引起他的注意,结果他回了我一句:“这不重要,你行你上。” 我一开始并不明白,为什么这个世界是这样的?我认为我们都应该有同样的认知,直到有一天我看到他的竞争升级 PPT 的时候,我就明白了,原来他不是针对我,他不换行不仅在产品上,PPT 里也不换行。不同的人有不同的想法,不同的工种也有不同的想法,而我们的工作是需要这样一群人一起合作,就会导致一个问题,当不同的人有不同的、不确定性的想法,会导致研发过程的不确定性。 ETCG 2.0 :Ant Design 设计的方法论 我们总说,一个人可以走得很快,一群人才能走得很远。我们要想办法怎么让这群人可以步调一致地走得快,又走得远,我们把这套体系、方法论叫做 ETCG 2.0。这是原有 ETCG 的基础上,进行升级的过程。我们希望面对同样的问题,各个角色都能推理出同样的方案。就像你在春天种下一颗苹果树的种子,你一定在秋天可以得到一颗苹果树,而不是一颗梨树。ETCG 2.0几个字母分别代表不同的意义,第一个是功能范例,第二个是模板,模板是我们基于业务的抽象,目的是帮助新手或者帮助不同设计师保持设计的一致性,指引页面如何设计,比如这是典型的列表页,由高级搜索和表格组成。今年在模板的基础之上又做了一层更大的精进,我们做了抽象和规范衍生出了模板组件。一行模板组件,当无法满足你的需求时,只要一行代码,就可以得到一个完整的序列。除了列表页,还有表格页,还有图表、表单,以及布局,构成了我们对系统的抽象,叫做「四表一局」,它大概覆盖了中后台系统、或者企业级产品 80% 以上的业务诉求,同时本着非常开源、开放和普惠的心理,整个「四表一局」正式对外开放,大家可以访问 Ant Design 的仓库下载和使用。 ETCG 中的 C 是组件,是 Ant Design 最早和大家见面的内容,五年的时间里面,我们有了很多数量上和质量上的精进,同时创造了非常多的社会价值。这五年前,非常令我们自豪的是,有接近 1000 名贡献者参与到 Ant Design 的建设中,同时 TOP 50 当中,60% 来源于社区,他们为 2 万家企业提升了 3-5 倍的研发效能,同时我们正式于去年年底成为全球开源第一的组件库。五年前,蚂蚁集团发起了 AntDesign 这个项目,但是它今天所取得的成就是来源于社区和我们的共同努力,这里的荣誉和掌声应该献给所有为Ant Design 贡献过代码的同学,谢谢你们的支持。 ETCG的 G 有两个。第一个 G,是对组件样式的抽象,我们用了变量化的方式进行了约束和管控,它可以做什么?特别简单,你的老板今天不喜欢蓝色,想要橙色,你只要一行编码,就让组件库发生了焕然一新的变化。ETCG 的第二个 G,是我们今年重点建设的部分,也是全新的一部分,叫做 Guides,指的是人和机如何进行互动交互的过程。 比如说这里是应该放一个数值输入框,还是放一个输入框?以及如何进行放置?我们将琐碎的交互规则进行抽象和封装,让机器学习这些规则,让机器帮助我们进行这些规则。你只要导入原数据,几乎不用做任何的配置和更改,可以得到可进入生产环境、可研发的表单页面,设计得可能比初级的设计师产生的效果更好,你想要的一切都应该放在合适的地方。 这就是我们对 Ant Design 确定性的理解,不需要设计师参与的设计产品,极致提升了设计和研发的体验,当然商业化还需要很长的时间。当下如何解决现在碰到的问题?仰望星空,也要脚踏实地。作为设计师,我在想怎么解决五年前的问题,我很想说我行我上。 我们怎么使用?使用 Kitchen 进行编辑化的能力,把 13% 甩给我的合作伙伴。如果你觉得还不够,想做更多的管理和管控,甚至可以用「四表一局」的能力进行服务的搭建,搭建可进入生产环境的服务产品,让设计师变成设计工程师的角色。 如何让设计变得更自然? 在今天分享的最后一趴,我和大家聊聊这个场次经常听到的词,那就是“自然”,学术界和产业界对自然有非常多的理解。我们把它定义成了形容词,我们认为这个行为很自然,大家经常在各个场合听到的一句话,设计是关乎如何运作的问题,Ant Design 在这个基础上,要聊的是 how it worksnaturally。 同样分享一个小案例,在我们有一天的用户群里,我们的用户反馈了一个非常有意思的问题。他说语雀可以插入图片吗?语雀的负责人当时在现场,就回到:“当然可以,最基本的能力”。我们的用户问出第二个特别具有代表性的问题:“可是我们找不到在哪里”。语雀是阿里内外都很喜欢的一款文档类文件。编辑页的第一页,我们的工程师特意做成了绿色的,你点进第一个的第一行就是图片上传的功能。但是大家有没有想过?我们仅仅隐藏了一级,就让用户记不起来有这个功能,我们仅仅隐藏了一级,就让用户找不到这个功能。这不是语雀产品特有的特征和问题,而是这个时代大部分问题具有的特征和问题,因为大部分的产品处于 1973 年的基础上。 WIMP 是什么?Window、lcon、Meru、PointDevice,当我们的功能只有20几个的时候,这是非常好的设计,总比代码行好太多,今天我们说了数字世界当中,我们的设备、计算机、网络成千上亿倍的发展,用户怎么记得住 8000 个功能?用户怎么定位到8000个功能在哪里?所以 WIMP 界面碰到了人机交互的瓶颈阶段。 为什么碰到瓶颈会越来越不自然?第一个角度从人机互动的环节,当用户记不住的时候,就没办法从哪个入口出发。所以 WIMP 界面第一个不自然的原因在于,所有动作的发起都依托于用户。用户一旦记不住,一旦找不到,人机交互就没办法走通,这是 WIMP 界面的第一个问题。 第二个问题,要回到人身上。人的行为分为有意识、无意识的两层,能量消耗比较大的就是有意识层面。WIMP 在于所有的行为依托于用户有意识地触发,这本身就是一个非常消耗脑力的一件事情。在我们面对这么多功能的环境下,这两个问题导致了我们在数字世界当中碰到的巨大问题。因为我们知道系统的功能每天在增加,数字世界不需要遵循物理制造的极限,它可以进入无限备功能的叠加,所以在这个世界当中碰到的挑战远远大于我们所掌握的技能,所以 WIMP 界面碰到了诞生以来最大的问题。 我们如何解决这个问题呢?首先一定要清晰地认识到,人是有意识和无意识两种思维的结构和意识形态的。同时系统也可以分为两部分,一部分是主动功能,第二部分是被动功能,我们要尝试的守正出奇。守正延续了 WIMP 界面常规的功能,让人有意识寻找功能,触发系统的能力。但是出奇要多做一步,除了让用户找功能之外,我们要增加很多的主动式的交互,让功能找到用户。 接下来分享几个案例,在我们的常规设备当中,都已经有这样一些主动式的服务来寻找到你。 第一类是相逢不相识,名字很好听,解释也特别好玩。在语雀当中有一个小功能是我特别喜欢的功能,当我编辑一篇文档,编辑了大于 30%、50% 的文本量,这个钩会自然地帮我钩上,因为它有一个基础的设定:如果这篇文章发生了比较大规模的修改,你的订阅者很自然的想知道你这篇文章做了什么。第二个相逢不相识的地方,大家可以聚焦一下支付宝。有兴趣可以打开支付宝首页,在你的收款码应用里,解决什么样的问题?解决面对面交易的问题,所以当你输入一个金额完成以后,自然旋转屏幕的时候,这个屏幕会进行自然的翻转,这样对面扫你钱的人,可以看到信息的正面,这非常自然。 第二个主动式交互的类型,叫做可用不可见。和相逢不相识的区别在哪里?就是默默地为你提供了服务,但你可能永远不会知道它的存在。在苹果第一代出来的时候,做了一个非常牛逼的设计,因为大家都知道虚拟键盘,没有物理触感,所以误触率很高。虚拟键盘怎么解决?苹果基于非常有趣的思考,在苹果的全键盘里面,只要输入了 Desig 的时候,通过语义词的分析,N 点击的范围远远大于旁边的 B 或者 M,以及上面的 G 部分,这是帮助你做主动选择的服务,只是我们从来不知道有这样一件事情。所以我们将这些自然的人机互动方式进行整理,包括融入到更多的案例以后,发现人机主动式交互有九种不同类型的分类,除了输入法,更多是通过用户使用情景的上下文进行优化的过程。 我们有了这张人机自然的交互,怎么解决语雀的问题?我和在座的语雀设计师有过这样的讨论,用户说图片上传找不到,我们大部分人的第一反映是把图片上传显示单独放出来。这可能会解决刚才的问题,但是如果明天财务说表格找不到了,我是不是还要把表格拿出来?有人说附件找不到了,还要把附件拿出来吗?我们需要从主动式交互的角度畅想怎么优化人机互动的过程。 回到这张自然交互的工具,提供了一种简易的思维框架。我们去判断哪些是可以去做的,第一件事特别简单,我们判断用户使用的上下文是什么,我们发现很多产品的通用习惯,直接把图片拖进去,做成小的服务,用户根本不需要知道功能的存在就可以使用。 第二个从原数据角度来理解,图片是一种特殊结构的数据,它是 jpg、png,用户在外部复制了之后,进入编辑页可以主动推送他一个服务,询问他是否要粘贴,本质上并不复杂,但是它确实在 WIMP 界面传统意义的基础上,又提供了初级的部分,又额外做了一部分。 我们所定义的自然里面,是需要我们做更多的主动式的服务,让我们这个海量的功能能够在合适的场景下,去找到用户,从而节约人的脑力和体力。因为对于人来说,我们和 70 年前的爷爷辈们没有本质的区别,我们需要被善待。有感兴趣的同学可以看支付宝的访问码,也期待和大家做更多的互动。 分享的最后一趴,我简单总结一下今天做了哪些事情和分享了哪些内容。第一趴,我们提出了 Ant Design 的基本假定,我们认为每个人都缺少快乐工作,这种快乐工作是和我们平时闲散完全不同的问题。同时大多数人都不可避免的来工作,我们怎么扭转工作对我们的体验,这是人生中非常大的问题。第二趴,我们衍生出新的价值观,这四个价值观中,因为时间篇幅的原因,重点和大家讲了确定性和自然的价值观,这是历史最悠久,也是最有代表性的两块。基于这两个价值观,我们衍生出了不同的组建库也好、可视化资产也好,相关的设计资产以及设计策略,以及配套的设计工具,当然蓝色部分是我们今天介绍的重点。最后这张图特别适合拍照,这是我们系统提供给大家的主动式服务。 我是设计师林外,来自于Ant Design,谢谢大家! 第十五届 D2 前端技术论坛·无界,开放报名,速抢! 关注「Alibaba F2E」把握阿里巴巴前端新动向

“因为你,我愿意成为一个更好的人,不想成为你的包袱,因此发奋努力,只是为了想要证明我足以与你相配。” —— 《侧耳倾听》 大家好,我是张舒迪,花名圣司(取自吉卜力的动画《侧耳倾听》),2014年校招应届进入阿里巴巴担任前端开发,目前在飞猪技术部负责「用户前端和数字化经营平台团队」。 一路走来虽然时常会反思自己成长道路的关键节点,以及判断和选择,但很少会落到纸上,一方面因为自认尚算年轻,阅历不多;另一方面人生没有大起大落、跌宕起伏的经历,缺乏故事感,不过是平凡人过着平凡的生活。这次很荣幸收到邀稿,借这个机会,梳理一下进入互联网行业、成为一名前端开发道路上的那些转折点,于我个人而言是个内观的机会;如果能给在看本文的你引起一些共鸣、带来一些输入,那更是甚好。 少年时代:心之所向,一苇以航 “我相信自己,生来如同璀璨的夏日之花,不凋不败,妖冶如火,承受心跳的负荷和呼吸的累赘,乐此不疲。” —— 《生如夏花》 泰戈尔 贵州省安顺市,虹山湖环湖路(图片来源 旅行迹) “你是怎么接触前端的?” 我面试时时常会这样问候选人。 我在西南一个小城市长大,父母都是坐办公室的公务员,所以我得以较早地接触电脑。90年代还在读小学的时候,父亲单位有台四通打字机,除了最基本的文本输入外,还提供了不少搜索、替换这样的功能,书本上带着墨香的文字以数字化的方式呈现,增删改查无需斑驳的修正带,仿佛有了生命一般,于是开始伸着两个食指学着敲起了键盘。出于兴趣,下课会带上一本「我们爱科学」杂志早早去 “接父亲下班”,噼里啪啦把里面有意思的文章和连载的科幻小说敲成电子版,学着做简单的文字排版,再打印出来带到学校分给小伙伴,乐此不疲。 初中阶段学校开设了微机课,电脑教室为了防尘,需要脱鞋光脚进去,这也是绝大部分同学为数不多可以接触到计算机的机会。经典的 win98,每人会配发一张 3.5 寸的软盘用以备份资料,课上老师除了教一些办公软件的基本操作,大部分时候让学生自由探索。那段时期也是我最早的编程启蒙,在老师的指导下接触了 Basic 和 Pascal,会做一些简单的编程题目,也对类似 “数组第一位下标为什么是 0 而不是 1”、“x = x+3 这样的等式为什么能成立” 这样的问题感到好奇。 2001 年家里买了第一台电脑,用于文字处理及娱乐,装了「猫」可以上网,每次联网滴滴当当的声音现在还记忆犹新。假期玩了很多游戏,开始思考像《仙剑奇侠传》这样的游戏是怎么做出来的?在一个交流群里第一次接触到「RPG Maker」—— 一款入门级的游戏制作软件,除了可视化的贴图、角色、地图、事件、触发器等编辑能力外,还支持基于 Ruby 的脚本开发,能实现从简单的角色对白字幕、自定义货币,到复杂的 ARPG 甚至第一人称射击游戏开发。从此课余爱好变成了逛各种 RM 开发论坛,尝试着画地图、捏人物、做剧情,依葫芦画瓢写 Ruby 代码,做自己的游戏,并打包发布到论坛上分享交流;当时国内最大的 RM 社区是幻想森林和 66RPG,我在幻森当版主,认识了一波热爱游戏开发的小伙伴,其中不少人现在还在行业中摸爬滚打,有的已成中流砥柱。刚刚随手搜了一下,幻想森林虽然还在,最新帖子却基本停留在 2016年;66RPG 则早已更名「橙光」,专注于原创 IP 的 AVG 游戏制作与发行,一阵唏嘘感慨。 RPG Maker XP RGSS (Ruby Game Script System)(图片来源 RM官网) 这段「游戏开发」经历断断续续持续了 2 年多,创造一个虚拟世界带来的兴奋感逐渐转变为对计算机世界的热爱,并开始驱使我立志报考相关专业,憧憬未来能够进入这个行业一窥究竟,并能有所作为。现在回头看少年时代的这段经历,兴趣是最好的老师,在国内应试教育的大背景下,学校、家庭能够给到我学业之外自由探索的环境与空间,这么早就找到自己的兴趣点与未来方向,我感到无比幸运。 我的大学:二八年华,如丧青春 “我年轻时候喜欢说如来,就是如同要来,还没来,但终归会来。如丧,就是如同要丧,还未丧,但终归会丧。” —— 《如丧》 高晓松 故事不会总按预设的剧本往下演,不然人生该多无趣啊。07 年高考,浙大计算机系落榜,被调剂到北邮的工业设计专业,工科院校、通信背景、设计专业,感觉老天爷给我开了个玩笑,如鲠在喉;两个月暑假过得无比煎熬,每天都在去留间反复纠结,最后思量再三接受了调剂。三个原因:1)北邮也有计算机系,大一结束绩点 Top 4% 的学生有一次转系的机会,努努力可以曲线救国;2)学校有浓厚的互联网氛围,师兄师姐给了不少鼓励;3)从没去过一线城市,对北京的向往。9月入学,由于要筹划转系,大一一年又过起了白天泡画室、晚上泡自习室的苦行僧生活,然而天不遂人愿,年末综合绩点专业第 4,又一次与计算机学院擦肩而过。 北邮工业设计专业画室(2008) 我从小学开始一直是 A 等生,接连而来的高考失利/转系失败,打击不可谓不大,加之生活上也出现一些问题,整个人跌入谷底,负能量满满;那时候年轻比较文艺,会在博客上写矫情的文字与诗歌,一个人跑到景山望着故宫出神,翘课、也不参加班级活动。这样浑浑噩噩的状态持续了几个月,拯救我的是书本和音乐,是路遥的《平凡的世界》、克里希那穆提的《重新认识你自己》、张国荣的《我》、杨千嬅的《再见二丁目》……生而为人,本无所谓功过成败、高低贵贱,正是每段旅程与经历、每次跃起与沉沦、每分收获与成长塑造了一个个独一无二的个体,凑近看都那么平凡却又那么不凡;尝试品味自己的人生旅程,自我欣赏并自我和解,会发现当下所经历的就是生活本身;推己及人,曾经感觉拥挤不堪的校园、做事毛糙的同学、能力平庸的老师都开始显得立体而高大起来。 “I am what I am,我永远都爱这样的我。快乐是,快乐的方式不止一种,最荣幸是,谁都是造物者的光荣。不用闪躲,为我喜欢的生活而活,不用粉墨,就站在光明的角落。我就是我,是颜色不一样的烟火,天空海阔,要做最坚强的泡沫;我喜欢我,让蔷薇开出一种结果,孤独的沙漠里,一样盛放的赤裸裸。” —— 《我》 张国荣 生命的韧性就在于,无论被打趴多少次,只要你全情投入,自驱的力量总能一次次再把你拉起来。调整状态,抱着与其怨天尤人,不如活在当下的想法,开始尝试把生活重新拉回正轨,继续追寻梦想: 确定跨专业考研的长期目标,开始自学&旁听计算机系课程,同时开始刷 OJ(那时候北邮的 OJ 做得是真不错); 包揽了本专业几乎所有团队课设大作业的编程相关工作,做 Flash ActionScript & Flex 开发,折腾 J2SE、LAMP,帮忙维护基于 .net 的院系官网,总之只要编程相关工作我都干; 进入校学生会科技部,开始混社团,一路做到副部长,主要承担各类大型活动开闭幕视频的制作工作,涉及一些 AE 粒子特效脚本的开发,这应该也是第一次与 JavaScript 结缘,除此之外 PS、PR、AU、CorelDraw 这些软件也玩得贼溜; 由于本身专业的缘故,接触了 3DMax 和 AutoCAD,凭借手艺课余接了几个外包项目。 部分被保留下来的大一素描作业(2009) 大三下半年又开始一边在专业教室赶大作业,一边泡自习室、逛王道论坛备考的日子;期间靠专业排名拿到本专业保研名额,没做太多思考便放弃了,算是一个小插曲吧。年底怀着惴惴不安的心情再次走进考场,初试、复试、面试,次年初结果公布,如愿进入北航计算机学院,师从院长,算是又一次人生转轨,了了一桩心愿。 北航硕士新生报道,怀念那时的一头秀发(2011) 顺境享受掌声,逆境享受人生,这段持续四年的曲折经历给我带来莫大的力量与精神财富,教会我诸多道理,也很大程度奠定了我日后的事业观与人生观: 追寻热爱:支撑自己向前的应该是源自内心的热爱,对当下的热爱,对生活的热爱,也是对爱与美的追求,这种热爱很少是与生俱来的,更多时候需要自我暗示;一如写这篇文章,刚动笔也枯燥不堪,尝试说服自己沉进去,文字从笔下缓缓流淌的感觉却也让人感到平静; 日拱一卒:人会高估短期的成果,却低估长期的成就,每天哪怕花 10 分钟看 5 页书,一年就是 6~7本;每天解一个 leetcode 题目,一年你能超过 95% 的人。其实走得慢不要紧,关键要走得久,时间长了自然能走很远; 接纳失败:“那些没能将我击倒的,都使我更加强大”,挫折来得早一点,跌得狠一点不一定是坏事,与自己和解,从情绪中跳脱出来,逆境更能激发人的思考,也更能锻炼人的韧性; 留条后路:人生不是非黑即白,避免情绪化决策,给自己留条后路;我参加考研没影响保研,不喜欢设计专业也拿到了 Top 2% 的校级优秀毕设,临毕业参加校招面了一些互联网公司的产品岗位,多几个选择总不是坏事;类比到现在流行的裸辞,是不是也可以更平滑一些?先换行业再换岗位?先做副业再做主业? 转型前端:意料之外,情理之中 “生活中多数东西,最好与普通之间的差距不超过两倍,好比说纽约的出租车司机,最棒的司机与普通司机之间的差距大概是 30%;最棒的 CD 机与普通 CD 机的差距有多大?20%?这种差距很少超过两倍。但是在软件行业,还有硬件行业,这种差距有可能超过 15 倍,甚至 100 倍,这种现象很罕见,能进入这个行业,我感到很幸运。” —— 《遗失的访谈》 史蒂夫·乔布斯 北航六系 “软国重”,笔者硕士阶段所在实验室(2011) 如果说上阶段是兴趣驱使进入 CS 世界,那接下来闯入前端领域则纯属误打误撞了。 我硕士主要研究方向是基于浮动车(Floating Vehicle)的智能交通系统(ITS,Intelligent Transportation System),简单说就是通过各类车辆实时定位数据、城市路网数据、地感线圈/摄像头等传感器数据,动态计算路况、识别事故、预测拥堵、控制信号灯等,领域属于智慧城市,技术上偏 GIS 和海量时空大数据处理。 专业方向与前端也有一定关联性,主要是基于 Web 地图的数据展示,例如和北京市交通委合作的公交到站预测项目,除了预测算法本身,还基于 Tomcat + PHP + Angular + BMap 搭了 PC 的数据展示平台,这也是第一次接触到 MVVM 框架,第一次认识到原来前端还能这么玩。这个项目的研究成果支持了北京市第一套公交到站实时预测系统,通过多个 App 向社会发布到站预测信息,算是个民生工程。 那时候不知道国内互联网公司里前端是个独立方向,直到研二在一家国企实习,由于成员离职被临时调剂到前端岗顶包,承担了一小部分 Web 应用和绝大部分前端开发工作,主要是基于 VMWare VCloud 和 VSphere 搭建虚拟机 Web 可视化终端,类似 WebVNC。当时公司的技术栈是 RoR + JQuery + Bootstrap,三个月时间搭建了完整的虚机管控、可视化及配套功能模组,开始被 Web 开发这种所见即所得的爽快感吸引。 最后促使我决策进入前端领域的,是两个机缘巧合: 毕业季拿到了阿里 Java 研发的 offer,入职前部门组织了一次圆桌,新人可以跟后端、前端、客户端、测试等岗位 TL 作直接的沟通,并在入职后转到任意方向。跟拔赤(也是我现在的主管)聊了一下前端技术的现状与未来发展,聊到 PWA,他演示了一个 Wap 页面怎么通过添加到桌面的方式变成一个 Web App,B/S 无需安装、互联互通的体验让人印象深刻,聊到类比 PC 时代 B/S 逐步替代 C/S 的案例也十分生动,跟其他几个 TL 更偏业务分享、工作内容、培训方案的交流相比,一个领域未来的可能性无疑更让人神往。 那段时间有幸读了 Paul Graham 的《黑客与画家》,对我触动很大的反倒是书名,本科设计、硕士计算机,中二地感觉自己像极了左手画笔、右手键盘的「黑客与画家」,而前端恰好是视觉交互设计与计算机的交叉学科,更能发挥我的优势。最后,这次圆桌与这本书将我引入了前端的世界,职场生涯就这样从挂着研发工程师 title 写前端代码开始了。 入职阿里,转型前端(2014) 现在再回头看,这段经历也让我受益良多,以为踏错的那些「弯路」,都在某个时间点串成一线,共同组成了人生,沿途足迹清晰可见,没有白走一步: 活在当下:四年的工业设计学习生涯,教会我的不只是怎么切图,更是对好产品的审美,作为前端开发有这样一段经历弥足珍贵;小到每个项目、大到每个人生阶段,我们很难预见当下的经历对未来的影响,因此认真对待每件身边事,尊重每段人生经历独特的价值,历久必会弥新; 不给自己设限:学理科考上大学,也能坐在画室折腾素描/水粉/石膏/三大构成;本科四年一身机械+设计的本领,硕士也能跟一帮 CS 大拿聊聊设计模式与系统架构;折腾两年半大数据&算法,进到公司也可以靠前端手艺吃饭;所以别给自己设限,能力不只是经历决定的,也有意识与胆量; “模仿” 身边最优秀的人:接触一个全新的领域,学习一门全新的技能,最快也是最好的方式,便是模仿身边这个领域最优秀的人;没做过工程化/可视化/低代码化?看看集团对应领域的同学在做什么/想什么;没牵过虚拟项目?看看身边做得最好的虚拟组组长是怎么做的,多久组织一次会议,怎么制定项目组目标,怎么驱动项目组同学; 坚持阅读:书本能够提供的不只是经验与知识,有时候是灵光一闪、虎躯一震,有时候则是更平和而充实的内心,与自己的和解;尝试带着意义感去品味,音乐、电影、诗歌、话剧、动漫、游戏...亦复如是。 我在飞猪做前端:因势利导,顺势而为 “譬之若寒暑之序,时至而事生之。圣人不能为时,而能以事适时。事适於时者,其功大。” —— 《吕氏春秋》 “得时无怠,时不再来,天予不取,反为之灾。” —— 《国语·越语》 双十一前端会场玩法项目组(2014) 14年进入阿里之后的开局其实并不好。 大环境上正逢 “All in 无线” 的高潮,前端从 Mobile first 到 Mobile only,资源开始大幅从 PC 往 H5 倾斜;进入公司毕竟是个新兵蛋子,按当时「新人做老业务,老人做新业务」的分配方式,我负责了国内机票 PC 业务,1)14 年还需要写 YUI 代码、调 IE6 兼容性、走前后端统一部署,非常边缘;2)由于阿里本硕校招生无差别定级策略,跟我同一天入职同样是 P5 的小兄弟小我整整 3 岁,起跑线堪忧;3)刚转岗残缺的前端知识体系完全写不出工整而高效的代码,基本盘被吊打;如此种种,瞬间让我感受到身处一线互联网公司的巨大压力。 出于危机感和自救本能,开始找出路,接了一个多月需求后,我发现其实业务研发本身工作量并不大,但因为代码历史包袱太重(6年数万行老代码,first commit by 癫总),架构腐化严重,改动往往牵一发动全身,效率奇低。当时想法很简单,重构提升研发效率,节约出来的时间去做 H5 业务,还是得紧跟无线大潮,别与时代脱钩。 与主管 @舒克 聊了想法,之后三个月时间断断续续一边老代码正常承接业务,一边抽晚上和周末的时间做重构,一份需求做两遍。年末顺利上线,藉由这个项目我成了比 PD 还了解这块业务的开发,顺便输出了一次前端架构分享和 BU 40% 的 PC 组件,研发提效/架构升级/物料输出,大大超出主管原本只需要维稳的期望。藉由这个项目,15年初顺利晋升,也如愿开始接触无线领域,感恩。 我把这段经历称为「对现状不满,就尝试把自己 “做没”」。如果负责了一个边缘业务,可以尝试从这些方面去思考: 调整心态:认可合理性,少抱怨(脏活累活也是活,总得有人干); 发挥优势:更低的预期意味着更容易超出预期(“他做边缘业务都能有这么多产出”); 寻找痛点:主导并落地解决方案(实在没痛点,尝试一下智能化方向把自己 “做没”?或者挤时间参与一下工程化基建?); 纳投名状:需要证明自己的能力,也需要韬光养晦等待机会; 专业为先:前端是相对垂直的技术体系,业务价值不高不代表技术价值不高,不要放弃思考与改变。 航旅北京前端团队 outing 合影(2015) 随着 PC 业务工作量逐步减轻,15年我的主要精力逐渐转移到无线 H5 上来,负责了一些体量偏小的新业务,比如签证、用车,练手性质偏多。坦白说那个时期的 H5 开发是比较枯燥的,一方面业务复杂度不高,逻辑尽可能往服务端下沉,端侧少了很多抽象封装、继承拓展、设计模式的需要,带来的代码爽感大大降低;另一方面屏幕变小了,精细化要求也变高了,视觉交互上的细节问题被极速放大;加之真机调试相较 Chrome devtools 的原始感,往往一个 px 偏移或动画卡顿的调整就能耗进去几个小时。 到了一个新的环境,最先要做的还是破局,从大环境上看,那段时期业界都在攻坚性能体验的课题,围绕 Hybrid 架构各类技术方案如雨后春笋。而旅行行业的特殊性在于,用户有大量在旅行途中使用 App 的场景,国内景区要么人满为患,通信基站负荷过重导致网络降级;要么各类自然风景区、高速路/铁路沿线直接没有信号覆盖,没办法查询电子票根,更不能享受各类行中服务;同时动画滥用、Webkit BUG 也导致 CPU 彪高、耗电量增加,在类似神农架这种缺少充电手段的场景非常致命。因此相比其他行业,性能体验对于旅行业务的影响面更大也更深远。 明确性能作为突破方向后,开始找突破口。当时架构组性能优化手段集中在容器架构层面,如iDNS/SPDY 改造解决网络传输问题、离线化体系解决资源加载问题、脚手架模板优化解决 JS 阻塞渲染问题,鲜有目光聚焦在前端业务优化层面。这一方面导致跑分与体感指标存在差异,另一方面业务上基础库未预加载、combo 失效、图片未压缩、错误的构建配置等问题都可能将底层优化积累的优势损失殆尽;加之性能数据上报链路和配套度量体系不够完善,指标对业务开发同学日常工作的指导意义不足。 抓住问题之后,我从手上小业务开始逐步落地全链路的性能体验优化方案: 重新定义性能质量标准,从最初的页面秒开率,转为 三端(飞猪、手淘、支付宝)、四网(2G、3G、4G、wifi)、五维度的度量模型,在白屏、DOM Ready、Onload 等通用评估标准之外定义了「页面可见时间」与「可交互时间」等体感指标; 重构数据采集上报链路,维护基础库 Base 及 tracker 模组,制定业务埋点规范并推进埋点上报率、准确性治理; 和 @舒克 搭档搭建数据分析平台「鱼眼」,打通 ODPS、Node 工程、数据清洗及可视化链路,提供页面性能、接口性能、JS/接口异常、在离线分析、红黑榜等度量分析报表; 工程化链路升级,从 dns-prefetch 到 mtop-prefetch,从 SSR、静态资源缓存,到数据、DOM 结构、占位符多级缓存,一毫秒一毫秒、一 kb 一 kb 打磨业务实现细节,优化加载性能; 构建泛性能体验相关最佳实践,包括帧率、CPU、内存、电量等指标优化,及全链路 Tap 化、转场动画优化、长列表滚动优化等体验优化。 “‘自己’这个东西往往是看不见的,你要撞上一些别的什么东西,反弹回来,才会了解‘自己’。所以,跟很强的东西、可怕的东西、水准很高的东西相碰撞,然后才知道‘自己’是什么,这才是自我。因此,交不同类型的朋友,看不同类的书,去不同的地方,在碰撞中不断反思自己!” —— 山本耀司 藉由一些业务优化上拿到的结果,15年中进入架构组开始承担「性能体验虚拟小组」组长的工作,着力提升整个飞猪 H5 业务的性能体验,包括已有经验向团队的输出以及 Hybrid 基建改造。经过几个月的持续迭代,当年双十一拿到超过 93% 的页面秒开率,体感指标优于手淘,各项体验/能耗指标也大幅提升。 随后 Native 化渲染方案兴起,开始推进 ReactNative 体系建设,持续了大半年时间,期间打通整个工程研发、运行时、配套工具与组件库链路,并上线了 3 个业务。但总的来说这段实践经历不算成功:1)技术基建重视程度足够,但缺少对业务价值的衡量,业务方感知弱;2)脸皮薄,推动力不足,问题修复拖了一个又一个版本;3)稳定性问题,RN 最初面向独立 App 场景的定位与成熟客户端水土不服,投入产出比低。彼时集团 Weex 开始崭露头角,相较 RN 更适合阿里的业务土壤,基建随即开始往 Weex 方向倾斜。之后经历了团队调整,我被调到营销组顶替已离职 TL 开始带团队,再之后不到 2 个月时间又迎来了入职以来最大的「变化」,在此先卖个关子。回头看架构组这段经历,也同样教给我很多: 技术与业务的围城:做业务就像在浅水区游泳,你知道有个底在那里,起雾下雨了、倦了累了、抽筋儿了,双腿往下一伸就能站起来,支持好业务至少不会有太差的结果,当然如果没有 130% 的自我加压,也很难有超出期望的结果;而做技术尤其是基础技术,更像是在深水区甚至大江大海中扑腾,没有兜底、没有退路,哪怕狂风大作、巨浪滔天,一旦出发必须游到岸边才能停下休息,而很多时候你并不知道岸有多远,很容易迷失。业务线同学羡慕基础线同学有广阔的天地可以遨游,殊不知很多时候是幸存者偏差,看见的都是靠岸的人,那些还在前行的、迷失的、甚至葬身海底的人,你却不会知道他的名字; 印象即事实:职场是个小社会,在别人眼中的印象需要有意识去管理,好的印象会让周围人对你有更高期待,从而驱使你继续前行;而差的印象则可能带来旁人的不信任,乃至破罐破摔的心态;回望在阿里这些年的发展,第一印象法则帮到了我,机票重构项目的顺利上线带给我的不只是 “我也能做好前端” 自信心,也有主管和协作方的信任与更大的成长机会; 收起羽毛与玻璃心:写得了一手好代码不一定当得了一个好 PM。15年我负责飞猪域名切换及全站 HTTPS 化改造工作,项目涉及 10+ BU 过百参与者,在推进过程中,从最开始纠结中午 1点半发旺旺是不是可能吵着别人睡觉,到半夜 1点联系 PE 解决域名配置问题;从凡是求人就是 “你好师兄打扰了” 的书生气,到顶着 P5 Title 跨 BG Push P9 大佬出解决方案;从被动执行到主动推动,被逼着磨厚了脸皮。工作这些年,看过不少新人(玻璃心)或老人(自尊心,爱惜羽毛)这一关过不去,遇事不敢问、不敢说,惧怕后果,技术同学折在非技术问题上实在可惜;胸怀是委屈撑大的,收起羽毛与玻璃心,跳出墨菲定律的怪圈,其实结果远没有想象中的那么坏; 魔鬼都在细节中:性能体验、研发效率与稳定性是前端三驾马车,围绕这些大方向很多技术规划都是类似的,但落到执行结果上千差万别;类比为什么每个公司都在公布自己的战略方向,却鲜有人能执行到位或抄得到位?因为顶层设计之下,对每个细节一点一滴的执行与积累存在差异,而这些差异聚合在一起决定了成败,互联网行业尤其如此。 北京→杭州:纵身一跃,逐风而行 “你是否和我一样,一路走来我好匆忙,模糊了来时的方向,清晰了北京的茫茫。你是否也和我一样,找到了梦开始的地方,日复一日谈着理想,年复一年的那条小巷。他们说远方是大海,那里会有海风吹来,看着海鸥自由自在,不要让我的梦醒来。” —— 《海风》 郝云 从北京到杭州、从技术架构到业务支撑、从一线开发到团队 TL,2016 年是充满变化的一年。 飞猪的前身叫做航旅事业部,最初是从淘宝北京研发中心旅行相关业务分拆出来的,因此当时绝大部分研发团队都在北京。当年为响应集团京杭双中心战略,需要成立杭州研发中心,一线同学可以自行选择是否转 base 到杭州,同时基本明确了未来资源向杭州倾斜的策略。我当时面临的情况是,生活上在北京待了近 10 年,在这里娶了妻、安了家、积累了不少人脉,也早已熟悉了这里的气候与氛围;工作上刚刚从一线开发成为 TL,接手营销团队并做完了财年规划,准备放开手脚大干一场。事业与生活对抗的焦虑感在团队内蔓延。与家里人思量再三,考虑未来发展,决定响应号召转 base 到杭州,自此开始了 4 年多的双城生活。 离京前欢送会,北京前端团队合影(2016) 7月份到杭州之后,先做了一段流媒体、直播业务,这期间有个小插曲,直播底层能力由淘系支持,由于优先级问题需求一直排不上,这种跨 BU 项目推进的痛苦相信很多人都经历过。我当时手上就这一件事,退无可退,索性把工位搬到对方团队坐了两周,软磨硬泡,直至参与对方的项目去写代码作资源置换。最终项目如期上线,而我也借这个机会学习了一下淘系的工程化基础设施和研发流程,收获颇丰。拿结果有时需要非常手段或另辟蹊径,找不到方法的时候问问自己是不是被逼得还不够狠。 16年底组织架构再次调整,开始接手 8 个人的杭州度假前端团队,以及 30+ KISSY 存量项目。 当时在中台化大背景下,大量基建收口共建;飞猪是阿里一个业务 BU,而我们是飞猪的一个业务团队,在集团中台(研发框架、搭建平台等设施)与飞猪架构组(工程化、基础组件等基建)之上,向下探索是重复建设,单纯支持好业务开发又缺少沉淀(相信现在不少团队也有类似问题);加之接连的组织架构和方向调整,士气不高,第一要务是明确团队定位和方向,一起赢一场大仗。 我的选择是坚决往上走,到业务最前线去找机会,底层基建不争不抢。由于历史原因,飞猪当时是行业化的组队方式,分交通、酒店、度假等业务线分别有独立的运营、产品、技术等职能团队;对于前端研发来说,这也意味着每个行业诸如频道、搜索、详情、下单等页面都需要独立开发一套,带来诸多问题: 前端行业化组队收益有限:行业化本质是在解决供应链差异性问题(如机票,基于 GDS 的运价体系结合全球库存分销体系,构成了非常深的行业壁垒),垂直化组队模式有助于底层业务模型抽象,但行业间 C 端表达层面区别并不大(价格/库存等行业业务语义差异极大的字段到端上都是数字),端同学垂直分工带来的收益十分有限; 难以在行业间形成合力:行业数据模型不统一、定制化功能不收口导致端侧重复建设,研发效率较低,同时面向多行业串联打通的场景无法高效支撑; 难以保障端侧体验一致性:行业化过程中由于视觉交互规范不互通,相似场景产生多套方案,端侧体验难以保障一致性(如机票搜索筛选面板固底而汽车票固顶,同样是 OD 类商品产生了两种交互形式); 不利于人的成长:行业化组队方式前端同学同时负责一条业务线的全链路业务,而类似频道的纯展示页面与类似订单填写页的表单页面本身依赖的技术方案差异性大,难以抽象复用,也因此很难有更体系化的产出。 抓住上面这些问题,紧靠业务上横向打通的大方向,技术策略定为「打破三个壁垒」: 打破前端与设计师的壁垒:拉通 PD 和 UED,构建蜂鸟设计中台体系,提供跨行业一致的视觉交互规范,以及五端一致的配套组件库(H5、Weex、Rax、Android、iOS);形成「行业提报-信息收口-规范升级-沟通决策-落地实施」的标准化链路,保障规范稳定持续; 打破端与云的壁垒:拉通后端,构建 BFF 层(Node/Java),面向各个业务领域抽象视图层模型,对下屏蔽业务差异,对上提供一致的数据结构; 打破端与端的壁垒:拉通各个业务前端团队,面向各领域 BFF 构建领域驱动的前端业务框架,并以业务组件形式封装行业实现,支持面向各类场景的功能组合与插拔。 在此基础上,结合集团中台化方向,逐步沉淀出度假业务导购域(泰坦+奥恩)、搜索域(猪搜+TUS)、详情域(travelDetail+TUD)以及交易域(tripbuy+奥创)解决方案。 18年整个飞猪的平台化战役打响,我负责了其中导购与端侧两部分的平台化工作,本质上是度假已有实践经验结合各行业特点向整个飞猪的输出。双十一前顺利完成改造切流,平稳度过流量洪峰。这次改造对于业务团队来说,价值体现在几个方面: 解决研发效率瓶颈问题,支持跨行业物料互通,统一商品/交易,也为后续支持全域氛围控制、结构化表达、全域投放、资源位互通等打下基础; 为业务团队一线开发同学打开思路,在基础架构与上层业务之间明确了业务架构层,各域可以更聚焦作领域解决方案的演进,也为日后频道批量生产、搜索卡片动态化、详情域 DX 动态模板化、交易域新奥创迁移等项目打下基础; 推动团队完成组织架构调整,从按行业化纵切的组队方式,改为按领域横切,职能更加聚焦。 双十一前夜动员会,有幸和老逍同框(2017) 今天回过头再看京杭调整这次旋涡对不同个体的影响,现在 4 年过去了,选择纵身一跃转战杭州的同学,与选择留守北京在聚光灯外坚守的同学,都收获了不错的成长,也拿到了结果;把时间的尺度拉长,并不存在决策的好坏,关键在于能否坚持。这段经历带给我的: 谋前不惧,谋后不悔:做决策最忌讳的是不作为与左右摇摆,正确决策>错误决策>不决策,在全面评估、权衡利弊之后,没有最优解的情况下,相信直觉是个不错的选择;坚持与选择同样重要,路都是越走越宽的,早决策早出发,把时间用来奔跑而非等待; 横向跨端,纵向跨栈:前端是应用架构最上层,浏览器屏蔽了硬件层、虚拟层、OS 层、框架层的绝大部分细节,架构很轻薄,因而也容易面临瓶颈问题;因此横向跨端的大前端体系,或纵向跨栈的全栈开发工程师体系是个人职业发展的必由之路,面对问题打开思路能够发现更多解法; 小处着手,大处着眼:从 PC 首页改版 PM,到 HTTPS 改造/域名切换牵头上百人虚拟团队;从 H5 小业务的性能优化方案,到「性能体验虚拟小组」负责人;从度假业务架构升级,到推进飞猪平台化建设,我的经历很多都是从一件小事开始积累量变,在某个时间点借势质变。规划不用开始就做得很大,重要的是从身边小事做起并做到极致,过程中不断涌现的新问题会带来深度与壁垒;脚踏实地的同时仰望星空,看看有什么设施可以复用,手上方案又可以解决别人什么问题,加以时日技术体系与产品自然能长起来; 定目标,画大图:我从一线开发到 TL 的跃迁是从画大图开始的,相比一人吃饱全家不饿的爽快感,团队协同需要做到一张图、一场仗;好的大图首先要考虑面向的受众与要定义的问题域,摒除不相关信息的干扰,其次要能结合规划突出重点,另外还要明确表达分工及相互间的关联关系;大图务虚的表象背后,是对一个领域运筹帷幄的能力与信心; 塑造团队,使众人行:打造一个奋进、卓越的团队需要对权利与责任有更清晰的认识,带好一个一线团队由浅入深可以拆分为四个阶段,1)活水之源:昨日因今日果,招聘要凭良心;2)换位思考:眼里要有事更要有人,多做 1v1 沟通,培养同理心(我懂你)、信任感(你懂我)与利他心态(能成事);3)榜样作用:我说你听,我做你看,你说我听,你做我看,带领团队赢一场大仗;4)使命与愿景:沉淀共同的文化、目标与路径,攀更高的山,看更美的风景。 我在飞猪做导购:谋定后动,知止有得 “梁丘据谓晏子曰:‘吾至死不及夫子矣!’晏子曰:‘婴闻之,为者常成,行者常至。婴非有异于人也。常为而不置,常行而不休者,故难及也?’” —— 《晏子春秋》 18年底,平台化战役一期结束后,伴随组织架构调整,我所负责团队的业务范围从垂直的度假业务,转型横向大导购方向,专注于购前链路的流量获取与高效转化。同时组建 Java 导购和无线服务端团队,开始从纯前端职能团队,向混合栈业务团队转变,2年时间团队规模也从最初的 8 个人慢慢发展到 30+ 人。从前端到导购的变化带来了诸多挑战:第一个挑战,是可对话,具备跨职能平等沟通的能力。接手后端团队后最先涌来的是一堆新的技术或业务名词、知识体系,印象很深的是一次开会与酒店团队聊 DUMP 数据对接方案,双方一线同学你来我往,云里雾里唇枪舌剑一番没有达成一致结论,幽幽地转头看向我,我憋红了脸吐出四个字:“啥叫 DUMP?”。 类似的场景其实在工作中比比皆是:担任项目 PM,后端同步的 fgc 问题有多严重,是否需要协调其他角色协助排查?记业务会议纪要,从 CPM 切换到 CPC 模式这个 Action 应该指派给谁?跟进客户端发版,iOS abort 率万 7 是什么水平,发版是否需要延期? 接触一个全新的领域,有大量陌生的名词和知识体系需要补足,解决鸡同鸭讲的问题,然而最大的阻碍不在于新领域的壁垒,而在于我们过往的经验、资历、光环,不想示弱、害怕伤自尊,缺失放下身段与周围人请教学习、比拼技艺的勇气,这些都可能阻碍沟通,影响理解与表达,提高进入新领域的门槛, 快速具备可对话能力没有太多诀窍,重点就是放下身段,磨厚脸皮,不懂就问。每个人都会有知识盲区,抓住机会向身边任何层次/背景的人请教,收获的是自己的成长;况且刚开始就主动坦诚、积极沟通学习,也远好过死扛一段后在关键场合被打回原形(比如晋升场)。 杭州大雪,度假前端团队合影(2018) 第二个挑战,是思想跨栈,从技术/产品思维到业务思维的转变。前端技术有其特点,1)天然开源;2)交互设计强相关;3)产出物可见;这些特点带来了我们这个群体对开源与分享的热衷、对美感与细节的追求、以及对用户体验的极度关注,因此优秀的前端工程师产品 sense 多半不错,从琳琅满目的技术产品、炫酷的官网、完善而规范的文档/Demo 就可以看出。但技术/产品 sense 与业务 sense 之间仍有巨大鸿沟,以 Push 平台的 case 举例,不同思维方式考虑的点: 前端思维:配置页面打开速度怎么样,大表单有没有缓存机制,Push 文案在不同尺寸屏下被截断的效果,承接页兼容性如何; 后端思维:消息能不能准确送到,任务如何拆分与合并,线程池如何设计,海量消息高并发如何解决吞吐率和时效性问题; 产品思维:消息类型能不能横向扩展,推送时间是否支持自定义,数据报表能不能与触达任务无缝衔接打通; 业务思维:哪类 Push 拉新效果更好,什么时间发打开率更高,哪些消息面向活跃率/又有哪些是面向成交,两者比例如何拿捏。 做业务要为最终结果负责,而前端角色从技术/产品思维到业务思维的一跃有很多天然的瓶颈与鸿沟,1)过度的产品化执念导致容易陷入细节;2)缺少与业务方长时间高频度的互动,对商业模式的理解、数据的敏感度不足;3)从阿里内部看,更偏垂直专业领域的 KPI 与晋升体系一定程度上也决定了技术产品化的重要性会略高于业务结果。 从产品/技术思维到业务思维的转变,可以尝试从以下几个方面来培养: 培养对目标与数字的敏感度,尝试收集并形成自己的订阅报表,定期 Review,多追问指标升降背后的原因; 加强与业务方互动,多从业务目标视角看待每个需求,使用 STAR 法则梳理关联关系,多问几个为什么; 尝试结合掌握的信息去做公式拆解与沙盘推演,例如 App DAU = (MAU * 月均访问频次)/30 + 域内日均拉新 + 域外日均拉新,目前的现状每个指标分别在什么量级,每个需求又分别服务于哪个指标,能够提升多少,提升后是否能推导出目标达成,拆解事项并梳理优先级; 抛下过于超前的产品执念,避免陷入细节,以产出最小可行产品(MVP)为原则快速试错与迭代,区分好「锦上添花」与「雪中送碳」。 阿里五年陈授戒,梦想可贵,天生无畏(2019) 第三个挑战,是目标与定位,划定在部门中的位置与边界。飞猪采用的是大前端的团队组织形式,内部分工协作相对清晰,协调成本也比较低,因此各团队除了对接固定业务方需求外,基建分工一般更面向技术栈,如小程序一码多端(Rax/小程序)、中后台(PC/表格/表单)、互动玩法(Canvas、WebGL)、工程化架构等,这样的分工天生会有相对清晰的边界。刚开始带导购后端团队,由于更贴近业务以及横向支撑的特性,带来不少问题:1)对接业务方多,各业务方 KPI 目标存在差异,需求承接缺少主线;2)技术上各应用缺少清晰的定位与领域划分,怎么快怎么来,架构腐化快;3)边界不清、业务功能模块重复建设导致与营销、行业等协同团队踩脚的事时有发生。 因此,拆解 BU 规划,确定团队绑定的业务目标会比前端更为重要。前期重点做了几件事情: 确定团队的北极星指标,前期关注导购平台承载流量规模,在研发资源投入不变情况下,提升多样化业务承接能力;后期关注业务 IPVUV/成交转化,通过业务策略、算法的快速迭代试错优化流量承接效率,再通过规模化效应快速赋能全渠道提升转化。 围绕北极星指标确定不同阶段的核心业务方,并通过目标规划对齐确定产品技术规划与优先级;如最初的业务收口阶段,首先拉取了各个资源位渠道流量规模,然后由大至小逐步沟通推进收口,同时对于 App 首页等重点场景提供底层统一能力之上的定制化产品支撑; 对于技术规划中涉及到的各系统模块,与协作 BU、中台团队沟通确认是否有已有系统能够支撑并且规划能够 match,不满足条件的情况下明确定位区别与各自边界,自建支持。 进入业务深水区,很多时候需要攻坚的不只是技术难题,还有组织难题;在有限资源情况下,决策不做什么也比要做什么更重要。近两年的飞猪导购生涯,推动了导购域三个阶段的升级改造: 阶段一 建设飞猪物料流通大动脉(2018):解决行业物料不互通,平台能力不互通的问题,完成面向飞猪业务的选品平台(星辰)、投放平台(泰坦)、搭建平台(页匠)建设,围绕多种类型的行业物料完成统一分发链路的构建,通过一条大动脉串联了云与端。 阶段二 端侧资源位收口,业务承接物料加工(2019):构建资源位管理体系完成端侧资源位收口,包括主动触达渠道(如 Push)、静态资源位(如 App 闪屏)、动态资源位(如 SmartBanner);构建 LandingPage 生产体系,基于飞猪行业化物料快速批量化搭建场景频道、榜单、清单等 Landing 页。提高人货场匹配效率。 阶段三 构建精细化运营体系,推动运营模式转型(2020,ing):构建用户增长、人货场理解、流量调控、策略编排、商业化、数据可视化等数据化/智能化基础运营能力,实现精细化人群/场景运营,推动飞猪从面向行业运营、流量运营的模式向面向用户运营、策略运营的模式转变。同时沉淀高质量运营物料与策略,并通过人群包、数据银行、商家运营平台、生意参谋等产品渠道赋能商家优化运营能力,提升运营效率。 这段时期从前端技术层面也做了不少事情,推进 Serverless 和 H5/小程序一码多端技术体系落地,重新定义云+端的研发模式;完成基于微前端+业务 SDK 化的中后台模式落地,面向运营场景对不同产品功能原子作一体化整合;构建互动玩法体系,赋能产品与 UED 更丰富的业务表现形态。目前聚焦在前端标准对接 Flutter Engine 自绘渲染的 Web on Flutter 体系构建,以及阿里经济体的跨端研发基础设施落地,继续提升研发效率及性能体验。 两年时间导购平台逐步承接了飞猪全域超过 70% 流量,同时实现了公域推荐搜索链路 GMV 占比 5% → 15% 的增长。我个人伴随业务一路成长也有不少收获: 技术跨栈,职能跨栈,思想跨栈:跨栈的本质是不设限,能写 H5 也能写 Node,能做前端也能做后端,能搞定技术也能搞定业务,关键在于投入够不够果断和持久。两年导购平台建设,不同阶段涵盖了前端、工程、算法、产品、业务、UED 等不同职能角色的突破需要,随着问题复杂度的提升,个人的力量会显得羸弱,尝试跳出自身技术栈与职能角色,围绕目标协同更多角色打大仗,挑战巨大却也充满价值; 因势而谋,应势而动,顺势而为:“风口之上,猪都能飞”,个人成长也好,业务发展也好,借好势能保证事半功倍。导购平台从 0 做到承载飞猪全域超过 70% 的流量,抓住了人员流失的风口重抓研发提效,抓住了全域个性化的风口提供统一算法埋点能力,抓住了场景化串联行业的风口统一数据模型与选品/投放能力,抓住了平台化的风口完成大部分公域投放业务收口。磨炼对业务方向与目标的敏锐感,顺势而为; 从管理者,到管理者的管理者:最近两年团队规模一路成长到大概 35 人,带队精力明显不够,于是在年中拆分了二级团队,直观感受到的变化 1)信息链路变长,很多信息直接 get 不到了;2)对一线同学的产出与状态感知变得不太清晰;3)团队内部开始出现分工与边界问题;4)在「一线管理补位」与「跨级管理顾虑」间反复横跳。一些会议逐渐不再参与,负责的事情也逐步下放,在 BU 内的存在感变弱,坦白说会有短暂的焦虑,尤其是下面同学能力很强时。我也一直在调整自己的状态与精力分配,1)努力往信息与规划的上游走,多与产品业务一号位、各技术域一号位沟通,保证信息通达;2)把控宏观方向,从日常事务中抽出身来,结合业务思考未来 2~3 年的规划,跟进前期运作;3)对新履职的 TL 给空间、做兜底,退二进三;4)更多思考团队发展与人员成长的问题,使众人行。早前参加过一次管理培训,授课老师提到管理分几个阶段:不带人 - 带几个人 - 带几个管理者 - 做一号位;从第二到第三阶段不是人数变多的量变,而被类比为不带人-带人的质变,当时不理解,现在深以为然; 关于 Work life balance:职业成长到达一定阶段难以突破有时不是因为能力或机遇,而是源于家庭与生活,并不是说家庭不重要或者拖后腿,而正是由于家庭生活非常重要,而我们在努力工作过程中会潜意识忽视掉对家庭的参与与贡献,最后矛盾激化。其实 WLB 指的并不是 6 点还是 7 点下班,而是保证有限的家庭生活中能够全情投入(不玩手机、参与家务、制造惊喜感等等),不存在顾家就不能加班,热爱工作就无法兼顾家庭的两极分化;是否能像对待工作一样对待生活,高质量陪伴,共同谋划未来,甚至一起定一些 KPI——比如每月带孩子去一次游乐园——并努力拿到 3.75,才是 WLB 的真谛。 “人生就是一列开往坟墓的列车,路途上会有很多站,很难有人可以自始至终陪着走完。当陪你的人要下车时,即使不舍也该心存感激,然后挥手道别。” —— 《千与千寻》 本文起稿于9月中,刚起笔时笔者还在负责飞猪大导购方向,月末适逢团队调整,拖了一个多月才最终完稿;当下团队方向已然转移到飞猪的数字化运营平台体系(偏中后台)建设上来,变化不可谓不快。分分合合间,有人会留下,也有人会离开,选择本身没有对错,作为曾经一起拼搏的同路人,心怀感恩,也期待未来能够在某个路口再相逢。 飞猪大导购团队安吉团建合影(2020) 借这个机会,也简单聊聊我对 “拥抱变化” 的理解。排斥变化是人性,我们潜意识里都会惧怕未知,首先认可这一点。把人的能力成长抽象成两根曲线:一根是真实能力曲线,代表内在部分,可以想象成一根弹簧,把它立在桌上,自顶向下俯看下去一直在绕圈,一如进入一家公司成为新人,几年时间变成老油条,换一家公司又变回新人;又如每次新技术的推陈出新,都从新手入门开始,继而写 Demo、做项目、看源码、fork 拓展,最后又被更新的技术替代。俯看每次画完一圈似乎都回到原点,但从侧面看过去,高度却一直在上升,无非是有时快一点,有时慢一点。 另一根是表象能力曲线,代表真正被别人看到的部分,可以想象成一系列不连贯的正切曲线,把每段曲线看作一段经历,向上的势能往往是缓慢增加,到达峰值后缓慢下降的过程;而每次 “拥抱变化” 就是两段曲线间的纵身一跃,对技术、环境、人的陌生看似短时间内降低了我们的表象能力,但也意味着更大的潜在势能和未来更大的空间。 “拥抱变化”这件事并不是阿里特色,无论身处何时何地都会反复经历。关键点在于如何看待并接纳 “变化”,在不确定中寻找确定性,抓住每次惊险一跃的机会去提升和突破,并在表象能力背后去感受真实能力的成长。 “今天的每个人都只是约 70 亿人类中的一员,而人类又只是地球上约 100 万物种中的一个。地球只是银河系约 1000 亿颗行星中的一个,而全宇宙有约 2 万亿个星系。人的寿命只是人类历史的约 3000 分之一,而人类历史又只是地球历史的 2 万分之一。换言之,我们渺小、短命得不可思议,无论取得什么样的成就,其影响都是微不足道的。同时,我们又本能地希望有意义,希望进化,而我们只能产生一丁点儿意义。所有这些一点点的意义加起来,才是宇宙进化的推动力。” —— 《原则》 瑞·达利欧 “人固有一死,但正因为此,我们才是幸运儿。大多数人根本就不会死去,因为他们压根就没有诞生。这些潜在的、没有出生的人,数量超过了阿拉伯大沙漠中的沙粒;他们本来可能活着与我们同列,但事实上却永远也没有机会见到一丝阳光。显然,在那些没有诞生的生灵中,会有比济慈更伟大的诗人、比牛顿更伟大的科学家。我们知道这些,是因为我们的 DNA 所允许的‘可能存在的人’的数量,大大超过有机会出生的人。拥有这些罕见机会的幸运儿,就是你和我,就是生活在这世上的平淡无奇的人们。” —— 《解析彩虹》 理查德·道金斯 这篇文章是我在阿里一路成长的总纲,经验与教训都杂糅其中,如果你能看到这里,希望能有所收获,或有所启发。回头看在阿里一路的成长,校招毕业 4 年时间从 P5 到 P8,除了足够努力这个必要非充分条件外,我自知是无比的幸运,感恩这个时代,以及所处的行业与平台带来的巨大红利,感恩家人/朋友/导师/伙伴的支持。 今天团队新人越来越多,30 岁的眼睛望过去,满是自己 20 岁的影子,一样的阳光开朗、意气风发,想要成就一番事业;却也在满是荆棘的路上,一样充满汗水与泪水、挫败与迷茫。人的成长更多靠自己,环境只能催化与启发,要相信风雨之后是晴天,乌云之后有太阳,播下爱与梦想的种子,耐心等待她破土而出,生根发芽。 今年疫情、山火、洪水、蝗虫,天灾不断;灾难来临,站在社会与国家的层面 “人” 确实是太渺小了,“时代” 掸掸灰尘落到每个个体身上都是千钧重压。然而生活在这个欣欣向荣时代的我们又是如此幸运,身边每个人都充满希望,活在明天收入会更多、福利会更好、交通会更便利、物资会更丰富的预期里,坦然地认为这就是平凡得不能再平凡的人生常态,殊不知把 5000 年文明史放在坐标轴上,这样的时代甚至短到看不见;原来我们才是茫茫历史长河中的幸运儿,没有常年的饥荒、战乱、瘟疫、残酷的剥削,而是粮仓殷实、社会进步、科技发展、国泰民安。 因此,怀揣感恩的心态,享受当下的生活,你若盛开,清风自来。 我是圣司,我在飞猪前端团队,一个「胜则举杯相庆,败则拼死相救」的集体! 栏目主编:平侠 官宣!前端热爱,技术无界,第十五届 D2 前端技术论坛,我们云端相聚! https://mp.weixin.qq.com/s/xucSDGSEVW_ln_bAzBuq9Q 前端小伙伴们大家好,很开心在 1024 程序员节即将到来之际跟大家分享今年 D2 的最新消息。在 D2 走过那些年里,伴随了前端见证了大前端领域翻天覆地的变化。如今,跨端的研发、全栈的探索、智能化的代码生成、云端一体研发等,前端总在用自己的创新和活力来重新定义着“未来前端”。在这个特别的 2020 年,前端热爱,技术无界,第十五届 D2 前端技术论坛,我们相信将最优质的内容和最前沿的技术趋势带给前端开发者会是最好的礼物!过去的14届D2里面汇集了无数前端的心血和情怀,今年我们也希望能够集大家之力,让我们的D2普惠到更多的前端开发者,请大家帮忙一起转发,一起扩散,让更多人看到!!(上优酷搜“ D2前端技术论坛”马上参与) React v17.0 https://reactjs.org/blog/2020/10/20/react-v17.html The React 17 release is unusual because it doesn’t add any new developer-facing features. Instead, this release is primarily focused on making it easier to upgrade React itself. In particular, React 17 is a “stepping stone” release that makes it safer to embed a tree managed by one version of React inside a tree managed by a different version of React. It also makes it easier to embed React into apps built with other technologies. Releated: What Vue.js Does Better Than React. Node.js v15.0.0 is here! https://nodejs.medium.com/node-js-v15-0-0-is-here-deb00750f278 Just some of the features delivered in Node.js 15: AbortController, N-API Version 7, npm 7, Throw on unhandled rejections, QUIC (experimental), V8 8.6. The Tyranny of Metrics https://nemethgergely.com/blog/the-tyranny-of-metrics There seems to be a growing trend in technology--and in all aspects of our lives, really--to measure everything: business outcomes, organizational success, and individual performance. I wrote about engineering productivity and how I disagree with measuring individual performance based on metrics before, so I was excited to start reading The Tyranny of Metrics by Jerry Z. Muller. In the book, Muller draws on both Campbell and Goodhart's expertise, then provides more insights on metrics fixation and the detrimental effects they have on our everyday life. Sometimes, the best metric is no metric. Solid Relevance http://blog.cleancoder.com/uncle-bob/2020/10/18/Solid-Relevance.html The SOLID principles remain as relevant to day as they were in the 90s (and indeed before that). This is because software hasn’t changed all that much in all those years — and that is because software hasn’t change all that much since 1945 when Turing wrote the first lines of code for an electronic computer. Software is still if statements, while loops, and assignment statements — Sequence, Selection, and Iteration. Every new generation likes to think that their world is vastly different from the generation before. Every new generation is wrong about that; which is something that every new generation learns once the next new generation comes along to tell them how much everything has changed. So let’s walk through the principles, one by one. 栏目主编:侑夕、紫益 一周精读《设计模式 - Prototype 原型模式》 https://github.com/dt-fe/weekly/170.精读《设计模式 - Prototype 原型模式》.md 通过三个生动的例子与 JS 示例代码,帮助前端的你理解设计模式,让我们一起积累不过时的知识! Prototype(原型模式)属于创建型模式,既不是工厂也不是直接 New,而是以拷贝的方式创建对象。意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 2020 年你不应该错过的 CSS 新特性 https://mp.weixin.qq.com/s/n8E9htw0xXMyxHALLae_Eg 作者从 2020 第四届伦敦 CSS 分享会what's new in 2020 PPT出发,加上自己了解的角度讲了近 24 个新特性,很是值得大伙研究。 聊聊 ESM、Bundle 、Bundleless 、Vite 、Snowpack https://segmentfault.com/a/1190000025137845 之前潮流周刊第 5 期有介绍过用「其他语言来写 JS 工具」,刚好看到一篇国内文章将这几个都讲了一遍如何使用,可全面学习下。 Meet Face ID and Touch ID for the Web https://webkit.org/blog/11312/meet-face-id-and-touch-id-for-the-web/ 来做 webkit 官方一篇 Blog,将 Face ID 和 Touch ID 应用到 Web 中,一种很好的代替密码登录的方式,很是期待早日落地。 阿里拍卖全链路导购策略首次揭秘 https://mp.weixin.qq.com/s/pMrs8JiJGrzIOhtDHGlutA 技术和业务的关系一般都是密不可分的,通过此文来深入了解下阿里拍卖的全链路导购策略技术吧。 计算机网络基础知识总结 https://juejin.im/post/6885468617580904455 很像大学计算机网络考试前整理的书本知识笔记,讲到发展历程、协议、网络核心概念、物理媒介等内容,对于已工作的前端同学可当做看教科书式复习一波~ 主编:侑夕 Auto.js-安卓平台上的 JavaScript 自动化工具 https://github.com/hyb1996/Auto.js 目前网络上薅羊毛用的一个神器工具,借此来完成一些自动化的点击、领取,有 Android 的同学可去玩玩。 FingerprintJS-现代灵活的浏览器指纹库 https://github.com/fingerprintjs/fingerprintjs 从浏览器指纹生成用户的唯一标识符,Fingerprint 和 cookies 以及本地存储不同,它在隐私模式下甚至在清除浏览器数据下依然有效,值得一试。 SpaceVim 模块化 Vim 配置环境 https://github.com/SpaceVim/SpaceVim SpaceVim 是一个模块化的 Vim 集成配置环境,以模块的方式组织插件,同时为不同的语言开发量身定制了相关的开发模块,这些模块通常包括自动补全, 语法检查、格式化、调试、REPL 等相关功能,Vim 爱好者应该比较熟悉的一个工具。 Actionsflow-代替 IFTTT 的开源自动工具流 https://actionsflow.github.io/docs/ 使用 Actionsflow,可以连接你喜欢的应用、数据和 api,在操作发生时做一些接收通知,同步文件,收集数据自动化的事情。 ChineseBQB-中国表情包大集合 https://github.com/zhaoolee/ChineseBQB 原来真的有系列,有同学居然将表情包大部分给收集整理起来了,感觉可以拿着这个和输入法、聊天工具做一些有趣结合事情。 CSS 前沿 主编:大漠 2020年CSS发展调查开始了 https://stateofcss.com/ 2020年CSS发展状态的调查开启了,为了能让CSS发展的更好,请花一点点时间完成该调查。 CSS Background Patterns https://www.magicpattern.design/tools/css-backgrounds 纯CSS绘制的纹理。没有CSS做不到的,只有你想不到的。 4 things you need to know about Atomic Design https://uxdesign.cc/4-things-you-need-to-know-about-atomic-design-e0d3e8269420 如果你不太喜欢BEM,更爱Atomic Design的话,那么这篇文章会告诉你使用Atomic Design需要特别注意的四个点。 1个Div可以做什么:1个div和CSS绘制的收音机 https://codepen.io/lynnandtonic/full/GRqoEqZ 这一期给大家展示的Demo是,使用一个 div 和CSS绘制收音机! BEM Visually Explained https://medium.com/@JonUK/bem-visually-explained-6e869373bbfd 如果你总是被类名的命名感到困惑和选择器权重冲突带来烦恼,那么BEM是可选方式之一。而且BEM也是众多CSS方法论中最被认可之一,这篇文章用图解的方式向大家阐释了BEM在实际项目中应该如何使用。 Why do [most] developers hate CSS? https://uxdesign.cc/why-do-most-developers-hate-css-63c92bce36ed 都说CSS很简单,但又都说CSS不容易。估计也正是因为这个,才让开发者讨厌CSS。文章中聊了聊为什么开发者会讨厌CSS,如果你也是讨厌她,那么可以看看文章中的观点和你是不是同样的。 Beautiful Custom List Styles Using Modern CSS https://medium.com/front-end-weekly/custom-list-styles-using-marker-710ad80ce760 美化列表标记符,以往更多使用的是 list-style ,但从现在开始,我们可以开始使用真正的列表标记符 ::marker 来美化列表,还可以列表标记符加样式。 标准化动态 主编:彼洋 Chrome 86 特性 Cache Partition (缓存分区) 解读 https://www.yuque.com/docs/share/81e9e6f1-8371-4ee4-89d9-6a869c108121 2020年10月份发布的 Chrome 86 中, 还有一项重要特性。为了保护隐私,它改变了浏览器核心缓存组件 HTTP Cache的工作方式,开始启用“缓存分区 (cache partitioning)”机制。从此,不同站点将无法使用同一缓存资源。 主编:十吾 全球空气质量一览 https://public.tableau.com/en-gb/gallery/air-we-breathe?tab=viz-of-the-day&type=viz-of-the-day Christian Felix 制作的这幅信息可视化作品研究了全球空气污染的现状,以PM2.5以及其他相关指标来评估每个城市的空气污染程度。 U.S. Wind Map http://hint.fm/wind/ 这是美国 15 年的一个动态风速可视化项目,模拟了全国各地的风速和方向。 https://www.informationisbeautifulawards.com/showcase/483-creative-routines 创作者(作曲家,画家,作家,科学家,哲学家)如何找到时间创作作品?梅森·柯瑞(Mason Currey)调查了数百名创意者为了节省时间,每天工作而运用的严格的“每日仪式”。有些人遵循相同的纪律制度数十年,而另一些人则只有在从事特定作品时才锁定模式。“创意例程”将 Currey 研究的例程可视化。 查看更多墨者修齐:https://www.yuque.com/mo-college/weekly/tnhea5#se0qr 栏目主编:平侠、侑夕 State-Switch Controls: The Infamous Case of the "Mute" Button https://www.nngroup.com/articles/state-switch-buttons/ Summary: On–off controls that switch between two different system states need to clearly communicate to users both the current state and the state the system will move to, should the user press that control. Atlassian - Moving to a cloud future, together https://www.atlassian.com/migration/journey-to-cloud Today, the majority of you already benefit from the advantages of cloud, with more server and Data Center customers making the switch every day. To ensure we’re delivering the cloud experience you deserve, we’re sharpening our focus as a cloud-first company and making bold changes to our self-managed offerings. 王兴:别轻视自己,别迷信他人 https://mp.weixin.qq.com/s/-8sC4WICGmSFhIbbfEa0_A 本文为清华大学共青团团委举办“对话王兴:20年,从心出发”主题活动,清华1997级电子系校友王兴,在蒙民伟音乐厅向清华学子,分享人生经验与创业历程,并提出三点建议:第一,别太不把自己当回事;第二,也别太把自己当回事;第三,也别太把别人当回事,但要把客户当头等事。 只有平庸的人,才总是处于最佳状态 https://mp.weixin.qq.com/s/HAI71-EXSdNYlDGm3MGSzw 如今,管理者面临越来越复杂的问题,也面临越来越不确定的变化,管理者要锻炼哪几种特质呢?最近,思考的时间比平时多了一些。借此机会,就把我最近的思考,看到的一些好句子,梳理成给管理者的8个建议,分享给你,希望对你有所启发。我们一个一个说。 OnRL: 基于在线强化学习的移动视频传输优化 https://mp.weixin.qq.com/s/YPgxinHa_mGQ82waLqNDqA 从 2019 年开始,淘系技术部内容社交互动团队和北京邮电大学周安福教授一起着手研究更好的基于机器学习的智能拥塞控制算法,在实验室环境完成原型验证后在淘宝直播的生产环境做实际效果对比,从实际数据来看效果明显,后面梳理出这篇总结。 浏览器是如何调度进程和线程的? https://mp.weixin.qq.com/s/bkSmKYGHk0V5eZIfuSTNyQ 作者以 Chrome 为例,给你浅显介绍线程和进程这两个概念,看完后再去学习 JavaScript 的执行机制会更便于理解。 iOS 性能优化:优化 App 启动速度 https://mp.weixin.qq.com/s/h3vB_zEJBAHCfGmD5EkMcw 从 iOS 启动的名词解释、启动介绍、测试 App 启动时间最后到使用 Instruments 分析和优化 App 启动过程以及如何监控时间来一一介绍,前端同学可当做科普文来看。 手机建筑摄影:从理解建筑之美开始 https://daily.zhihu.com/story/9729231 本文主要从设计角度讲手机建筑摄影,看完后很有一种「建筑是凝固的音乐」的完美诠释,也不由播放起「重塑雕像的权利」的音乐。 作弊与反作弊的较量:分屏器真的安全吗? https://zhuanlan.zhihu.com/p/155819108 不少高校由于疫情将考试从线下搬到了线上,但不同于线下,线上监考由于增加了更多不可控因素,作者用尽可能通俗易懂的方式,向大家分享一些作弊与反作弊的知识,很是潮流。 关注「Alibaba F2E」把握阿里巴巴前端新动向

官宣!前端热爱,技术无界,第十五届 D2 前端技术论坛,我们云端相聚!

第十五届 D2 前端技术论坛,如约而至。 D2 前端技术论坛 (Designer & Developer Frontend Technology Forum, 简称 D2),是由阿里经济体前端委员会主办的面向全球前端领域的技术论坛,立志于建设一个促进业内交流、引领前端领域发展的平台。目前 D2 已经成功地举办了 14 届,为国内外前端领域的开发者和设计者提供了共同探讨行业发展的机会,以技术会友、一起分享技术的乐趣。 在过去的这些年里,随着语言标准的完善、硬件的进化,前端的应用场景越来越广泛,如跨端的研发、全栈的探索、智能化的代码生成,前端一直在用自己的创新和活力,重新定义着“未来前端”。前端热爱,技术无界,在这个特别的 2020 年,第十五届 D2 前端技术论坛,我们依旧带着最优质的内容和最前沿的技术趋势与大家相见。 本次 D2 将于 12月19日 和 12月20日 两天在优酷进行线上直播,我们调整了往年一天并行三个专场的形式,今年进行串行的内容设置,以便两天时间让大家可以看完全部的内容,收获更多的知识,获得更多的成长。 D2 依旧秉承着它的初心,促进前端行业技术交流,引领前端技术发展,非盈利,不商业化,一杯咖啡的价格,只为给大家带来更好的线上参会体验,同时你将收获最前沿的技术内容。此次云端相聚,请大家关注优酷的 D2 直播间,并提前进行线上购票。 售票时间:即刻起至12月1日 早鸟价格:30元 售票时间:12月1日至12月20日直播结束 晚鸟价格:98元 直接识别上述二维码,或打开手机优酷 APP /支付宝 APP扫描上述二维码,或点击阅读原文立即购买大会门票。 关于线上直播间的购票说明请以 D2 购票页的购买规则为准。 回顾去年的第十四届 D2 前端技术论坛,23 位演讲嘉宾为我们带来了 21 个精彩话题。 在语言框架专场,JavaScript 语言持续新增的新特性都是怎么产生的?JavaScript 未来即将要做什么?让TC39 的核心成员 Daniel 进行了精彩的分享!周爱民老师为我们带来了 JavaScript 中最为精彩的、动态与静态语言特性结合的程序执行过程。 超火爆的 Serverless 专场中,来自 ZEIT 的讲师 Matheus Fernandes、Shu Ding 分享「 Serverless 赋能前端应用开发」,看 Serverless 如何大幅提升应用的可用性与伸缩性!人气满满的狼叔带来了阿里巴巴 Serverless 共建组中关于 Serverless SSR 和它的演进过程、背后思考,超前沿的技术配上幽默的演讲和“狼”味十足的胡子,收获了很多粉丝的好评。张挺的分享带领我们一起看 Serverless 体系下全新的框架、工具链和研发模式是什么样的,在阿里经济体我们已经逐渐的在业务中应用落地了! 只简单列举去年两个专场的内容就感觉已经干货程度爆表了啊!是不是更加期待今年的大会内容了呢?! (图:第十四届 D2 前端技术论坛部分演讲嘉宾) 晚场的精彩话题,则是我们给大家准备的彩蛋,召奴、凌征、亨睿带来的三个分享可以称之为“前端黑科技”,着实让人眼前一亮。有 Daniel Ehrenberg,响马,玉伯,Hax 、Winter 坐镇的 《D2 之夜》嘉宾交流环节则就 优秀的前端需要什么样的基本素质或能力模型、如何培养自己的思维能力、如何保持对技术的热爱和前进的动力等前端同学们最关心的一些话题展开了激烈和深入的探讨,作为前端领域的榜样和领路人,他们对大家的提问和困惑知无不尽,统统回答,让人印象深刻。 (图:第十四届 D2 前端技术论坛 《D2 之夜》合影) 今年我们依旧会为大家准备干货满满的内容。内容将涵盖语言框架、跨端技术、Node.js(Serverless)、前端安全生产和多样化的前端技术。 语言框架专场 继去年 D2 的语言专场后,这段时间又有哪些新的语言诞生了,哪些语言规范又增加了新特性?函数式编程和函数式流编程的思想究竟如何,我们是否应该将其引入到我们的产品中?本届 D2 的语言框架专场,将邀请 RxJS 的开发者为大家介绍 RxJS 内部的结构,以及 RxJS 如何重构的又快又小。同时我们也将邀请 Google 的 V8 核心成员讲述最新 ECMAScript 新特性,以及这些特性在 TC39 讨论中如何克服困难,脱颖而出成为标准的故事。 跨端技术专场 伴随互联网展示设备形态的多元化,前有 Web、H5、Hybrid 开宗立派,后有 Native 化、小程序、自绘渲染异军突起,前端技术百花齐放。在此基础上,Flutter 跨端方案与 IoT 平台的火热又带来了大前端诸多新的机会与挑战,面对愈发繁荣的多端多平台生态与适配场景,我们该如何高效驾驭?本届 D2 跨端技术专场将邀请一线技术专家,围绕移动与 IoT 等平台,为各位带来有关跨端研发解决方案的新思路、新进展、新挑战,结合真实业务场景共同剖析跨端研发提效、性能优化的最佳实践。 Node.js(Serverless)专场 Serverless 作为一种新型的互联网架构直接或间接推动了云计算的发展,随着 Serverless 体系不断完善,也让整个前端开发的边界变的更大,未来的前端开发人员的视角会更广阔,不管是当前的全栈,还是边缘计算,AI,3D 等,前端会在不同领域去使用 Node.js 和 Serverless 结合,这将使得整个行业行业带来怎样的变革?我们如何基于自身的业务场景去运用,发挥 Serverless 的最大价值?本专场将邀请一线技术专家分享相关技术实践,给大家带来更多的思考和经验参考。 前端安全生产专场 随着前端领域边界的不断拓展,前端工程师的日常工作内容已经与几年前有着巨大的不同。Serverless、微前端、智能化等新兴技术使得前端的技术闭环越来越完整而又错综复杂,前端交付的也早已不再只是简单的 HTML 页面,前端已经参与到业务的核心逻辑和关键链路。如何提升团队安全意识和保证交付代码质量?如何做到秒级线上监控和故障快速响应?这对前端而言是一个熟悉而又陌生的挑战。安全生产本身也是一个工程问题,所以今年 D2 的前端工程专场将聚焦安全生产,我们将首次对外披露阿里经济体在前端安全生产上的建设成果,相信大家能在这个专场收获不一样的惊喜。 多样化专场 在过去很长时间,前端的核心工作是“快且好的交付一个或多个模块/页面”,并围绕它打造研发工程体系。随着语言标准的完善、硬件的进化,前端的应用场景越来越多样化,开始应用在软件工业的方方面面,如智能化研发、游戏级互动、IoT 设备、工业制造、多媒体应用等。这些不断扩展的多样化场景,滋养、刷新着前端技术生态,让我们每个前端从业者得以机会预判技术机会、并参与建设未来。本届 D2,前端多样化专场将分享和介绍这些领域应用,非常期待能给听众带来一些面向未来的思考。 给大家剧透一下,语言框架专场每年都有重量级海外嘉宾参与,今年也不例外哦,Ben Lesh 已经受邀会来 D2 演讲,这位 RxJS 项目代码的第一贡献人,曾在 Google 的 Angular 团队工作,目前是 RxJS 开源项目的负责人,他将为我们揭秘 RxJS 的核心架构设计及背后的思考。除此之外,组委会还在邀约其他重量级海外嘉宾,让我们先期待一下吧。 D2 是开放的国际化的前端行业盛会,与往年一样,我们同样欢迎来社区的优秀话题报名,在 11月10日 之前提交报名话题,我们将邀请内部专家组织筛选。报名地址:https://survey.taobao.com/apps/zhiliao/hSqqQecfs 或使用手机淘宝、支付宝、优酷等手机 APP 扫码报名。 期待见到你 本届 D2,组委会出了会为大家准备最前沿的技术内容,我们还为大家准备了丰富的技术活动,请大家期待我们后续的“双”彩蛋。(持续关注 Alibaba F2E 微信公众号,获得 D2 的最新讯息) 还等什么!现在就可以购买早鸟票啦,早鸟票有时间窗口哦,如果你对本届 D2 感兴趣,那就赶紧扫描下方海报二维码或访问大会官网(http://d2forum.alibaba-inc.com)购票吧! 晚了可就只剩下晚鸟票咯~ 大家有任何疑问也可以钉钉扫描下方二维码加入答疑群,我们组委会的同学会及时为大家解答。又见 D2,一年一度的前端盛会,我们仍然全心投入,努力为大家带来最优质和前沿的前端技术交流盛宴,新朋友们,老朋友们,又该来 D2 聚一聚啦! ⏰ 12月19日-12月20日 约! (图:第十四届 D2 前端技术论坛部分讲师和组织者) 最后,感谢各位对本次大会的支持,如果你感兴趣,那就赶紧抢票吧,也动动手指分享一下给你身边的同学!也许他也感兴趣!

栏目主编:平侠 The Developer Experience Gap https://redmonk.com/sogrady/2020/10/06/developer-experience-gap/ If there is and can be no Apple-equivalent enterprise vendor arriving to make sure the enterprise telephone app team plays nicely with the enterprise music player team, what progress can be expected? It’s early, and the next few quarters should provide hints at who has accurately identified the depth of the problem and taken steps to address it. In the meantime, here are five adjectives that will describe the next generation of developer experience: Comprehensive, Developer Native, Elegant, Multi-Runtime, Multi-Vendor. Faster Web App Delivery with PRPL https://addyosmani.com/blog/the-prpl-pattern/ PRPL is a pattern for structuring and serving web applications and Progressive Web Apps (PWAs) with an emphasis on improved app delivery and launch performance. The letters describe a set of ordered steps for fast, reliable, efficient loading. Webpack 5 release https://webpack.js.org/blog/2020-10-10-webpack-5-release/ The major version was also the chance to revise some of the defaults and to align with proposals and specifications that come up in the meantime. Relaeted: Webpack 5 Headache, How to Set Up webpack 5 from Scratch. Temporal: Open Source Workflows as Code https://mikhail.io/2020/10/temporal-open-source-workflows-as-code/ Microservices, serverless functions, cloud-native applications—distributed event-driven business applications are hot, and we will deal with them for years. I worry that the application development industry underestimates the complexity of such systems. Ad-hoc solutions to common problems may rapidly increase the technical debt and slow down the ability to innovate. I’m excited to see tools like Temporal enter the space of open-source workflows, or rather the space of asynchronous data processing. Releated: Why the Serverless Revolution Has Stalled, Serverless Horror Stories. Emerging Architectures for Modern Data Infrastructure https://a16z.com/2020/10/15/the-emerging-architectures-for-modern-data-infrastructure/ And yet, despite all of this energy and momentum, we’ve found that there is still a tremendous amount of confusion around what technologies are on the leading end of this trend and how they are used in practice. In the last two years, we talked to hundreds of founders, corporate data leaders, and other experts – including interviewing 20+ practitioners on their current data stacks – in an attempt to codify emerging best practices and draw up a common vocabulary around data infrastructure. This post will begin to share the results of that work and showcase technologists pushing the industry forward. 栏目主编:侑夕、紫益 一周精读《设计模式 - Factory Method 工厂方法》 https://github.com/dt-fe/weekly/169.精读《设计模式 - Factory Method 工厂方法》.md 通过三个生动的例子与 JS 示例代码,帮助前端的你理解设计模式,让我们一起积累不过时的知识! Factory Method(工厂方法)属于创建型模式,利用工厂方法创建对象实例而不是直接用 New 关键字实例化。意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。 ECMAScript 2020 新增特性 https://juejin.im/post/6883306672064987149 ECMAScript 2020 是 ECMAScript 语言规范的第 11 版,新增的这 9 个新特性值得一学。 Serverless 未来十年发展解读 https://juejin.im/post/6883773727733972999 本文整理自 Johann Schleier-Smith 在 ServerlessDays China 的演讲,主要分为四个部分:首先阐述 UC Berkeley 怎样来定义 Serverless ,之后会分享一些近期的研究成果和进展,最后提出对云计算未来的一些预测和设想。 浏览器是如何工作的 https://king-hcj.github.io/2020/10/05/google-v8/ 一篇文章方方面面的介绍到了 Chrome V8,让你更懂 JavaScript,很是详细。 超全的 Linux Shell 文本处理工具集锦 https://segmentfault.com/a/1190000037480939 每周学一点新知识,用过 Shell 处理一些文本才知道原来这么简单方便,此文将一些处理文本常见的工具都介绍了一个遍,可先了解到用的时候再查。 一文了解文件上传全过程 https://segmentfault.com/a/1190000037411957 一篇很详细的介绍文件上传流程的好文,从前置知识、请求端、服务端、接收端一层一层来带着入学的感觉。 栏目主编:侑夕 Zipson - Json 压缩工具 https://github.com/jgranstrom/zipson Zipson 是一个让原本JSON.parse/stringify增加了压缩和流媒体支持的临时替代方案,感觉前后端传输中,接口先压缩吐出数据,前端通过解压获取 Json,可让传输数据变小 50%。 Bubble Tea:一个强大轻量的 TUI 框架 https://github.com/charmbracelet/bubbletea Bubble Tea 一个基于 Elm 架构的 Go 框架,借此可用有趣、函数式、带状态的方式去编写命令行 APP,效果很不错,虽然是 GO 语言,不过可触类旁通研究一波。 BlurHash: 图片懒加载舒服的占位符 https://github.com/woltapp/blurhash 之前我们一般使用纯灰色亦或是骨架占位符的方式来缓存暂未出来的图片,虽然看起来没问题但是不讨设计喜欢,BlurHash 这个模糊彩色的占位符值得试试。 Drogon:一个基于 C++14/17 的 Http 应用框架 https://github.com/an-tao/drogon Drogon 是一个基于 C14/17 的 Http 应用框架,通可以方便的使用 C构建各种类型的 Web 应用服务端程序,写习惯 Node 的同学看看这个会让你惊讶的。 detect-gpu:一个 GPU 的检测库 https://github.com/TimvanScherpenzeel/detect-gpu 根据 GPU 的 3D 渲染基准分数对 GPU 进行分类,开发人员可借此结果为图形密集型应用程序提供合理的默认设置。 Plausible Analytics:Google Analytics 替代品 https://github.com/plausible/analytics Plausible Analytics 是一个简单、轻量且隐私友好的 Google Analytics 替代品,不使用 cookie,自托管或者云上部署都可以。 Awesome YouTubers https://github.com/JoseDeFreitas/awesome-youtubers 以上这个 Awesome YouTubers 将技术领域值得关注的 YouTuber 给挑选出来了,适合那种看视频学习的同学来有选择关注~ 栏目主编:大漠 [mediaqueries-5] Updating the CSS media feature syntax for foldable & dual-screen devices #5621 https://github.com/w3c/csswg-drafts/issues/5621 @zouhir 和他的同事@dlibby是最早提出了跨媒体特性,主要用来解决微软双屏幕设备,然后拓展到可折叠屏幕,甚至是可以通过创建更多枚举值来表示新硬件的屏幕拓扑。这是目前解决双屏幕和可折叠屏幕的技术方案之一。现在该特性已提交W3C规范中 Media Queries Level 5进行讨论。 The --var: ; hack to toggle multiple values with one custom property https://lea.verou.me/2020/10/the-var-space-hack-to-toggle-multiple-values-with-one-custom-property 你肯定知道使用JavaScript来动态更新或者应用CSS的属性值,但你肯定不知道如何在CSS中采用自定义属性的特性来决定属性运用哪一个值。时至今日的CSS自定义属性也可以做到JavaScript中真( true )和假( false )的切换。 Logical layout enhancements with flow-relative shorthands https://web.dev/logical-property-shorthands/ 很多开发者都习惯于物理属性,但在Web的布局当中物理属性将会带来很多令人感到困惑,甚至是麻烦。特别是有着国际业务需求的同学,那么CSS逻辑属性的到来,将会改变这一切,再也不会让你为不同语言排版,布局感到头痛。而且CSS逻辑属性真的要到来了,甚至说已经到来了。 Dynamic Element Scaling in CSS https://levelup.gitconnected.com/dynamic-element-scaling-in-css-7e35ed9a3914 使用CSS给HTML元素做动态缩放,比如 width 、 height 或者 font-size ,可能会想到的是使用CSS媒体查询特性,在不同的屏幕下使用不同的值。但这将会增加代码的冗余度,也会让你的代码变得越来越难维护。在这篇文章中,作者通过CSS的 calc() 函数,向大家展示了如何动态修改元素大小。 一个Div的能做什么:Demo1 https://codepen.io/jshwrnr/full/ZEOGroR 这是一个 div 构建的纹理背景效果。 栏目主编:彼洋 TC39 9月会议提案进度报告 https://www.yuque.com/alibabaf2e/vab8a9/czwuqv 本次会议上,我们主持了 Error Cause 提案进入了 Stage 1,作为阿里巴巴集团内 JavaScript 错误处理模式的一个总结,将这个行为写入标准,便于更多的开发者工具如 Alinode、阿里云 ARMS 等改进异常分析的体验。 Chrome 86 重要更新 https://www.yuque.com/alibabaf2e/gt3np7/ullslm Chrome 86 在2020年10月推出了稳定版,现已全面应用于Android、Chrome OS、Linux、macOS 和 Windows等平台,我们一起来看下这次的重要更新。 栏目主编:十吾 为什么智能手机会导致颈部综合症可视化 https://multimedia.scmp.com/lifestyle/article/2183329/text-neck/index.html 现在,全球手机用户数量超过了 50 亿,这个世界上三分之二的人口都拥有手机。我们大多数人每天至少要弯腰 2 个小时,这将让我们的颈部承受的重量增加多达 27 千克。如果在走路时使用手机发消息,则可能会带来各种意外事故。该可视化作品通过交互的形式,展示了颈部是如何承受压力的。 名作失窃可视化 https://www.informationisbeautifulawards.com/showcase/3266-you-could-fill-a-museum 联邦调查局的数据库全球数据库包含7,200多种失窃的名作,包括斯特拉迪瓦里小提琴、卡尔德手机、蒂法尼灯、小丑画等。 对 tensorflow 中数据流图的可视分析 http://vis.pku.edu.cn/blog/%e5%af%b9tensorflow%e4%b8%ad%e6%95%b0%e6%8d%ae%e6%b5%81%e5%9b%be%e7%9a%84%e5%8f%af%e8%a7%86%e5%88%86%e6%9e%90%ef%bc%88visualizing-dataflow-graphs-of-deep-learning-models-in-tensorflow%ef%bc%89/ Tensorflow 是谷歌开发的当下最流行的机器学习软件之一。它采用数据流图(Dataflow Graph)来表达机器学习算法的计算过程,用户可以定制不同的数据流图来构建自己的算法。然而,随着深度学习的兴起与流行,各类神经网络渐趋大规模、复杂化,算法开发者仅凭借自身的理解与记忆,很难把握算法的各部分体系结构,相互之间也难以进行沟通。为此,这篇文章提出了可视化工具 TensorFlow Graph Visualizer,通过可视分析帮助用户在 TensorFlow 中进行算法分析与开发。该文章荣获了 IEEE VAST 2017 的最佳论文奖。 查看更多墨者修齐:https://www.yuque.com/mo-college/weekly/syvbtp 栏目主编:平侠、侑夕 Thoughts writing a Google App script https://martinfowler.com/articles/202009-google-app-dir.html Recently a friend of mine asked for a simple program that would correlate some data drawn from a couple of online services. I decided the best way to do this for him would be to use a google spreadsheet as the host, putting the code into the spreadsheet's script area. I'm no expert in Google App Script, but the exercise led to a few observations, which I feel compelled to share. How AI is powering a more helpful Google https://blog.google/products/search/search-on/ When I first came across the web as a computer scientist in the mid-90s, I was struck by the sheer volume of information online, in contrast with how hard it was to find what you were looking for. With recent advancements in AI, we’re making bigger leaps forward in improvements to Google than we’ve seen over the last decade, so it’s even easier for you to find just what you’re looking for. Today during our Search On livestream, we shared how we're bringing the most advanced AI into our products to further our mission to organize the world’s information and make it universally accessible and useful. Help kids Be Internet Awesome https://beinternetawesome.withgoogle.com/en_us/interland To make the most of the Internet, kids need to be prepared to make smart decisions. Be Internet Awesome teaches kids the fundamentals of digital citizenship and safety so they can explore the online world with confidence. 编码技巧(五):适当可扩展 https://zhuanlan.zhihu.com/p/266076082 本文介绍了一个新的编码技巧:“适当可扩展”,什么样的代码才能成为 “适当” 的呢?文中详细的进行了解释。值得一提,代码的各种优秀特征,都是需要花费精力来写出来的,也就说需要成本,我们才能有收益。所以,提供 “可扩展性”,必然得是满足了相关的需求,不能是开发者一厢情愿而为之。当然为了追求技术精进,高度可扩展的案例,也是非常值得学习的。这并不冲突。我们可以身怀绝技,但用的时候却只 “恰到好处”。这才是行家的手笔呀。 企业文化建设需要适度“用力过猛” https://mp.weixin.qq.com/s/fTqMP7vbunhWyDOleyYgvw 企业文化建设,是一个有破有立的过程,破在固有的思想观念和行为模式,立在新的思想观念和行为标准。按照惯性定律,没有外力作用时,事物总是处于匀速运动或静止状态,因此成功的企业文化建设,多少会给人一种“用力过猛”的感觉,否则不足以打破当下的惯性;即便是自我心灵觉醒,同样也需要外力。海尔砸冰箱,就是一种适度“用力过猛”的外力,张瑞敏砸的不是冰箱,砸的是当时干部员工队伍中落后的思想观念,不光在企业内部,甚至在整个企业界唤醒了人们沉睡的质量意识。适度“用力过猛”,为的是让人从习以为常的稳态中惊醒,迈向需要做功的激活态(非稳态)。 当百度to B https://mp.weixin.qq.com/s/xS5ACCrgh0C5w_rUL2gwJg 当云计算进入以各行业传统企业和政府部门为主力客户的“下半场”,一个行业共识是,计算与存储的基本能力之外,云与AI的结合将成为接下来的关键竞争点——云计算负责新型IT基础架构,AI负责具体业务问题。而在云和AI两个领域,尤其是二者的结合上,百度都是重要的玩家。 iOS 后台锁屏监听摇一摇 https://juejin.im/post/6881420727371694093 不会吧这也行系列,一般情况下出于省电、权限、合理性等因素考虑一些奇怪的需求 iOS 不是很好实现,如当 APP 处于后台或锁屏状态时,依旧可以监听到摇一摇,看看这里是怎么做的。 Flutter 1.22 正式发布 https://juejin.im/post/6879048672597213198 来看一看 Flutter 1.22 趁着 iOS 14/Android 11 发布季,都更新了一些什么样的功能? 1 分钟将 vscode 撸成小霸王 https://juejin.im/post/6882576431503638536 这个是真的“浪”,借助JSNES模拟器弄了一个 VSCode 的小霸王游戏机,VScode 插件搜索「小霸王」即可使用,这个想法很是不错~ 哪些工具使你成为一个更好的程序员? https://news.ycombinator.com/item?id=23468193 Hacker News 上面比较热烈的一个讨论,看看国外的程序员怎么说? 很炫酷的 3D 可视化的星空 http://stars.chromeexperiments.com/ 一个可交互式的三维可视化恒星邻居,包括超过 10 万颗附近的恒星,点击 URL 进入很是不错。 Blush:插图定制生成工具 https://blush.design/zh-CN 这个工具不错的是可以自定义插图的每一部分来创建自己的构图,同时种类也很多,对于前端同学写一些图文搭配 PPT 蛮适合。 2020 中国奢侈品消费者数字行为洞察报告 https://mp.weixin.qq.com/s/fsBblPTiTjYXg1vUKzK_Jw 从此文来了解下后疫情时代中国奢侈品消费市场呈现的趋势、消费链路以及品牌打法,还可结合“名媛拼团”侧面来剖析下。 查看更多:https://www.yuque.com/awesome/fe_weekly/20201019 关注「Alibaba F2E」把握阿里巴巴前端新动向

独家下载!Java工程师成神必备宝典

复制该链接到浏览器完成下载或分享:https://developer.aliyun.com/topic/download?id=923 初学Java的你还在烦恼不知道怎么去学,学习什么内容吗?那么多的技术书籍是否已经让你无从下手?别急,这就附上一份完整的Java学习路径。从头开始,给你一个体系化的学习方案。结合作者多年开发经验,倾心五年沉淀,旨在与众多Javaer相互交流,共同进步。 《Java工程师成神之路(基础篇)》介绍了普通Java工程师必须要学习的相关知识点,包括面向对象和Java语言基础两大部分,涵盖基本数据类型、关键字、异常、I/O流、集合、反射、泛型和枚举......另外,内附成神导图哦~ >>阿里云产品爆款活动火热进行中 HOT<< 云服务器ECS资源免费得,实时计算Flink净省3258元!点击链接>>:https://developer.aliyun.com/plan/promotion/1?utm_content=g_1000198928 免费下载《Java工程师成神之路(基础篇)》 关于作者:Hollis ,阿里巴巴技术专家,51CTO 专栏作家,CSDN 博客专家,掘金优秀作者,《程序员的三门课》联合作者,《Java 工程师成神之路》系列文章作者;热衷于分享计算机编程相关技术,博文全网阅读量数千万。 Java如何实现的平台无关性的 相信对于很多Java开发来说,在刚刚接触Java语言的时候,就听说过Java是一门跨平台的语言,Java是平台无关性的,这也是Java语言可以迅速崛起并风光无限的一个重要原因。那么,到底什么是平台无关性?Java又是如何实现平台无关性的呢?本文就来简单介绍一下。 什么是平台无关性 平台无关性就是一种语言在计算机上的运行不受平台的约束,一次编译,到处执行(Write Once ,Run Anywhere)。 也就是说,用Java创建的可执行二进制程序,能够不加改变的运行于多个平台。 平台无关性好处 作为一门平台无关性语言,无论是在自身发展,还是对开发者的友好度上都是很突出的。 因为其平台无关性,所以Java程序可以运行在各种各样的设备上,尤其是一些嵌入式设备,如打印机、扫描仪、传真机等。随着5G时代的来临,也会有更多的终端接入网络,相信平台无关性的Java也能做出一些贡献。 对于Java开发者来说,Java减少了开发和部署到多个平台的成本和时间。真正的做到一次编译,到处运行。 平台无关性的实现 对于Java的平台无关性的支持,就像对安全性和网络移动性的支持一样,是分布在整个Java体系结构中的。其中扮演者重要的角色的有Java语言规范、Class文件、Java虚拟机(JVM)等。 编译原理基础 讲到Java语言规范、Class文件、Java虚拟机就不得不提Java到底是是如何运行起来的。 我们在Java代码的编译与反编译那些事儿中介绍过,在计算机世界中,计算机只认识0和1,所以,真正被计算机执行的其实是由0和1组成的二进制文件。 但是,我们日常开发使用的C、C++、Java、Python等都属于高级语言,而非二进制语言。所以,想要让计算机认识我们写出来的Java代码,那就需要把他"翻译"成由0和1组成的二进制文件。这个过程就叫做编译。负责这一过程的处理的工具叫做编译器...... 更多内容点击下载电子书 藏经阁系列电子书 阿里云开发者社区——藏经阁系列电子书,汇聚了一线大厂的技术沉淀精华,爆款不断。点击链接获取海量免费电子书:https://developer.aliyun.com/ebook

居家隔离+一起学习!21天打卡养成习惯,坚持就拿“大礼包”!

2020年1月29日,今日学习《3大阶段,30+教程,超全年度 Python 礼包大放送 | 开发者社区年终礼包》0 基础入门 学习准备(上):计算机是什么