北海(Kraken)构建大前端混合渲染技术体系 —— Web 与 Flutter Widget 混合渲染方案

Posted Alibaba F2E

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了北海(Kraken)构建大前端混合渲染技术体系 —— Web 与 Flutter Widget 混合渲染方案相关的知识,希望对你有一定的参考价值。



背景


组件(模块)封装与开发可以给前端业务开发的过程带来非常大的研发效能的提升,各个业务域的开发者会定制开发许多符合自己业务场景的基础组件(模块)沉淀一套快速复用的物料体系,以保证业务开发的研发效能。同样,在各个 Flutter 团队,也有大量的 Flutter Widget 的物料,以及各种基于 Flutter 场景做的性能优化。在大前端的视角下,我们期望在端内拥有 Web 开发的研发效能以及动态性的同时,也期望通过一些 Native 的优化手段让应用拥有媲美原生的体验与性能。

北海(Kraken) 作为一款高性能、易扩展的 Web 标准渲染引擎,通过上层实现 W3C 标准以提供前端开发者较低的学习成本以及快速复用已有的前端研发体系的能力。众所周知,除了根据前端框架做一些业务组件开发,在前端有一套为容器(浏览器)标准的扩展定制能力的技术 —— Web Components。Web Component 更多地提供开发者创建可重用的定制 element 的能力,而它本身基于 Web 技术栈还是存在一些限制,比如说无法直接管理 Render Object 达到在长列表下一个动态回收能力等。作为一个 UI 能力的复用以及对基础原子组件能力的封装,Web Components 是完全够用的,但是对于在端内在节点容器上提供一些默认的 Native 级别的优化,Web Components 显得并没有那么突出,这里面其实还可以有更大的想象空间。

那么,Kraken 本身是一款基于 Flutter 技术开发的 Web 渲染引擎,是否可以复用 Flutter 生态,将 Flutter Widget 能力融合进 Web 渲染能力中呢?这样可以复用大量 Widget 的业务组件,采用同一条渲染管线高效渲染的同时,也在端内提供了更多客户端(Widget)的性能优化手段,以形成一套“动态化”、“高性能”、“易扩展”的融合 Web 与 Flutter 生态的大前端技术体系。


实现一个  FlutterContainerWidgetElement ,并通过 defineCustomElement 注册到 Kraken 中去,使其成为一个 Custom Element。在 FlutterContainerWidgetElement 的 build 方法中,每当该节点的 attribute 或者子节点变化(比如 appendChild),该节点就会被标脏,依赖 Flutter 的生命周期,该节点最终会重新被 build,Kraken 在此时会把该节点最新的 properties 以及 children (对应到前端就是 setAttribute 以及 dom 节点)传递过来,Widget 根据这些参数完成一次 build,最终更新到界面上。

下面是一个将 Flutter 的 Column Widget 实现一个 ColumnWidgetElement 以提供给前端一个列布局容器的 Demo。

即可调用该 Widget 能力。

,在 Kraken Widget 的生命周期 mount 中,会将该 Flutter Element 的指针存储起来,以供后续使用(后面的 Flutter Element 需要挂载在 Kraken 的根节点上)。此外,初始化过程会创建出大家熟悉的 Window、Document、Body 以及 Head 等节点,同时创建出对应的 Render Object。

接着是中间一部分,这里展示了一个 Flutter Widget 作为容器(下面继续插入 DOM 子节点)以及普通 DOM 在 Kraken 内部的一个渲染流程。首先是普通的 DOM,以最右侧黄色树的 DIV Element 以及 TextNode 为例,它们插入到 BODY 节点上就是默认的 WEB 渲染流程,会生成对应的 RenderFlowLayout 以及 RenderTextBox、RenderParagraph 作为对应的 Render Object 插入到 Render Object  Tree 中。当一个 Flutter Widget (WidgetElement)作为节点插入到 DOM 树中时,会有一个 WidgetElement(继承自 dom.Element)作为 DOM 结构插入到 DOM 树中去。那么这个以 Flutter Widget 作为实现的 DOM 节点,是如何驱动 Flutter Widget 产生 Flutter Element 以及对应的 Render Object 并挂在到对应的父节点的 Render Object 上的呢?

首先,WidgetElement 类在初始化时会创建一个 Stateful 的 Widget——_KrakenAdapterWidget,当一个 DOM 节点的 attribute 或者 通过 appendChild 等操作插入(或删除)一个子节点时候,会需要通过触发 build 将 Widget 标脏,使该 Widget 可以通过 Flutter 的生命周期重新构建输出。同时,该 Adapter 也会对所有子节点进行处理,如果子节点是一个 Flutter Widget,则直接通过 build 方法构建出对应的 Widget,如果子节点是一个普通的 DOM,则会通过 KrakenElementToWidgetAdaptor 来包装一下该节点,已桥接对应的生命周期以及 Render Object(下面会讲到普通 DOM 如何转换成一个 Flutter Widget)。

我们知道, DOM 最终被被插入 DOM Tree 后会将产生的 Render Object 也插入到 Render Object Tree,如果 DOM 节点是一个 WidgetElement(Flutter Widget),那么就需要使用 Flutter Widget 最终生成的 Render Object。所以 override 了 didAttachRendere 生命周期,内部调用了 _attachWidget,通过它将 Flutter Widget 最终产生的 Render Obejct 给 attach 到 Render Object Tree 上。

最后来看看上文已经提到过的,一个普通 DOM 元素是如何融入到 Flutter Element 与 Widget 的渲染流程中去的。以 DIV Element 为例,在上文提到的 convertNodeListToWidgetList 中,会将一个普通 DOM 元素转化成 KrakenElementToWidgetAdaptor 这个 Widget,该 Widget 的 createElement 会生成对应的 Flutter Element, 所以会被 override 掉,并生成 KrakenElementToFlutterElementAdaptor 这个 Flutter Element。同样的,该 Widget 我们并不希望它会按照 Widget 流程产生一个 Render Object,而是直接用上述的 DIV Element 产生的 Render Object, 所以会通过 createRenderObject 方法来直接返回 DIV Element 产生的 Render Object。

同样,KrakenElementToFlutterElementAdaptor 这个 Flutter Element,会在 mount 以及 umount 生命周期中触发 createRenderer 等方法,用 Flutter 的生命周期钩子去保证 Kraken DOM 的一些流程的调用或者资源的释放。

基于以上原理,Kraken 实现了 Flutter Widget 作为一个 Custom Element 嵌入到 Kraken 中的任何地方。以 Demo 的 JS 代码为例渲染 已注册到 Kraken 内部的 Flutter Widget,Flutter Widget 无论作为容器还是一个子节点,都可以呈现在 Kraken 中,用 JS 来动态修改。来监听 Widget 组件抛出的 Custom Event。

flutterContainer.addEventListener(\'refresh\', () => );

最终渲染出来的内容如下,可以看到内部子节点的 Web 节点可以直接使用瀑布流 Widget 的布局能力。同时,由于该 Widget 自带的动态 Render Object 回收能力,可以使得子节点在滚动时候动态回收,保证流畅地滚动,并且内存不会有明显的增量。而这一切对于前端开发者是没有任何额外的接入以及理解成本的,Flutter Widget 接入 Web 体系中会完全按照 Web 标准呈现给前端。同样,对于 Flutter 开发者,依旧可以控制熟悉的三棵树——Widget、Flutter Element 以及 Render Object,以提供一些端上的增强能力。



最后


Kraken 在 follow 了 W3C 标准的同时,也将 Flutter 的渲染能力融合进整个体系,让 Flutter 生态与 Web 生态融合渲染,成为一个融合渲染的大前端技术体系,互相取之所长,补其所短。让 Web 前端生态提供的表现力、动态性以及 Web 生态使业务可以快速开发迭代,满足大部分变化的业务。同时也让 Native 的同学可以提供给前端开发者多样化的 UI 渲染能力,以及将更多的性能优化手段运用到整个体系中,使优化的上限更高,体验更好。

同时,基于 Kraken “易扩展”这个点,开发者可以用非常低的定制成本根据自己的业务域开发一款深度定制的 Web 渲染引擎。复用已有的基建以及生态,给端内的体验带来更多的体验升级以及可能性。

最后,Kraken 的所有代码都已经开源,Kraken 提供了开放的 TSC 机制期望所有开发者可以平等地交流以及决策,使 Kraken 可以更好地发展,也欢迎更多的开发者一起来共建 Kraken。

Kraken Github:https://github.com/openkraken/kraken

Kraken 官网:https://openkraken.com/


前端技术选型

本文主要介绍前端技术选型。

文章目录


前言

前端技术选型


一、名词解析

名词 说明
大前端 手机、web、PC等客户端
native开发 原生开发语言,安卓或IOS等都有专属的平台框架来做应用
混合开发 通过H5+APP开发应用的技术,这里的APP指js调用系统能力

二、主流架构框架

框架名 技术支持 思想 针对性
React Facebook<

以上是关于北海(Kraken)构建大前端混合渲染技术体系 —— Web 与 Flutter Widget 混合渲染方案的主要内容,如果未能解决你的问题,请参考以下文章

混合开发之uni-app

前端知识体系-JS相关对移动端和Hybrid开发的理解?

前端技术选型

Shiro+SessionId构建token鉴权体系

NodeJS 服务器负载均衡方案(性能优化)

web性能优化之浏览器网页渲染原理