Skip to content

58、低代码 #60

@CodingMeUp

Description

@CodingMeUp

最终场景: 基于模型设计直接生产标准化页面
低代码引擎的几大核心能力:入料、编排、渲染、出码

低代码引擎: 制定统一底层协议,基于标准打造出低代码平台的基础能力,并在此基础上提供定制化能力

架构分层

协议栈 --(实现)-->
低代码引擎 -- (扩展) -->
引擎的生态(包含 插件物料工具链面板配置) --(支撑)-->
低代码平台(宜搭 纪元 表单平台 数据平台)

前端技术领域

  1. 组件体系: 将页面中所使用的的元素进行原子化封装,通过配置选项让组件具备适应性调整的能
  2. 可视化搭建设计器:布局可视化、配置可视化、样式可视化
  3. 弱工程化:将打包、发布等等各种环节进行弱化,用户只需要所见即所得的关注页面产出

协议先行

  1. 低代码引擎物料规范
  2. 低代码引擎搭建协议规范

低代码入料

入料模块负责物料接入,通过自动扫描、解析源码组件,产出一份符合《中后台低代码组件描述协议》的 JSON Schema。这份 Schema 包含基础信息和属性描述信息部分,低代码引擎会基于它们 在运行时自动生成一份 configure 配置,用作设置面板展示

大体分为本地化、扫描、解析(【静态】: react-docgen解析JS/TS,自定义了 resolver 及 handler,前者用于寻找组件 定义,后者用于解析 propTypes、defaultProps,【动态】:require 组件进来 parse-prop-types 库,动态解析可以解析出全部的类型信息,因为 PropTypes 有可能引入依赖组件的一些 类型定义,这在静态解析中很难做到,或者成本较高,而对于动态解析来说,都由运行时完成了)、转换、校验 5 部分

低代码编排

编排,即将设计器中的所有物料,进行布局设置、组件设置、交互设置(JS 编写/逻辑编排)后, 形成符合业务诉求的 schema 描述 。本质是生产符合《低代码引擎搭建协议规范》的数据,在这个场景里,协议是通过 JSON 来 承载的,编排实际上操作 schema,但是实际代码运行的过程中,我们将 schema 分成了很多层,通过将 schema 和常用的操作等结合起来,最终将低代码引擎的模型分为节点模型、属性模型、 文档模型和项目模型。

  1. 项目模型(Project)

提供项目管理能力。通常一个引擎启动会默认创建一个 Project 实例,有且只有一个。项 目模型实例下可以持有多个文档模型的实例,而当前处于设计器设计状态的文档模型,我们将其添 加 active 标识,一个 Project 包含若干个 DocumentModel 实例,即项目模型和文档模型的关系是 1 对 n

  1. 文档模型(DocumentModel)

文档模型提供文档管理的能力,每一个页面即一个文档流,对应一个文档模型。文档模型包含了一 组 Node 组成的一颗树,类似于 DOM。我们可以通过文档模型来操作 Node 树,来达到管理文 档模型的能力。每一个文档模型对应多个 Node,但是根 Node 只有一个,即 rootNode 和 nodes。

  1. 节点模型(Node)

Node 节点模型就是负责这一层级的 Schema 管理。它的功能聚焦于单层级的 schema 相关操作
Node 节点模型核心功能点有三个:
1)Props 管理:通过 Props 实例管理所有的 Prop,包括新增、设置、删除等 Prop 相关操作。 2)Node 管理:管理 Node 树的关系,修改当前 Node 节点或者 Node 子节点等。 3)Schema 管理:可以通过 Node 获取当前层级的 Schema 描述协议内容,并且也可以修改它。 通过 Node 这一层级,对 Props、Node 树和 Schema 的管理粒度控制到最低,这样扩展性也就 更强。

  1. 属性模型(Prop)

一个 Props 对应多个 Prop,每一个 Prop 对应 schema 的 props 下的一个字段。
Props 管理的是 Node 节点模型中的 props 字段下的内容。而 Prop 管理的是 props 下的每一 个 key 的内容

项目、文档、节点和属性模型关系
整体来看,一个 Project 包含若干个 DocumentModel 实例,每个 DocumentModel 包含一组 Node 构成一颗树(类似 DOM 树),每个 Node 通过 Props 实例管理所有 Prop。整体的关系 图如下。

节点 & 属性模型是引擎基石,几乎贯穿所有模块,相信从上面的类图已经能看出几个基础类的职责 以及依赖关系。
节点 & 属性模型等价于 JSON 数据结构,而编排的本质是产出 JSON 数据结构,现在可以重新 表述为编排的本质是操作节点 & 属性模型了。

低代码渲染

低代码渲染的载体大多数都是在 Web 浏览器上。 所以低代码渲染是在 Web 渲染的基础上进行的另一个渲染黑盒。低代码渲染的模型是基于标准的《低代码引擎搭建协议规范》产出的 Schema。而影像是同 Web 端一样的网页,由于其特性,它可以只作为网页的一部分存在,也就是区块;它也可以作为一整个应 用存在,即应用级别的渲染

由于低代码渲染实际上底层是利用的 web 端渲染能力,即最终我们的语言都会转化为 web 端的 语言。所以这一个过程需要进行转化。而像是大多数编译器一样,低代码渲染的编译模式也分为预 先编译(AOT)或运行时编译(JIT)形式工作

运行时编译渲染(JIT)

运行时编译渲染又称为实时渲染。指的是,保留原始的描述模型,在网页加载并执行 JS 的时候,通 过递归、计算 props、设置上下文等实时操作来完成渲染的过程

JIT优势:

  1. 实时性强 运行时渲染是有其优势的,它省略掉了编译的时间,做到实时生效。对于低代码搭建的产 品来说,进行了修改之后是不希望在 1-2 min 甚至更长的时间才能在页面中看到效果,而是希望 在修改之后的下一秒就可以看到变更的效果。因为,大多数低代码的渲染都是选择这一方式,或者 就是 JIT 和 AOT 的渲染能力都能提供。
  2. 轻量化 现代化的前端项目基本上都没办法离开工程化体系,一个 React 项目至少需要 Webpac k、Babel、发布、部署等步骤。而对于运行时框架,我们需要的就只有 Schema 和一份前端渲染所 需的 SDK。对于运营、产品、后端等低代码使用人员是十分友好的。

JIT局限点:

  1. 性能瓶颈,和大多数的 JIT 的框架一样,JIT 渲染由于需要运行时进行编译,这个编译是会带来性 能损耗的。一方面是首屏时间时间的损耗。另外一方面在交互的过程中,由于上下文的改变,需要重 新进行递归计算,这个带来的损耗影响是更大的,因为这个会在首屏渲染出来之后,还会有操作卡 顿、延迟等问题。
  2. 小程序不支持,部分平台不支持 JIT,原生小程序不支持动态化渲染。小程序作为移动端上实现快速迭代、提升用户 体验、集成端能力的集大成的解决方案,已经成为商业的重要技术基础设施。而原生小程序有着诸 多的限制,它不能够直接操作 DOM,所以导致动态化渲染无法在该平台上完成。

预先编译渲染(AOT)

预先编译渲染又称为出码渲染,指的是,将 Schema 等模型通过编译器编译为特定语言的代码。预先编译渲染,我们在低代码领域叫做出码。如出码成 React,这样就可以省略 掉运行时编译的递归和计算流程,能进一步提升其性能。如果想完全抛弃运行时相关的代码,也可以直接出码为 JavaScript + HTML。

AOT优势:
性能优化上限更高,不能说 AOT 性能就会比运行时性能好,毕竟这很大程度依赖于出码之后的代码,如果出码之后是没有性能优化的,那么它的性能很可能低于运行时。但是由于其出码的形式是 没有受到限制的,所以它的性能是可以比运行时的性能优化的更好的。

AOT局限点:

  1. 成本高,由于 AOT 出码不是统一的,所以需要出码到不同的模型都需要写一份,所以出码的成本 相对比较高。
  2. 实时性低,出码需要较长的编译时间,所以在搭建页面修改之后,无法即时生效。所以无法使用在低 代码预览场景。

低代码出码

所谓出码,即将低代码编排出的 schema 进行解析并转换成最终可执行的代码的过程。出码是为了更高效的运行和更灵活地定制渲染。相对而言,基于 Schema 运行进行渲染的优点在于 其能实时响应内容的变化和接入成本低,而缺点是实时解析运行的性能开销和包大小都比较大,时 无法自由地进行扩展二次开发,功能自由度受到一定程度限制。

出码也会存在一些限制:一方面需要额外的接入成本,另一方面通常需要额外的生成代码和 打包构建的时间,难以做到基于 Schema 的运行时渲染那样保存即预览的效果。 所以不是所有场景都建议做出码,一般来说以下 3 个场景可以考虑使用出码进行优化

  • 场景一:想要极致的页面打开速度,降低 LCP/FID
    这种场景比较常见的是 C 端应用,比如手淘上的页面和手机钉钉上的页面,要求能够尽快得响应用 户操作,不要出现卡死的情况。当一个流入协议大小比较大的时候,前端进行解析时的开销也比较 大。如果能把这部分负担转移到编译时去完成的话,前端依赖包大小就会减少许多。从而也提升了 加载速度,降低了带宽消耗。页面越简单,这其中的 gap 就会越明显。

  • 场景二:老项目 + 新需求,用搭建方式产出页面
    这是一个很常见的场景,毕竟迁移或者重构都是有一个过程的,阿里的业务都是一边跑一边换发动 机。在这种场景中,我们不可能要求使用运行时方案来做实现,因为运行时是一个项目级别的能力, 最好是项目中统一使用他这一种方式,保证体验的一致性与连贯性。所以我们可以只在低代码平台 上搭建新的业务页面,然后通过出码模块导出这些页面的源码,连同一些全局依赖模块,一起 Merge 到老项目中。完成开发体验的优化。

  • 场景三:协议不能描述部分代码逻辑(协议功能不足或特别定制化的逻辑)
    当我们发现一些逻辑诉求不能在目前协议中很好地表达的时候,这其实是项目复杂度较高的一个信 号。比较好的方式就是将低代码研发和源码研发结合起来。这种模式下最大的诉求点之一就是,需 要将搭建的内容输出为可读性和确定性都比较良好的代码模块。这也就是出码模块需要支持好的使 用场景了。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions