阅读 10530

可视化搭建页面,你会遇到这 143 个问题么

前端早早聊大会目标成为用得上、听得懂、抄得走的技术大会,计划 2020 年办 >= 15 期,由前端早早聊与掘金联合举办,前端早早聊大会行程动态、录播视频/PPT/讲稿资料下载请关注 「前端早早聊」 公众号跟进。

你的支持,是早早聊办下去的唯一动力!

还想听哪方面的分享,直接加 Scott 微信: codingdreamer 提需求吧!


第十二届|前端可视化专场,7-18 即将直播,10 位讲师(蚂蚁金服/阿里云等),报名地址


本篇为第三届 - 前端页面搭建专场讲师们的答疑,相关讲稿如下(视频关注公众号获取):

一、如何设计实现 PC 站点搭建系统 - Schema --- 洛尘

1. 已回答问题

Q: 请教洛尘:多个组件之间如何进行业务逻辑关联?

A: 由于我司搭建系统是采用行布局,所以组件之间的业务逻辑相对来说会比较少,比较常见的组件关系是,登录状态的共享,权限控制等,目前是通过 Vuex 进行数据共享解决的。


Q: 请教洛尘:页面和后台怎么进行个各种业务的接口调用?

A: 我司搭建系统还是通过组件直接请求业务接口的,当然,入参是可以进行配置的,业务逻辑也是直接在组件中写好的,毕竟我们搭建的粒度是业务组件。


Q: 请教洛尘:对于营销类的页面或者业务组件,是如何做横向布局的呢?

A:  嗯 banner已经抽离成组建了。现在有个问题是banner的每一帧在不同时间段展示不同的图,对到运营来说,他们有需求要提前配置时间点段,然后到点显示。这里的配置可能涉及不同的排期,以及不同部门的权重也不一样。最近思考这里如何实现更方便的配置和排期分配


Q: 请教洛尘: 发布生成的页面是一组配置数据还是实际生成了html文件?

A: 是html文件,那这里我说一下发布的具体过程:1、从数据库查找到该页面的用到的所有组件和 JSON Schema数据,2、获取 Vue SSR 生成的vue-ssr-server-bundle.json、vue-ssr-client-manifest.json、index.html文件(这部分可以参考 Vue-SSR 官方文档)其实这就是render函数所属要的文件,我们它为渲染模板。3、将数据和渲染模板通过 render 函数(函数的思路在Vue-SSR中也有)得到 Html,用 IO 写成文件。


Q: 请教洛尘:搭建工具中,业务组件如何维护的,所有的组件都装到本地吗,新增一个组件就需要install一下吗?

A: 搭建系统和组件是解耦的,组件是通过node注入到搭建系统中,并不会因为组件的新增、迭代影响搭建系统。


2. 未回答问题

2.1 schema 设计相关

Q: 请教洛尘: json schema 和ts 的interface是不是一样的功能?

A:JSON Schema 和 ts Interface 要是从性质上来讲,都是一种规范的定义,但是JSON Schema更加注重你对于业务场景和可视化形式的规范定义,而 interface 其实是入参规范的定义。


Q: 请教洛尘:JSON SCHEMA 到 页面的一个完整流程,是如何的?

A:组件在开发时不需要关心Schema这一部分,等待组件开发完成以后,会根据运营的需求和已有Schema的规范手动配置一份Schema数据,放在组件中,Schema 会在搭建平台中被解析渲染成为数据可视化窗口,所以Schema 和 组件(并不是你说的页面)并没有必然联系,


Q: 请教洛尘:json Schema 和现在百度开源出来的amis框架是否类似?

A: JSON Schema 只是 amis 框架的一部分,是渲染时要用的一份规范化的 JSON 数据,和 amis 框架还相差甚远。


Q: 请教洛尘:鲁班在搭建过程中,Json Schema 有状态更新时如何更新UI?

A:JSON Schema 是搭建系统和组件之间的一份规范约定,它用于数据可视化配置窗口的渲染,所以,要更新JSON Schema 其实本质就是更新组件。


Q: 请教洛尘:json-schema 定义里,如何涵盖组件之间的数据联动关系怎么处理?

A:

请看上图,这就是一个二级联动:广告位banner-图片配置,可以看到图中”广告位名称“这一部分数据其实就是来源于"广告位banner"这个tab,当它的下拉框值变化时,图中的表格数据也会跟着联动,而这一部分功能就是JSON Schema 通过增加辅助字段完成的,比方说,你已经定义好了一个二维数组的 Schema,只要再 Schema 的第一层数组的定义里再加一个key值,让你能够知道第二层数组是根据这个key联动的,那就成了。


Q: 请教洛尘:json-schema 里你如何去设计处理组件之间的联动关系 (禁用关系 或 显示隐藏关系)?

A:JSON Schema 是搭建系统和组件之间的一份规范约定,它用于数据可视化配置窗口的渲染,它和组件有关,但是组件之间的 JSON Schema 并没有关系。


Q: 请教洛尘:接口设计和 schema 设计是完全匹配的吗?还是schema做通用设计,兼容多种类型的接口数据?

A:今天说到的内容只涉及静态数据配置方面的JSON Schema 通用涉及,还未涉及接口层的Schema定义。


Q: 请教洛尘:这么多不同组件的schema格式,在迭代过程中,是如何进行维护,来保证页面和规范之间是同步更新不遗漏的?

A:Schema的格式是预设好的,定义无效的Schema 是没有办法被解析的,定义多余的Schmea也不会被组件所采用,迭代过程中,组件(而不是页面)和 Schmea 并不是强耦合的,Schema 的迭代取决于运营对于数据配置的需要,而组件迭代取决于产品对于组件功能或者展示的需要。


Q: 请教洛尘: PC页面的布局比较复杂、不一定都是上下楼层罗列下来就行、例如左边是导航栏,右边是其他内容、有可能右侧的内容比导航长、这种鲁班里是怎么处理的?

A:为减少鲁班使用成本,目前只支持行布局,即一个组件占据一整行,而这一整行可能是包括多个业务组件的,组件能被划分成为怎么样的粒度,是由视觉规范决定的,因此和视觉之间的协作也是很重要的。


2.2 组件模块设计相关

Q: 请教洛尘:如何依赖三方包,扩展相关组件功能?

A:这就涉及到创建组件的脚手架,首先,你的脚手架里面具备了组件开发时一些必要的第三方包,但是这些第三方包不能被打包进 lib 中,即保证了组件在本地开发时可以正常进行,有减少了去除了公共的引入,然后在鲁班的渲染模板中统一引入第三方包,如果有用到 Vue 插件的,记得将 Vue 通过全局引入(即 cdn引入后再在webpack 中配置 external)。


Q: 请教洛尘:搭建系统站点中,对那些的布局不规则活动页面怎么处理的?

A:目前我司的搭建系统,在不规则活动页的场景上的处理还比较少,但是这边有几个建议可以提供参考:1、将不规则活动页归类为模板,统一进行管理,方便二次使用;2、在搭建系统中,增加标记功能,视觉给的图只是作为背景,通过标记背景图的绝对位置来配置功能(点击事件、链接等等)


Q: 请教洛尘:搭建系统中扩展了一个新组件之后,搭建系统中接入使用的过程?

A:1、新组件打包,打tag后上传git库,2、搭建系统通过git groupId 拉取该组下所有组件信息,和数据库中组件数据作对比,筛选出新增组件,拉取其组件源码到本地服务器并上传oss做备份,更新组件数据到数据库。


Q: 请教洛尘:代码检测这里,对组件的代码检测,有哪些关键的指标可以提一下吗?

A: 目前组件的检测包含几个方面,1. 规范检查,通过 lint 工具进行源代码的规范性检测;2. 资源检查,例如对一些不在域名白名单内的资源或者不可用的资源进行检测;3. 安全检查,比如根据黑名单配置针对 npm 依赖包进行检查。当然,你也可以根据业务特定灵活的决定检测的内容


Q: 请教洛尘:多团队维护组件,是同个组件池吗,还是有隔离,组件相似性高,冗余怎么办?

A:目前我司搭建系统组件在git的同一个group下,组件的冗余是避免不了的,搭建系统本身不能保证每个组件都能够被复用,也无法保证组件不产生冗余,它存在的意义更多的是提效,从某种程度上来说,将原本组件的大量冗余,通过一种规范和系统的方式,将冗余减少到了可以接受的范围,并且我们对于原本分散在各个业务中的组件模块进行的规整,并在此基础上,才有可能赋予搭建系统更多的能力,和更多系统进行横向打通:数据配置化、主题配置、代码检测、性能检测等等。


Q: 请教洛尘:搭建系统中的最小单元也就是组件如何进行扩展?包括如何外部引用?还是内部通过系统进行引用?

A:搭建系统和组件是解耦的,首先,组件源码是在本地服务器上的某个文件夹(并不在搭建系统项目目录下),然后组件是通过node将组件源码直接注入到搭建系统中,注入是按需的,也就是默认情况下,我搭建系统中只存在组件信息(组件名,版本号、预览图等等),仅仅用于组件列表的展示,当你通过拖拽或者点击的方式去使用这个组件到页面时,是通过node的一个接口,去获取这个组件的源码,然后用script标签注入。这样,我不管你组件增加、减少还是迭代,对于我搭建系统本身并没有影响。


Q: 请教洛尘:页面里的数据,比如banner里的图,不同时间展示不同的图,不同用户展示不同的图,这个也是走配置实现吗?是否引入了一个类似排期的系统?

A:其实数据配置能力本不属于搭建系统,只不过为了满足业务方要求,做了一个简化版的数据能力,如果按照正规的做法,确实应该引入一个其他系统专门用来做数据这一层,它可以通过不同维度和规则从中台这个数据池中去捞数据,提供给搭建系统。


2.3 业务数据交互相关

Q: 请教洛尘:页面内组件如何通信?

A:在页面级别上给组件提供 Vuex 能力,组件通过封装的 Api 进行数据操作和获取


Q: 请教洛尘:组件嵌套调用和通信怎么处理?

A:我们暂时只有行组件,如果行组件内有嵌套,由组件自己实现。


Q: 请教洛尘:活动页面中的数据交互怎么处理?

A:组件直接发起异步请求进行数据获取


Q: 请教洛尘:配置组件与组件之间的交互怎么处理?

A:在页面级别上给组件提供 Vuex 能力,组件通过封装的 Api 进行数据操作和获取


Q: 请教洛尘:组件嵌套调用和请求聚合的处理思路?

A:暂时由行组件自行调用,聚合处理是下一步目标,可以先参考下同期京东的方案


Q: 请教洛尘:页面和后台怎么进行个各种业务的接口调用?

A:组件直接发起异步请求进行数据获取


Q: 请教洛尘:页面的业务数据怎么获取数据,接口还是其他?

A:组件直接发起异步请求进行数据获取


Q: 请教洛尘:页面UI是生成后, 各个模块之间如何进行关联交互?

A:在页面级别上给组件提供 Vuex 能力,组件通过封装的 Api 进行数据操作和获取


Q: 请教洛尘:异步数据如何进行绑定,组件如何及时同步更新之后的异步数据?

A:在页面级别上给组件提供 Vuex 能力,组件通过封装的 Api 进行数据操作和获取


Q: 请教洛尘:页面搭建完毕之后其中的业务逻辑如何埋入?二次开发么?还是有对应的方式去解决?

A:暂时业务逻辑都是由行组件自行处理,页面层面只提供部分通用的功能,比如三方脚本注入,主题配色等


2.4 搭建技术实现相关

Q: 请教洛尘:这种配置化的表单如何实现差异化的表单校验?

A:不建议直接配置差异化,会增加数据配置和组件数据处理的复杂度,结合投放系统更合适。如果要做,可以处理成二维数组的方式。


Q: 请教洛尘:你们的搭建模块不是按行来拆分的,怎么做css样式的兼容?

A:暂时都是行拆分的,css 样式兼容,会限制组件的样式都是有 prefix,并且唯一不重复的,所有不影响全局,使用 scoped 也可以达到同样的效果。


Q: 请教洛尘:组件编辑器,是怎么实现的,有支持模块拖拽移动吗,用到什么基础库?

A:组件没有单独的编辑器,可以理解成是一个独立的 Vue 项目,提供普通 IDE 就好,只是提供了 Schema 相关的校验工具。如果是说搭建过程中的模块移动,使用的是 vuedraggable。


Q: 请教洛尘:现在组件量有多大?生产环境组件都在一个node module吗?这里怎么做容灾的?

A:现有组件 230+,搭建过程时,添加组件时会动态注入组件,如果是发布页面之后的生产环境会根据页面实际使用的组件,由于没有 Cdn Combo 功能,所以是重新进行代码合并,只会包含实际使用的部分。


Q: 请教洛尘:鲁班系统搭建过程中,对那些需要特殊外部扩展模块,自定义的站点是怎么提供支持的?

A: 页面级别,可以进行三方依赖配置,配置之后,在渲染时会自动插入对应位置


2.5 搭建系统产出结果相关

Q: 请教洛尘:这套系统产出的页面,直接是SSR之后的结果吗?

A:暂时鲁班搭建还未接入 SSR,数据方面还是组件自己获取后渲染页面


Q: 请教洛尘:活动页是增量发布还是全量发布,是多页面的吗?

A:每个活动页面都是单独页面,页面的每次发布都是整体组件全量发布


Q: 请教洛尘:这套系统产出的页面,用户访问时,用的是SSR么?

A:还没有接入 SSR 的发布,系统产出的是静态Html文件,用户访问的也就是Html文件


Q: 请教洛尘:上线的是页面是解析器渲染schema,还是产出实际代码?

A:上线的页面是静态的Html。


Q: 请教洛尘:搭建系统只输出数据吗,各端的UI是单独实现的吗,比如PC,H5,小程序等?

A:搭建系统是提供了一个平台,每个组件都可以由业务方前端开发者自己开发,搭建系统将各个符合规范的组件引入后,实现搭建页面的功能,目前我司鲁班仅提供 PC,H5 类型的页面搭建,由于PC、H5在本质上一样的,所以可以公用一份解析器,如果涉及到小程序、RN等就需要提供新的解析器。


二、如何设计实现低代码页面搭建系统 - Paas 服务 --- 月飞

1. 已回答问题

Q: 请教月飞: iceluna 和iceworks有什么区别?

A: iceluna定位为低代码搭建产品,面向全体研发同学,以拖拉拽+可视化配置为主,其研发链路云端化,开箱即用,研发人员无需关注前端工程化问题; iceworks定位源码研发的GUI工具,主要面向专业前端同学,通过可视化配置方式完成前端工程初始化、物料选择、页面创建等,页面内容标准源代码开发。


Q: 请教月飞: 插件系统怎么实现?

A: 总体来说,iceluna的插件系统,从以下3个方面实现:

  1. 插件与编辑器解耦:提供插件开发脚手架和命令行工具,插件初始化创建时继承骨架内置的BasicAddon基类,在基类内部实现插件在骨架上的展现类型、交互形式、展现位置等,从而实现插件与骨架的解耦
  2. 插件生命周期:提供插件运行全生命周期,用于给插件做功能定制。如插件注册,取消注册,初始化启动自动保存等等功能;
  3. 插件获取编辑器统一上下文this对象:插件通过基类,可以获取编辑器骨架的统一上下文,通过上下文提供的api来与编辑器进行消息通信;

Q: 请教月飞: 沙箱隔离不同类型组件,加载或者渲染时性能是怎么优化的呢?

A: 分享时讲解的沙箱隔离,是指编辑器本身与画布内正在开发的应用的隔离。因为是iframe隔离的,所以编辑器和画布的资源是分别加载的。目前iceluna均采用提前云端构建的方式进行资源bundle的打包,而非异步动态加载,所以不会出现重复加载资源;对于中后台系统的搭建来说,资源和第三方的依赖不会频繁发生变动,资源在浏览器测也有缓存,总体不太会存在加载性能问题。对于渲染性能,在组件接入时会描述该组件是否支持局部刷新。如果支持,会给组件渲染时包裹一层高级组件,在组件属性发生变化时,会出发包裹的高级组件来进行组件范围级别的局部刷新,从而优化渲染性能;


2. 未回答问题

2.1 组件模块设计相关

Q: 请教月飞: 搭建编辑器的插件机制?

A: 总体来说,iceluna的插件系统,从以下3个方面实现:

  1. 插件与编辑器解耦:提供插件开发脚手架和命令行工具,插件初始化创建时继承骨架内置的BasicAddon基类,在基类内部实现插件在骨架上的展现类型、交互形式、展现位置等,从而实现插件与骨架的解耦
  2. 插件生命周期:提供插件运行全生命周期,用于给插件做功能定制。如插件注册,取消注册,初始化启动自动保存等等功能;
  3. 插件获取编辑器统一上下文this对象:插件通过基类,可以获取编辑器骨架的统一上下文,通过上下文提供的api来与编辑器进行消息通信;

Q: 请教月飞: 在 schema 之前我看到有一层 DSL 层,此处是何种思考呢? 有何用意?(对互转模块那块)?

A: 搭建的schema是一个约束性描述,其描述的功能相对于标准React源码的一种最佳实践。因此Schema在出码阶段,可以转成React源码的一种最佳实践,然后线上运行,单向这是可行的。 如果要实现互转模块,那么必须在功能实现和语言约束上是1:1实现的,任意一方功能强大都不能实现互转。React语言过于灵活,没有任何限制,通过AST分析,需要描述的内容schema不能涵盖全,因此React标准源码无法转成schema。 所以:为了实现互转,必须将React源码,在工程目录、视图模版、交互通信等进行约束,形成一套全新DSL来实现与搭建schema的功能1:1对等,最终达到互转的目的。


Q: 请教月飞: 组件的npm包安装到node module,那这node module不就越来越大了吗,这里怎么处理增量问题的?

A: 每一个应用都有自己的依赖,应用的bundle是云端动态构建的,而非中心化的一个node module,所以应用依赖了的npm包,才会打包进来,跟源码webpack打包机制是一样的。去中心化就自然解决了node module无限增大的问题。


Q: 请教月飞: 组件npm包依赖其他npm包的话,安装到环境不会影响node module内已有的依赖吗?这里怎么处理的?

A: 云端构建是webpack依赖分析的机制,跟本地npm build的机制一致,版本相同只会打包1个进去。


Q: 请教月飞: 构建服务是把文件拉下来然后构建吗?有没有实现内存构建的方法,组件的开发是不是也可以提供网页编辑器直接在线上coding?

A: 目前iceluna的构建服务已经迁移到了阿里集团的DEF构建服务,iceluna自身的构建是在服务器上从git拉文件下来进行构建,没有实现内存构建。 组件开发已经提供网页编辑器进行低代码搭建,目前未提供纯源码coding的方式进行线上coding。


Q: 请教月飞: 同个页面中的不同版本组件是如何解决和使用的? 比如同个页面中可能会有React 15的组件,有些可能是新写的16的组件。这个要怎么做才能做到更优化的集成到页面中?

A: 同一个页面最佳实践只能支持同一个React版本的组件,iceluna也不支持2个React版本的组件混用哈。


Q: 请教月飞:组件是以npm包为粒度进行拆分的。开发一个新的模块的时候,搭建系统如何支持新的组件?通过npm包重新安装的方式么?还是线上资源动态化拼接的方式?另外一个问题是,关于各个npm组件的公共代码是如何抽离的?

A: iceluna上支持npm包导入和低代码搭建2种组件接入的方式,配置好npm信息后,会通过云端构建在服务端重新npm build出包含新组件的bundle资源包。npm组件的公共依赖,是webpack依赖分析的,同一个依赖的同一个版本只会打包1个进去。


2.2 业务数据交互相关

Q: 请教月飞: schema实现了可视化的定义,关联、联动是如何实现呢?

A: 搭建协议配套有一个渲染SDK,提供了搭建协议的标准API,可以通过API来实现 应用级别/页面级别/区块级别的数据更新,数据获取。比如:this.state获取数据,通过this.setState()来更新数据。关联和联动机制与标准源码实现思路一致。


Q: 请教月飞: 组件的事件触发和组件之间的业务数据是怎么触发和流通的?

A: schema中支持描述组件的事件属性,可以写事件代码。 schema中实现了区块容器,一个区块容器对应一个React Class内,这个容器组件可以配置异步数据源,发起异步请求,对异步数据进行处理,最终数据返回到容器的state内。这个容器组件内的子组件通过context机制继承容器组件的this对象,可以共享同一个数据对象state。


Q: 请教月飞: 中后台系统中no-code中联动怎么处理呢,有比较好的方案吗?

A: 常规联动包含显示、隐藏、赋值等常规操作,可以参考阿里对外开源的Formily的实现。


Q: 请教月飞: 中后台系统中有很多业务逻辑,这里是怎么做好关联的呢,还是需要自己书写业务代码,比如一个搜索框,涉及到validate、防抖、接口请求、下拉等等?

A: 部分功能流程比较固定的组件,一般会封装成通用性功能组件来提供使用。对于业务逻辑复杂,不太好抽象成组件的场景,是需要基于原子组件来书写代码的方式来实现的。


2.3 跨端跨栈支持相关

Q: 请教月飞: 怎么面向小程序等其他移动端技术栈的?

A: 讲稿中提到的多端适配,只要是只编辑器的多端适配,可以实现产出物可以是移动端技术栈的编辑器。一是搭建协议需满足多端的诉求,在出码时每一个属性与目标技术栈有对应的映射关系;二是画布内的渲染引擎能渲染对应技术栈的组件物料,具体是针对不同技术栈实现不同的渲染引擎。


Q: 请教月飞:既然物料都是纯 js, 那是通过什么方式引入 React、Vue等组件呢?

A: 文稿中讲的纯js,是指在低代码编辑器中,配置组件事件、数据处理等内容时是纯js书写。而UI视图彻底通过可视化的方式进行拖拽嵌套实现,而不提供写JSX的方式来构建UI。React, Vue等组件接入进来都是最小的原子组件,在Schema中只会描述是什么组件,组件名称是什么,npm包信息是什么。


Q: 请教月飞: 搭建Schema规范,如何处理schema和reactjs、vuejs等各大框架的代码转换呢?

A: schema主体结构一致,在部分内容的key上会存在差异,比如生命周期,不同技术栈的生命周期抽象不同,在顶层会有一个字段来表明当前schema属于哪一种技术栈。 至于同一份schema是否能转出成不同技术栈的源代码,目前只在极少场景下会做多端适配,需要对schema做进一步约束,以及搭建的组件必须满足多端适配。


Q: 请教月飞: 不同的框架渲染转换是怎么设计的,一套schema支持到vue,react还有rax,学习成本和使用成本高吗?

A: 目前对于中后台场景,这个不是一个强诉求。schema的设计是多技术栈实现的一个超集。在具体的多端场景中,会综合面向的端来做schema的进一步收敛和约束,以达到可以面向多端的可能。


Q: 请教月飞: 针对多端的适配层是针对每个端写组件还是代码转换去适配多端?如果是代码转换适配多端的,有没有开源这种适配多端的插件呢?

A: 绝大部分业务组件是针对每个端写组件。部分通用场景的原子组件会实现多端适配,目前没有开源的插件。


Q: 请教月飞: 能介绍一下多端的技术实现思路吗?是自创DSL还是组件的源码就需要多端?所谓“渲染模块内核”是只做了js渲染部分还是说连不同端的ui部分都统一处理呢?

A: 提供面向多端的低代码编辑器,而非实现搭建产物schema的面向多端哈。iceluna目前孵化的绝大多数搭建编辑器,要么是中后台React,要么是Rax,或者小程序。只会是其中的一种。不会同时适配多端哈。 有少数搭建产品是同时多端适配的,比如普通列表,表单页面,门户是可以做到PC/移动端双端适配,对于淘系业务来说,这只是中后台比较小的一个场景。


Q: 请教月飞: 能介绍一下跨端的技术实现原理吗?是自创DSL解释器和组件语言:一次开发到处运行?还是组件本身就要开发多套以适应PC、H5、小程序和Native呢?
BTW:Native和小程序一般依赖于自有生态和开发者工具(如Native for IOS、微信、支付宝小程序有其自有生态和IDE工具),你们如何集成倒中台里呢?又如何做调试和渲染呢?

A: 重复问题。


2.4 产品咨询相关

Q: 请教月飞:iceluna-canvas主要是用来做什么?

A: 主要用于实现画布区域的操作功能,如绑定点击事件,双击,原地编辑,右键,拖拽,辅助线等。


Q: 请教月飞: 用ice luna 的编辑器比起直接本地IDE撸代码,提效提效在哪?

A: 工程提效:开箱即用,云端一体化,大幅降低了前端工程启动和环境依赖所带来的成本。     可视化提效:UI拖拉拽+可视化配置,所见即所得。  协同提效:低代码编辑器抽象出来的是一套标准的最佳实践,配置方式一致,等同于有了统一标准的开发步骤和实现,解决了交接/维护/协作等方面的问题。


Q: 请教月飞:ice luna 基于schema生成的页面 对于性能问题是如何处理的呢?

A: iceluan主要还是面向中后台pc的页面,在schema层做了容器组件的拆分,在组件数据更新视图上,diff范围缩小到了容器范围,性能不会有太大问题,常规页面一般不会有太明显的差异。


Q: 请教月飞: 这样的服务中控,是否使场景固态化的,毕竟依赖数据结构是固化的。说到数据结构固化,如何使各视图间相互依赖相互制约?

A: 目前iceluna上的服务,均是中后台场景通用的底层服务。问题中所到的数据结构固化,不太理解是指什么。


2.5 low-code 相关

Q: 请教月飞: 低代码组件是通过怎么样的设计模式,将组件和代码进行耦合的?

A: 低代码组件的实现,主要还是schema的描述,可以描述组件的属性,组件的自定义方法,组件的生命周期,组件的异步数据请求、异步请求数据结果处理等,这些都属于代码的部分。另外schema中描述UI的部分,就是描述组件的嵌套结构,组件的npm包信息(包名,版本号,是否解构,引用路径等)。


Q: 请教月飞: 低代码搭建使用于什么类型的应用开发,不适用于哪些应用的开发?

A: 常规以UI为主的页面,适合用低代码搭建。少UI且功能逻辑复杂的场景,适合用源码开发。 (备注:iceluna的总个搭建编辑器所有插件和面板功能,以及研发中心官方站点,均是低代码搭建的schema渲染的)


Q: 请教月飞: 这块的低代码调试能力是如何思考设计的呢?相对于普通的控制台log,设计中提供了怎么样的能力去增强调试体验呢?

A: 主要是让画布是个实时的runtime,可以在所有写代码的地方加debugger进行断点调试,与源码的渲染流程和逻辑保持一致,另外将低代码渲染引擎中的核心api、数据对象,挂在到window对象下,可以通过console来实时查看数据。


Q: 请教月飞: 使用low-code最终创建出来的是一个react项目或者一个react页面,还是一个纯html页面呢?如果需要的某个页面不光是通过搭建就可以实现的,还需要开发人员做一些定制化的工作,是做怎么呢?

A: 一个标准的react项目。低代码搭建编辑器提供足够丰富的扩展机制,部分实现可以通过源码来实现,发布npm包后接入到项目中使用。


2.6 其他

Q: 请教月飞: 可以讲讲骨架是什么吗?

A: 主要是编辑器的骨骼,用于规划编辑器的栅格布局。


Q: 请教月飞: 这套系统是提供给产品使用的吗?

A: iceluna目前产品形态还偏向于研发,不提供给产品使用。


Q: 请教月飞: 场景切换,在视觉体验是否依赖后端配置?

A: 纯前端实现,不依赖任何后端服务,因为编辑器会被嵌入到不支持远程依赖的场景,比如webIde。


Q: 请教月飞: 淘系营销中后台有哪些非常复杂又比较常用的交互场景?

A: 商家&商品选择器,单个&批量审核/选品/类目选择等等


Q: 请教月飞: 如果我们想做个阉割版本的搭建器,不做平台,哪些功能可以阉割掉?

A: 只需要搭建基础设施即可,编辑器功能可完全自定义,不需要的功能可关闭和移除插件配置。


Q: 请教月飞: 飞冰将很多本地研发的过程线上,线上服务方面,也是飞冰团队开发吗?

A: 是的


Q: 请教月飞: 这么庞大的系统,完全由开发主导实现,中间有产品参与么?怎么确保某个组件是否好用的?

A: iceluna还是一个比较技术型产品,解决研发自身的问题。目前没有产品参与。自身不开发组件,而是提供一套开发组件&页面&应用的开发环境和运行机制。目前使用的组件,由集团统一的Fusion/Antd官方提供。


Q: 请教月飞: 目前分享的是最终成果,那么建设前期有没有什么初级版本,可以快速开发完成并投入使用,有roadmap嘛?

A: 目前暂未开源,不方便提供完整搭建编辑器实现的roadmap。


2.7 人力投入相关

Q: 请教月飞: 整个系统花了多少人力,多长时间去做?

A: 大概历时3年半,前面2年全职投入1人左右,后面1年半7人业务型团队,业务之余开发。


Q: 请教月飞: 人手和工资资源不充足的情况,怎么思考前端低代码建设?

A: 结合业务场景,先聚焦在窄口径的垂直领域做低代码建设。 通用场景中后台搭建人力投入巨大,没有足够大的业务场景,不建议小公司自行建设低代码基础设施,可以借助开源产品或项目做上层建设。


Q: 请教月飞: 没有这么大的人力资源的话,如何基于小公司的现状进行低代码的建设?

A: 同上。


Q: 请教月飞: 可以介绍一下iceluna的开发人数以及级别分布嘛?多少人做出了这么强的一个解决方案,太优秀了?

A:  iceluna开发人数在不同阶段2~7人不等,业务型团队业务之余开发,发展至今已3年半(历时比较久)


Q: 请教月飞: 飞冰系统的建设持续了多久,前后有多少前端资源投入,以及团队梯队如何(比如P6:P7:P8 比例)?

A: 飞冰总体体系建设大致4年左右。投入大致5~7人左右。


三、如何设计实现 H5 页面搭建系统 - 数据模型 --- 沐童

1. 已回答问题

Q: 请教沐童: 请求队列的实现维护是如何做的,如何处理大批量的请求的?

A: 首先,请求队列的目的在于请求去重,因此它需要界定什么是重复请求。我们认为,接口相同且参数相同的请求对象,是重复请求,所以我们直接将请求对象转化为 JSON 字符串之后进行 MD5 计算,如果计算出来的 MD5 一致,那就是相同请求。

其次,我们用一个 map 来维护请求的状态和相关队列,map 的 key 是请求对象的 MD5 值,map 的 value 是一个 object,它包括了三个东西: 1)请求状态:这个请求当前的状态,包括未发起、等待中、正常响应、异常响应; 2)回调等待队列:一个数组,包含了多个重复请求的回调函数; 3)缓存数据:正常响应时写入的响应数据,所以只有请求状态为“正常响应”时才有这个值。

当请求中心接收到来自数据中心的一个请求对象时,会先做一个 MD5 判断,判断结果有以下几种情况: 1)未发起:map 中还没有这个 MD5,说明请求是全新的,未发起的,于是一方面发起请求,一方面在 map 中登记这个 MD5,状态设置为等待中,并将回调 push 到回调等待队列里;等到响应完成后,再根据异常判决结果,将状态设置为正常响应或异常响应,然后设置缓存数据,并将等待队列中的回调取出,一一执行; 2)等待中:map 中已有这个 MD5,并且对应状态是等待中,这个时候就不需要发起请求了,只需要将回调 push 到回调等待队列里; 3)正常响应:map 中已有这个 MD5,并且对应状态是正常响应,直接取缓存的响应数据,回调; 4)异常响应:map 中已有这个 MD5,并且对应状态是异常响应,那么就把它当成未发起状态,重置状态为等待中,并执行 1)步骤。


2. 未回答问题

2.1 schema设计相关

Q: 请教沐童: 你们对不同数据源的数据模型是否有统一约束?类似于领域模型的概念?

A: 暂时没有,对于 MPM 所针对搭建的卖场来说,数据模型的复杂多变是关键问题,所以我们依然是希望能够尽可能赋予数据源更大的灵活性,当然后续我们希望能够实现数据源的可视化管理,包括数据源的生成和修改,可能到时就会需要对数据源补充一些必要的约束手段。


Q: 请教沐童: 组件开发是否有一些规范或者约束,比如要满足能够拖拽需要组件开放一些参数,设计这些规范或约束的目的是什么?

A: 就目前来说,MPM 的页面布局是比较固定的,也就是严格的自上而下铺列的布局方式,并不像其他搭建系统一样,可以灵活自定义组件尺寸和位置,这也是符合卖场的瀑布流布局的。所以,MPM 的拖拽大多时候只是一个 “新增” 的替代操作,不需要组件自身去考虑接入拖拽能力。当然对于搭建体系来说,规范约束自然是少不了的,搭建场景下往往需要考虑的是从开始到现在的整个迭代周期,加之多人协同开发,没有规范约束是走不远的。相比起简单的规范文档保证,我更倾向于将约束加持到开发流程中,比如数据源、同构流程这类带约束力的开发范式,又或者是开发阶段补充的一些规范验证工具(比如构建稿样式规范检测工具等)。


2.2 请求中心相关

Q: 请教沐童: 请求中心的数据聚合是做了BFF层吗?

A: 数据的聚合都是在引擎中实现的,目的是为了将多个楼层朝向同个接口的散装请求,按照聚合策略打包成一个,再从前端发出去,所以我们所讲的聚合其实是在前端做的。但是这样一来,就只能对那些支持批量的接口提供聚合策略了,如果这个接口不支持批量,那就没法指定聚合分发策略了,这种情况下,可以考虑自建一个 BFF 聚合网关来作接口能力增强,配合前端的聚合,可以达到更好的效果。


Q: 请教沐童: 这个调用层是在服务端还是客户端?

A: 调用层指的是页面中发起请求的各处起点,它可以是页面级别的,比如页面查询“这个用户是不是新人“,也可以是组件级别的,比如各个页面获取自身的业务数据。所以如果是直出 h5 场景的话,这个调用就发生在服务端,如果是静态 h5 或小程序场景,这个调用就发生在客户端。


Q: 请教沐童: 重复的接口,是对数据源进行去重吗?

A: 应该说是对重复的请求对象进行去重,数据源描述的是一类请求,请求对象是数据源的实例,它代表了一个请求。


Q: 请教沐童: 需要事件处理后发起的请求怎么聚合到数据中心?

A: 数据中心统管页面发出的所有请求,自然包括一些交互触发的请求,也就是说事件中发起请求也必须调用数据中心的方法,走数据中心代理请求。而分享中我们也提到,数据中心的聚合针对的是一个事件循环(Tick)中收集到的请求,也就是聚合多个一瞬间内发起的请求。假如你的事件触发了多个请求,那就有机会走请求聚合,但如果你的事件就触发了一个请求,那就不会走聚合,也没必要走聚合。


Q: 请教沐童: 你们的这个直出端和nextjs这种服务端渲染有什么区别?

A: 如分享提到,MPM 的初态函数是参考 Next 设计的,因此整个流程的原理和 Next 是基本一致的,都是通过拓展渲染生命周期来为直出同构提供可能。只不过我们借鉴 Next 的初态函数之余,也针对 MPM 场景的特殊要求,对初态函数进行了拓展,包括分享提到的“允许组件拥有初态函数”和“初态函数的分端执行”两个能力。


Q: 请教沐童: 请求队列的实现维护是如何做的,如何处理大批量的请求的?

A: 首先,请求队列的目的在于请求去重,因此它需要界定什么是重复请求。我们认为,接口相同且参数相同的请求对象,是重复请求,所以我们直接将请求对象转化为 JSON 字符串之后进行 MD5 计算,如果计算出来的 MD5 一致,那就是相同请求。

其次,我们用一个 map 来维护请求的状态和相关队列,map 的 key 是请求对象的 MD5 值,map 的 value 是一个 object,它包括了三个东西: 1)请求状态:这个请求当前的状态,包括未发起、等待中、正常响应、异常响应; 2)回调等待队列:一个数组,包含了多个重复请求的回调函数; 3)缓存数据:正常响应时写入的响应数据,所以只有请求状态为“正常响应”时才有这个值。

当请求中心接收到来自数据中心的一个请求对象时,会先做一个 MD5 判断,判断结果有以下几种情况: 1)未发起:map 中还没有这个 MD5,说明请求是全新的,未发起的,于是一方面发起请求,一方面在 map 中登记这个 MD5,状态设置为等待中,并将回调 push 到回调等待队列里;等到响应完成后,再根据异常判决结果,将状态设置为正常响应或异常响应,然后设置缓存数据,并将等待队列中的回调取出,一一执行; 2)等待中:map 中已有这个 MD5,并且对应状态是等待中,这个时候就不需要发起请求了,只需要将回调 push 到回调等待队列里; 3)正常响应:map 中已有这个 MD5,并且对应状态是正常响应,直接取缓存的响应数据,回调; 4)异常响应:map 中已有这个 MD5,并且对应状态是异常响应,那么就把它当成未发起状态,重置状态为等待中,并执行 1)步骤。


Q: 请教沐童: 聚合分发机制,是不是采用nginx的concat来合并同类请求的?

A: 这里说的合并是指在前端发出请求之前,对同接口的多个请求合多为一。当然前提也就要求接口侧必须支持批量,如果接口不支持,我们可以基于 Node 自建一个 BFF 聚合网关,来完成类似于 Nginx 的 concat 能力,灵活性和可控性都会更高。


Q: 请教沐童: 接口分发聚合层能否再分享一下事件循环的细节?使用的是vue的时间循环机制还是自己开发了相应的数据结构?

A: 数据中心根据调用层的请求申请,创建出一个个的请求对象,交付请求中心处理,这是我们理解的大概流程,但内部机制是这样的: 1)数据中心针对每个数据源,都维护了一个队列,每次创建出请求对象后,并不是直接交给请求中心,而是先推入队列中; 2)事件循环采取了类似于 React 的 Transaction 结构来进行批量收集、滞后交付,本质上可以看出是一个 setTimeout(func, 0) 的操作,通过这样的操作,我们会在下一个 Tick,针对上一个 Tick 收集到的各个数据源下的请求对象,分别进行聚合处理,打包成一个请求,再交付给请求中心,如此不断循环; 3)当然了,数据源的 batch 属性中有个 limit 字段,表示该数据源请求的最大聚合数量,所以如果在当前 Tick 中收集队列已经达到上限,则聚合会提前执行,并不会等到下一个 Tick。


Q: 请教沐童: 上述请求队列避免重复请求的方案,如果未缓存的请求在请求的过程中发生失败请求,会如何处理?回调等待队列中的同类请求全部失败返回么?还是有重试机制?

A: 为了简化流程,我在讲稿中略去了异常请求的处理策略。对于失败的请求,其实还需要有个前置判断:什么算是失败。目前 MPM 认为,失败分两种:接口异常(比如接口500)或数据异常(业务错误码不为0)。

第一种很好判断,当发现接口异常时,请求中心直接执行回调通知错误。而对于第二种,我们给每个数据源补充了一个响应校验函数 checkResponse,来为请求中心提供判断响应数据是否异常的依据,如果该函数执行结果是异常,请求中心将不写入缓存,并会执行回调通知错误。
当然了,数据源也可以指定重试次数,用于在接口异常时重新发起请求。


2.3 组件设计相关

Q: 请教沐童: 根据组建配置是如何渲染成真实页面的?能讲下思路吗?

A: MPM 是以楼层为维度对页面进行拆解的,拆解后页面的渲染其实就是多个楼层组件的渲染,有了配置,请求到了楼层数据,再加上提前内置的模板代码,基于 React/Vue,渲染楼层就是一个很常规的操作了。


Q: 请教沐童: 怎么快速开发组件,组件的复用性怎么考虑,比如一个组件只是请求不同,交互几乎完全相同,是重写一个组件还是在组件上开配置?

A: MPM 的开发核心其实是模板,它承载了各个楼层绝大多数的业务逻辑。

如何快速开发模板呢?MPM 利用了类似于 Vue 单文件组件的格式来组织一个模板,具体的实现我在 mp.weixin.qq.com/s/9sKvf0VQV… 这篇文章讲述四大系统要素-模板的时候有提到。

模板交互逻辑不变,更换数据源,是 MPM 经常遇到的需求。分享中我们提到,数据源与接口一一对应,基于数据源向上再封装成更高级的调用函数,所以在这里,我们可以给模板提供一个调用函数,它封装了两个不同数据源,并且会对两个数据源的响应数据进行字段对齐。模板侧只需要开设一个配置项,来决定选取哪个数据源就行。


2.4 数据交互相关

Q: 请教沐童: 数据模型拿到的数据怎么回流到组件?

A: 分享中我们提到,调用层通过 dataService.fetch 来请求数据,这是数据中心提供给调用层的一个异步方法,会返回数据中心接收到的异步响应数据,调用层用 await 来异步获取这批数据。


Q: 请教沐童: 页面在展示给用户以后,如果需要在展示层面做一些业务接口的请求操作(比如卖场里面的商品要去下单,假如需要在下单接口调用的时候,会需要前端组装也产品ID这些参数),需要怎么处理?有什么建议么?

A: 在 MPM,交互操作产生的请求,也需要走数据中心代理,也就是说,我们依然会以一个数据源来设计这个接口请求逻辑,然后调用层以数据中心提供的 fetch 方法来发起请求,这才能真正做到页面请求统管,也更方便维护。


2.5 缓存更新相关

Q: 请教沐童: 缓存如何更新和过期更新?

A: 请求的缓存模块是基于 LRU 算法的,也就是说会对最近一次被引用的时间作个排序,清除缓存时优先清除失活最久的缓存项,至于过期更新我们就没刻意关注了,缓存是在前端做的,驻留时间一般较短,没太必要设置过期时间。


Q: 请教沐童: 请求缓存是否已过期是怎么判断的?

A: 请求的缓存模块是基于 LRU 算法的,由于缓存是在页面上做的,驻留时间一般较短,所以就没太必要设置过期时间了。


Q: 请教沐童: 缓存有效期和缓存上限是如何控制的?

A: 缓存有效期是基于 LRU 计算的,清理时优先清理失活最久的缓存项,上限固定是 5 M。


Q: 请教沐童: 需要实时查询的数据,是标记成不缓存吗?

A: 是的,假如某个接口的所有请求都不希望缓存,可以在数据源中加了一个字段标记,来告诉请求中心,对于这个接口的所有请求一概不走缓存。


Q: 请教沐童: 能讲讲接口缓存、聚合分发怎么做、缓存怎么管理吗?

A: 这个问题比较泛,在其他细化问题中我也做了详细回答。

接口缓存:可以结合问题 “请求队列的实现维护是如何做的,如何处理大批量的请求的?” 和 “缓存如何更新和过期更新?” 的回答了解下。
聚合分发:这块在分享应该是讲解得比较全面了。我们知道,在页面发出请求之前,我们会利用一个缓冲队列提前收集请求,进行尽可能的合并后再发出请求。这里边,关于缓冲队列的实现可以查看问题 “接口分发聚合层能否再分享一下事件循环的细节?” 的回答,如何进行聚合分发,可以对录播视频和讲稿多过几遍,应该可以更深入理解。
缓存管理:可以结合问题 “缓存如何更新和过期更新?” 的回答了解下。
不知道我的回答能不能解答你的疑惑,如果还有疑问,欢迎大群里+我微信交流。


Q: 请教沐童: 缓存怎么更新呢?很多请求是一样的,但是返回数据是不固定的,比如列表?

A: 首先,MPM 卖场场景多为陈列需求,数据实时性其实没那么高,短时间内获取到的数据基本不变(即便是一些实时推荐场景,也不轻易变化),因此我们默认,所有的 get 请求都会优先走缓存。

其次,假如真的有一些场景,接口数据获取的实时性很高,那么我们只需要在我们的接口参数里加入一个变参,比如时间戳或随机数,让请求参数每次都不一样,就能避免缓存。

当然了,假如是针对这个接口的所有请求都不希望缓存,那就不建议通过加变参来避免缓存了,否则很容易造成一些无谓的缓存压力。这种情况下我们建议在数据源中加了一个字段标记,来标记某类接口请求是不允许被缓存的,这种做法更优。


Q: 请教沐童: 缓存怎么更新呢?很多请求、参数都是是一样的,但是返回数据是不固定的,比如列表,每次都需要最新的?

A: 首先,MPM 卖场场景多为陈列需求,数据实时性其实没那么高,短时间内获取到的数据基本不变(即便是一些实时推荐场景,也不轻易变化),因此我们默认,所有的 get 请求都会优先走缓存。

其次,假如真的有一些场景,接口数据获取的实时性很高,那么我们只需要在我们的接口参数里加入一个变参,比如时间戳或随机数,让请求参数每次都不一样,就能避免缓存。

当然了,假如是针对这个接口的所有请求都不希望缓存,那就不建议通过加变参来避免缓存了,否则很容易造成一些无谓的缓存压力。这种情况下我们建议在数据源中加了一个字段标记,来标记某类接口请求是不允许被缓存的,这种做法更优。


2.6 其他

Q: 请教沐童: 你们的系统用户是谁呢?

A: 目前是针对京东内部的运营同学,用于搭建运营、营销活动的卖场和会场,后期可能有计划对外开放,可以小小期待下。


Q: 请教沐童: 请问一下是如何发布部署的?

A: 这里分为三个流程: 1)静态 H5:对于静态 H5,我们会在发布时组装页面,生成一个包含组件模板代码、配置数据、渲染引擎的 HTML,进而发布到 CDN,访问时就是访问这份 HTML,所以页面的发布是组装生成 HTML; 2)直出 H5:对于直出端,我们在发布时会将配置数据存到 Redis,用户访问直出链接时,服务端从 Redis 读取页面配置数据进行数据请求和渲染,然后组装成 HTML 输出到客户端,页面的发布就是将页面配置数据通过接口存到 Redis 即可; 3)小程序:发布小程序页面,我们将配置数据存为一份 JSON,发布到 CDN,用户访问小程序时,引擎会拉取这份 JSON 并解析,请求数据,渲染页面,所以页面的发布是组装生成一份 JSON 文件。


Q: 请教沐童: 解析引擎怎么做 ,怎么部署的?

A: 解析引擎的职责就是获取并解析页面的 PageData,生成真实页面。三端渲染一共对应了三个不同的解析引擎: 1)静态 H5 引擎被我们打包成了卖场依赖的一个 JS 资源。我们利用 Nginx 的 SSI 能力,运营发布 MPM 页面时,生成的页面会自动加上引擎 JS 的引用页面片,访问时经 Nginx 解析,就能依赖到静态 H5 引擎了。 2)直出 H5 引擎存在于我们的 Node 服务中。这里值得注意的是,直出仅仅只是直出了首屏,页面非首屏的内容依然是要进行客户端渲染的(也就是静态 H5 的流程),所以直出生成页面的时候,我们也会将静态 H5 引擎 JS 的引用页面片补充到页面中去。 3)小程序的解析引擎,我们已经提前内置到小程序项目中去了,跟随小程序项目发布。


四、如何设计实现无代码智能搭建 - autoCode --- 妙净

1. 已回答问题

Q: 请教妙净: ImgCook的核心技术是算法团队做的吗?

A:  imgcook团队有专业的算法工程师、前端算法跨界工程师和前端工程师,问题难点一般是由前端工程师提出并解决,算法模型由算法工程师一起调优。


Q: 请教妙净:算法部分也是由前端团队的FE伙伴负责的吗?

A: 是的,目前淘系前端智能化团队也有专业的算法小伙伴,因为全链路涉及的算法模型很多,每一个模型都由前端负责owner,如果准确度不高,由算法工程师一起优化。


Q: 请教妙净: 之前提到了 antd 和 fusion 这些组件库,imgcook是如何和这些物料库结合的?

A: antd 和 fusion 这些组件库都是可复用的物料,对于可复用的物料(组件库、业务组件库),imgcook 提供识别能力和还原链路配置干预能力。 识别能力分为:人工协议识别(人工见 www.imgcook.com/docs?slug=a…)> 模型识别能力(配置处见 www.imgcook.com/docs?slug=t…),最后出码需要根据自己的组件名控制输出的代码,见 www.imgcook.com/docs?slug=d…


2. 未回答问题

2.1 解析实现相关

Q: 请教妙净: PRD2Code应该就是基于NLP+规则生成吧?

A: 是的


Q: 请教妙净: 业务逻辑是如何进行标准化后生成代码的?

A: 我们内部引入逻辑代码协议,大致分为 workflow/action/expression 几个维度


Q: 请教妙净: 设计图层有可能是很多小的图形进行拼接的,那么设计图层的碎片化对代码生成有很大的影响么?

A:  对前端编码视角而言是一个图片,但设计师设计视角是需要多个图形拼接,目前这种情况算法再尽可能地识别“合并”为同一个图层,也可以人工针对多个图层添加 “合并”协议,见:www.imgcook.com/docs?slug=a…


Q: 请教妙净: 模型是怎么根据图层生成,比如 react 代码的,这中间发生了什么,希望重新讲讲。另外前端在这个环节中,是贡献组件、物料、业务代码吗?

A:  可以看看这一页技术分解ppt

image.png


Q: 请教妙净:imgcook这套系统搭前端开发能参与的地方有哪些?好像很多地方都是依赖某些底层的服务,比如模式识别、图片识别这种人工智能相关的服务。考虑开源么?如果考虑开源的话,那大概到什么成熟度会开源?

A:这套系统全部是前端主导设计&实现完成的,模型的能力也是有算法背景的前端同学一起完成的,目前正在着力解决稍微复杂一些的业务智能生成,期望生成代码量可平均达到85%,后续会筹备开源~


2.2 发展方向咨询

Q: 请教妙净:横跨CV、NLP、前端技术栈,CV方向的学生如何接轨?

A: 如果是已经拥有丰富的 CV 方向经验,对前端智能化方向期望对以下技术点有丰富项目经验, openCV、CNN、fastRNN、YOLO等,同时前端基础知识扎实,前端框架、前端工程、Nodejs 等领域有项目经验。


Q: 请教妙净: 在未来前端方面能如何向 ai 方面进行转型和需要掌握哪些具体的技能?

A: 业余时间可学习 传统机器学习、深度学习相关课程;关注并实践 tensorflowjs 、 tfjs-node、和基于 tfjs-node 的前端算法工程框架 pipcook,github.com/alibaba/pip…


2.3 其他

Q: 请教妙净: 前端代码的可用率如何衡量?

A:  可用率 = 通过 imgcook 直接生成的代码被 gitlab 最后发上线最后被保留的代码 / 发上线的所有代码。


Q: 请教妙净: 如何衡量提效比例,尤其是考虑从用户体验因素,有计算公式嘛?

A:  目前仅有内部模块有较严格的提效比例计算公式, 前端研发提效比例 = 100%-内部研发一个模块所用时间(内部研发链路在线化研发所用时间,含 imgcook还原开始+imgcook可视化干预时间 + webIDE编辑停留时间)/原来研发一个模块所用时间;同时感官提效时间也会结合用户调研感官提效的时间加权平均计算。目前的提效时间是一个比较粗的计算方式,比如质疑的点还有,前端的研发是否应该包含需求评估、设计稿评审等时间。


Q: 请教妙净: 深度学习这块是专门有AI部门帮忙还是前端人员学习python开发训练?

A:  淘系前端智能化团队内部有体系化的培训课程,目前淘系前端智能化团队的有 75%+的是传统前端出身,我们目前进行了系统化的学习数理统计、传统机器学习、深度学习等课程,团队内有专业算法工程师答疑授课,并且全链路的算法模型均由前端 owner 进行问题定义、样本采集、样本处理、建模、模型调优、部署等,和频繁的模型调优测试,如果调优效果不明显由算法工程师协助。对前端智能化感兴趣的可以直接钉钉或微信联系妙净。


五、如何设计实现营销搭建系统 - 终端秒开 --- 墨冥

1. 已回答问题

Q: 请教墨冥: 能否讲一下快照渲染如何实现?

A: 快照渲染,本质上就是将用户上一次访问的资源或渲染内容(快照)缓存下来,在下次访问的时候优先使用快照进行快速渲染。常见的方案就是使用PWA中的Service Worker(SW)拦截用户的网络请求,控制缓存的生成、读取、更新。

Q: 请教墨冥: 每个代码模块代码,可能会依赖一些第三方的npm模块,如何避免不同代码模块之间对npm模块的重复打包?

A: 根据场景不同可以考虑两个方案:

  1. 模块申明自己的第三方依赖模块信息,不直接打包代码,由搭建页面发布时构建生成合并去重后的页面级模块依赖信息并打包依赖的模块代码进行发布;
  2. 搭建页面发布时构建生成合并去重后的页面级模块依赖信息,由运行时PI动态载入依赖模块的代码

2. 未回答问题

Q: 请教墨冥: 数据预缓存处理流程是怎么样的?

A: 数据由于千人千面且变化频率快,不适合(预)缓存,所以只做预请求,可以参考分享PPT中的核心时序图,当用户打开页面时,在请求页面代码的同时就由客户端预请求页面级数据并缓存起来,当页面代码解析执行时,调用客户端提供的Hybrid API 获取预请求的页面级数据进行渲染。

Q: 请教墨冥: 这个设计比之离线包的优势是什么呢?

A: 本质上讲,离线包是这个设计方案的一部分,模块代码缓存、页面代码缓存就是使用的离线包方案。这个设计的优势是按照加载的资源(数据、页面信息,模块代码、页面代码)变更频率的差异,做了细粒度拆分,对相对静态的资源做(预)缓存,对相对动态数据做预请求,是在搭建场景下比较极致的资源加载优化方案

Q: 请教墨冥:客户端内web的缓存存在哪里的,indexDB?local Storage?

A:

  1. 模块代码缓存、页面代码缓存是直接离线下载存在客户端的本地物理文件
  2. 快照渲染方案里的Web缓存存在localStorage

Q: 请教墨冥: 首页秒开之后,用户哪些操作会触发次屏缓存,规范这些操作的根据是什么?

A: 加载优化的核心策略之一就是按需加载,首屏秒开之后,次屏的加载策略可以考虑:

  1. 用户操作(比如滚动)触发次屏的加载和缓存
  2. 首屏秒开后,按一定延时间隔自动触发的次屏的加载和缓存

Q: 请教墨冥: 这些独立的模块构建时候是使用了webpack,打包成umd方式,引用时候通过new Function 方式组装的么?

A: 可以这么理解,不过淘系有自己的打包构建解决方案,根据不同场景构建出合适的模块规范文件

Q: 请教墨冥: 经过可视化的搭建之后,输出页面的样式是怎么组成的?感觉应该是内联?如果不是,怎么做到的?

A: 是内联

六、如何设计实现跨端页面搭建系统 - 跨端模块 --- 步天

1. 已回答问题

Q: 请教步天: 想知道系统是怎么部署的,所有页面也是所有环境共享一个页面吗?测试跟开发时怎么隔离的?

A: 系统还是和正常的应用一样区分日常、测试、灰度、线上,对开发者来说用到的都是线上环境,每个页面都是独立的实体页面,如果对线上页面进行调试,可以复制正式页面为测试版本进行修改。


Q: 请教步天: 如果考虑后端的领域模型,前端的工作是不是太复杂了。而且领域模型和前端直接接受的对象类型不是一一对应的,而是对应应用返回的字段,而且也是会经常变化的。这样前端的UI对象怎么做到尽可能的适配领域模型的变化?

A: 考虑后端的领域模型,前端的工作确实会更多,但是反过来想,从公司的角度,如果前端不考虑数据标准化,那么一定会做很多重复的模块、组件或者业务代码,有一套统一的方案,同时尽可能降低领域模型到 UI 模型的映射成本,比如可以自动映射或者可视化编排。如果后端应用足够符合领域模型,那么已有字段就是确定不会变化的,更多就是新增字段的时候需要再映射一下,这个还是有必要的操作。当然如果领域模型和 UI 模型沉淀的比较好的话,实际上你也是在复用映射关系,不需要做修改,后端增加字段,映射也是现有的。


Q: 请教步天: 在跨端设计中你们组件是开发一套还是多套呢?如果是一套组件,那你们如何做到一次开发到处运行的?另,如何解决一套代码(组件)在不同端里渲染?因为PC、H5和小程序的模版都不一样,渲染机制也不一样,肯请解答,说说实现原理和细节?

A: 目前的最佳实践按照设备类型来,比如 PC 端一套、无线端一套(包含小程序、weex、webview),主要实现方式还是依赖 Rax 本身支持。因为都用了 Rax,DSL 是统一用的 JSX,统一用 vdom 作为中间层,不同的端侧差异由 Rax 的 driver 来抹平。具体细节可以看下 rax.alibaba-inc.com/docs/guide/…


2. 未回答问题

Q: 请教步天: 一次开发,生成多端, 如何解决不同端的样式和图片适配问题?

A: 主要实现方式还是依赖 Rax 本身支持,比如 weex 是用运行时的 vdom + driver,小程序则直接在本地编译出一个版本,提升性能。样式问题主要由 Rax 来抹平,如果有特殊差异也可以针对特定容器进行样式调整。图片适配 Rax 也提供了官方的组件,会自动适配。rax.alibaba-inc.com/docs/guide/… rax.alibaba-inc.com/docs/compon…


Q: 请教步天: 组件资源都发布在CDN的话,服务器SSR的时候,如何处理组件资源,获取和清理?

A: 组件其实是同时发布了 CDN、OSS和 npm,SSR 的时候,从 OSS 拉取的文件,然后存到内存缓存内,同时再存一份到本地磁盘应急,清理的话,缓存会定时失效,而本地磁盘则也会定期清理一次。当然之前淘宝也有渲染服务是直接用 CDN http 方式拉文件,原理也差不多。


Q: 请教步天: seed.json在渲染服务中进行实时combo url的过程其实是一个cpu密集型任务,高流量高并发场景下,比如双十一这种场景,渲染服务的高可用性如何保障呢?同时大流量多页面的请求进来,渲染服务是否能够支撑这么大量的实时计算?

A: 因为流量实际上是先到 CDN ,再到渲染服务,大部分并发请求都会被 CDN 挡掉,所以多终端的缓存副本能力还是比较重要的。而对于真正渲染服务自己所需要的计算能力优化,目前是会缓存计算结果,确保一个模块只需要计算一次,同时这是一个内存缓存,多进程之间也可以共享。本质上一个是降低并发量,另外就是依赖计算缓存结果


七、如何设计 toB 商家搭建系统 - 海量部署 --- 奕纯

1. 已回答问题

Q: 请教奕纯: 这边提到的200W页面需要哪些服务器资源来进行支撑呢?

A: 主要看QPS和渲染服务的优化程度,我们这边目前是用了十几台32核机器做为渲染,和几台4核机器进行资源托管,外加一些tair和oss存储,也申请了CDN资源,周边保障设施包括一些实时监控平台和阿里云的一些日志服务等。


Q: 请教奕纯: 物料为什么要部署到机器上,直接放 oss 上不行吗?SSR 的话,node 也可以 load oss 上 的js 资源

A: 这个主要是一个优化的方法,对于大流量请求的话,每个损耗都会比较关键,将物料就近部署可非常有效降低损耗,提升性能。另外,也要假设外部服务不会是一直可靠的,要抱着它出事但是我不能出事的原则去设计,例如机器断网导致oss不可访问等。


Q: 请教奕纯:这边说服务的日访问量最高每天能达到8亿次,这个量级是完全由egg服务进行支持吗?还是说通过其他后台服务进行了协助支持?阿里妈妈这边ToB的宣传界面都是服务端(egg)渲染的么?

A: 都是通过Node支持的,目前没有借助其他服务,阿里妈妈前端这边的常规平台后端都是基于Node。


2. 未回答问题

Q: 请问奕纯: 渲染进程是ssr么?

A: 是的,不过也可以有服务端构建类型的。我们这边目前还是普通的SSR模式,构建在发布时就已经完成。


Q: 请问奕纯: 如何把搭建系统的组件和数据生成静态html发布出去?

A: 如果场景比较简单的话,直接拼装好html页面发布就好了。复杂的场景可能会涉及到SSR等。


Q: 请问奕纯: 集群部署中的分流和tair路由表是指什么,起什么作用?这两个名词不大了解,能否讲一下??

A: 分流这里属于团队内部的一个名词,其实指的是ABTest,当一个请求进来后,会根据配置的实验规则来分配具体的流量去命中不同的页面,这个是业务上的常规流程。路由表这里主要是针对搭建系统的物料获取部分的,依据物料的特征去获取物料文件的实际存储地址。一个实例,一个请求进来了,去路由表里获取分流物料,并完成本地部署,然后再去计算分流配置,确定接下来要命中的目标。


Q: 请问奕纯: 请问老师,每一次页面请求,都会默认走一遍cdn,没有命中才会开启一个worker ,执行SSR渲染么?

A: 不全是,如果页面是静态的,渲染服务可以做为CDN的源站来响应,不过很多情况下页面不是静态的,例如页面中需要服务端直出同时也需要配合接口的个性话数据,此时会是实时渲染模式。具体都那种模式,页面搭建的时候可以进行配置。



关注下面的标签,发现更多相似文章
评论