游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

深入解析基于Flutter的Web渲染引擎北海Kraken技

  大家好,我是染陌,这是我在全球开源技术峰会GOTC上的一个topic《基于Flutter的Web渲染引擎北海Kraken》。我主要从技术角度来分享Kraken的一些实现原理以及关键的技术特性,现在整理成文字版分享给大家。
  KrakenGithub:https:github。comopenkrakenkraken
  Kraken官网:https:openkraken。com北海的技术背景
  说到北海的技术背景就不得不提及跨端技术的演进,很多同学应该都比较熟悉跨端技术的历程了,我还是简单讲一些。
  我们知道,浏览器是最成熟的天然跨平台方案。早在PC时代,浏览器已经成为了互联网的入口,大家都会习惯性通过浏览器来进行网页的浏览以汲取各种信息,当时我们把这种上网的方式叫做冲浪。然而到了移动时代,浏览器在移动设备上并没有一个抢眼的表现,反之因为内存大、弱网环境白屏久、传感器能力缺失(标准跟进慢)等问题使各种质疑不绝。
  为了弥补上述浏览器在移动端的一些不足,出现了Hybrid技术,在Web之上通过容器的能力实现一些非标准化的超集,同时也通过prefetch、离线包等各种技术来提升首屏的加载性能。
  此后,出现了类RN的方案(典型代表ReactNative),它的原理是通过JSengine将Native控件与前端生态实现一个桥接,通过Web开发业务逻辑提升效率,而向下通过Native控件渲染来提升性能及体验。但是这类方案的缺点是无法完全抹平两端的差异,没有解决一致性的问题,而最终将复杂度暴露给了开发者。
  Flutter作为跨端届的新宠,这两年也获得了越来越多的关注,下面介绍一下Flutter。
  Flutter的优点是性能好、由于其通过自绘渲染使得跨端一致性高,但是它也有它自身的缺点,比如生态自成一派,既不是前端也不是AndroidiOS。
  这就是引出了一系列的问题。首先,前端(JavaScript)或客户端(SwiftJAVA)转型都有一定成本,但是由于端侧的GUI体系大同小异。笔者站在一个前端开发者的视角去看语言上的学习成本并不会特别高,有React或者Vue等前端框架经验的同学可以通过简答的学习快速上手。对于一些小型的创业团队,确实可以小步快跑快速学习上手并开发,但当组织庞大到一定程度,这个转换的成本将会指数级上升。其次,生态圈等待重新建设,一些Flutter开发者朋友或许觉得目前Flutter开发已经有挺多的pub可以直接使用了。但实际上生态圈不止于Flutterpub,还有各种已有的基础链路,比如建设相关的CICD,再比如搭建等等。这一系列的生态都需要重新建设,成本是非常大的。再次,已有的非常多业务都是通过JavaScript前端框架开发的前端项目,我们如果想把它们迁移成DartWidget成本无疑是非常庞大的。
  在面对如此多的问题以及切换的高成本的同时,我们也期望通过Flutter给我们的业务带来更多的技术的可能性,同时改善Web容器在端上的一些性能及体验问题。那么,引入一项新技术的第一步是解决引入这项新技术的成本问题,所以我们积极探索一种将前端生态与Flutter结合起来的方案。
  于是产生了本次topic的主角北海Kraken。
  Kraken是一款高性能Web标准的自绘渲染引擎,具有高性能、易扩展、基于Flutter以及遵守Web标准的特点。
  下面我列举了一些北海在阿里的一些应用场景,在C端APP或者IoT设备上,北海都有相关的落地。
  北海的技术原理
  在介绍Kraken的技术原理之前,我先演示一下如何开发一个Kraken应用。因为Kraken是基于W3C标准来开发的Web渲染引擎,所以上层是框架无关的,无论开发者使用的是Vue或者React还是Rax都可以在Kraken上进行一个应用开发。
  以Vue。js开发为例,下面是我用Vue官方提供的vuecli起的一个项目。具体的代码见官方示例。
  可以看到的是,最左边是Vue的相关代码,右边分别是该应用在Chrome(左)上跑的结果以及在Kraken(右)上跑的结果,大家可以看到结果是完全一致的。
  了解了如何开发一个Kraken应用,我们再来理解一下Kraken的技术原理。为了大家更好地理解,首先我们来比较一下Flutter于Webview的渲染流程。
  WebView的渲染流程相信大家非常熟悉了,面试中非常经典的题目就是一个URL输入如何最终渲染到屏幕上了。总的来说就是解析HTML、JS以及CSS文件,执行相应JS调用DOMAPI,最终会生成DOMTree以及CSSOMTree,然后会计算最终得到RenderTree,经过Layout以及Paint流程生成一系列的Layer,最终通过合成以及光栅化渲染到屏幕上。
  再看Flutter这边,Flutter经典的三棵树WidgetTree、ElementTree以及RenderObjectTree。WidgetTree对应到前端类似于前端框架这层,而Element与DOMTree,RenderObjectTree与RenderTree分别对应,最终也会通过Layout以及Paint一系列计算生成Layer,然后通过合成以及光栅化渲染到屏幕上。
  那么,我们再将前端框架加入到我们整个流程中进行一个更加直观的对比,这里还是以Vue。js为例。
  Vue。js会在运行时生成一系列Vdom产生VdomTree,再通过platfom的抽象调用具体平台的API。
  那么我们就会发现,只需要把我用红框圈出来的部分的流程进行互换,就可以实现我们最终想要实现的效果(上层Web开发,下层基于Flutter进行渲染)。
  基于以上设想,那么北海的渲染流程就出来了。
  目前主流的前端框架都会将产物打成一个JSBundle,通过标准的DOMAPI去操作具体的视图,而HTML内一般只有一个根结点。在Web下,页面会先请求HTML文件,再解析Script标签去加载对应的JS文件。而Kraken的入口设计成了一个JS文件,这样做可以减少一次请求,加快首屏的渲染。
  该JS文件会在JSEngine中执行,Kraken的runtime通过JSEngineBinding的方式提供了一系列Web标准的API接口,调用相应API会执行相关逻辑并创建一系列需要发送给Dart层处理的指令,指令通过一个struct进行存储。C通过FFI将相应的指令底层的address发送到Dart这边,Dart处理相关指令并生成DomTree。同样的,CSS也会通过Parser生成对应的CSSOMTree,最终会结合生成Flutter的RenderObjectTree,经过Layout以及Paint的一系列计算,生成对应的一系列Layter,然后通过合成光栅化最终上屏显示。
  同样的,在最新的实现中,我们考虑到了SSR应用的场景,所以加入了HTML为入口的北海应用开发方式,通过HTMLParser即可解析对应的HTML文件,后续流程是一样的。SSR的支持也让首屏的秒开率更上一层楼。
  那么了解了Kraken的整个渲染流程,那么我们如何基于Flutter去完成Web标准的渲染引擎的开发呢?
  那么要基于Flutter去做这个事情,就必须先了解Flutter的架构。
  Flutter最上层是Dart实现的Framework,包含了响应式框架、官网组件库以及实现布局与绘制协议的部分。中间是C实现的FlutterEngine,他是渲染流程的下半部分,提供了一些基础能力,以及将layer合成以及光栅化后输出。最下层的Embedder层,则负责具体platform的一些实现,以实现跨平台。
  不难发现,最DartFramework的Widget是对UI的抽象,实现了一套响应式框架,对应到前端就是VueReact等前端框架。而下方的布局协议,可以对应W3C的标准来实现一套基于前端标准的布局与绘制协议。
  那么我们就可以得出北海的架构设计。
  先看左边,左边还是上面介绍的Flutter的整体架构,Flutter的Widget能力可以通过插件的形式注册到Kraken中去,成为一个前端标准的Tag,JS可以动态化地调用及控制渲染。整个左侧的Flutter架构支撑了上层的Flutter生态,使Flutter生态也可以通过插件的形式融合到整个Kraken的渲染体系中去。
  右边是Kraken的架构实现,Kraken的实现并没有把实现侵入到FlutterEngine中去。在Dart层,通过实现W3C标准的一系列布局与渲染能力,为上层提供了一些列标准化的能力,比如Element、CSS、以及各种Web标准的Module等。在上层Kraken的runtime通过JSEngineBinding的方式提供了一系列Web标准的API接口,调用相应API会执行相关逻辑并创建一系列需要发送给Dart层处理的指令,指令通过一个struct进行存储。C通过FFI将相应的指令底层的address发送到Dart这边,最终Dart根据指令调用前面说的标准化能力,以完成对接。通过该实现,为上层的前端生态提供了支撑,凭借丰富的前端生态,开发者可以享受前端生态带来的高效的开发体验。
  关键技术特性
  首屏的加载性能是一个C端场景的关键指标,长时间的白屏会极大地影响用户体验。
  Kraken在首屏初始化时需要创建大量的节点,大量的时间耗费在通信上,所以优化首屏性能迫在眉睫。
  在上面技术原理部分我们知道,Kraken需要通过Bridge来完成C(JSEngine)与Dart之间的通信,以达到将指令传递到Dart层的目的,Bridge的架构也进行了三个版本的演进。
  最初的第一代方案,我们侵入了FlutterEngine,使数据从JSEngine传递到FlutterEngine中,然后通过nativebingding最终将数据发送给Dart层。这一代的方案非常明显的缺点是侵入了FlutterEngine,开发时需要编译FlutterEngine需要耗费大量的时间。同时,对于Kraken的架构来说,侵入FlutterEngine也并不是一个合理的设计。
  后来出现了DartFFI,可以实现C与Dart之间的高效通信,所以产生了第二代方案。第二代Bridge方案通过将JSON数据序列化后,通过DartFFI将数据传递到Dart层,Dart层再通过JSON的反序列化以拿到最终的数据。这代方案比起上一代方案可以解决侵入FlutterEngine的缺点,但是引入了字符串的拷贝以及JSON序列化反序列化的时间长的问题。
  为了解决上述问题,于是产生了第三代Bridge方案。第三代Bridge方案通过共享内存的方式定义了一个标准的40Bytes的Struct来存储指令,而通过DartFFI传递的只是指令的地址,C跟Dart两边都依赖地址来访问相关数据。这样做解决了JSON序列化反序列化的问题,节约了时间,并且少一次数据拷贝。同时,由于内存是40Bytes对其的,可以提高内存的访问效率。
  下面是一些实际线上页面带来的首屏收益。
  无限滚动的长列表是困扰前端开发者很久的历史性问题了,大量的layout导致页面卡顿,以及滚动时Paint的时间长导致滚动掉帧,页面的体验非常糟糕。社区也有非常多的前端的解决方案来处理该问题,而在Kraken上,我们也期望在容器层解决该问题。
  在Android跟iOS上也分别有RecyclerView以及TableView来解决该问题,他们的原理分别是在可视区域viewport外定义一块缓冲区域,当节点超过该区域时进行动态释放,进入该区域时动态创建,以及通过一系列节点进行属性替换的方式来保证节点数不爆炸。Flutter中也提供了类似实现Sliver,那么我们能否用Sliver赋能前端解决该问题呢?
  Kraken定义了一个新的display属性sliver,通过将节点的display属性设置为sliver,则可以直接使用Flutter的Sliver能力,以达到节点超出可视及缓存区域后动态回收的一个能力。可以看到我们使用1000个卡片的DEMO进行测试,sliver下比起block有明显的收益。
  同时,该标准也已经在W3C中文兴趣小组进行了讨论,期望在大家讨论充分以及达成共识后,尝试将此提案向W3C进行提交,反哺前端社区。
  一个大前端团队往往既有客户端也有前端,会沉淀一系列的端上的能力。不同的需求会有不一样的技术选型,譬如说一个播放器往往是通过Native技术去开发的。我们期望将端上的能力(包括FlutterWidget、Web、Native以及三方SDK等)进行整合,融合成一个大前端的端开发体系,所以在Kraken内我们如何整合端上的这一系列能力呢?同时,我们也期望按需引入,能做到包体积的优化。在不同的业务域,我们期望可以快速地进行定制化开发,快速形成一套垂直业务域的领域能力。
  Kraken提供了一套扩展能力来解决上述问题,通过渲染能力扩展接口,开发者可以将开发完成的符合标准的FlutterWidget以及Native的渲染能力快速集成到Kraken体系中去,最终通过JavaScript来提供一个动态化调用的能力。同样的,通过MethodChannel,开发者可以通过该通道调用一些Native或者DartAPI的能力,譬如说一些二方或者三方的SDK能力。
  开发者可以通过扩展能力自定义业务域需要的能力,按需拔插以达到包体积优化的目的。同样的,注册到kraken的插件都可以通过JavaScript代码控制,提供了动态性。
  下面是一系列在Kraken内部扩展FlutterWidget、NativeAPI以及Native播放器的Demo。
  下面是提升可交互性。在介绍Kraken的可交互性之前,我们先来看一下在Web下的一些交互问题。
  在Web下开发富交互能力的应用时,前端开发者往往需要引入一个额外的lib来提供增强的手势能力(譬如说Hammer。js这样的手势库)。那么当前端开发者引入lib时,就会导致加载index。html以后,还需要额外的请求对应的JS库,造成一次额外的请求开销的同时延长了首屏的可交互时间。
  当用户在屏幕上进行某个操作时,由于用户操作的方式可能是用户的手,也可能是ApplePencil或者鼠标这样的设备。所以在W3C标准中,将用户操作可交互应用的触点抽象为一个pointer,这些pointer会根据操作形成一个手势,分别是down、move、up三个过程,其中move可省略(譬如说click)。
  在Web中,需要将这一系列pointer给dispatch到elementtree上,通过冒泡将这些pointer频繁地发送到JS层,然后JS再通过封装TouchAPI来完成对交互的识别。这样做带来几个问题,首先频繁地将pointer从C传递到JS带来了不必要的开销,此外封装标准的能力也会造成额外的开发成本,易用性并不突出。此时,如果使用社区的一些方案,也会导致非标准化使标准不对齐导致同个应用中的不同页面有不一致的交互体验。
  为了解决上述问题,我们期望从标准化、易用性、标准化几个方面提供一套标准化的交互能力。通过封装底层的pointer来得到不同的手势能力,使开发者可以快速开发富交互的应用。
  下面是Kraken中增强交互能力的流程图。当用户进行某些交互操作以后,每一个触点的pointer会从Native传递到Kraken中,Pointer会同时分发给GestureManager(手势识别器管理类)以及Scroll识别器。GestureManager会识别开发者通过Web标准的监听行为(EventTarget。addEventListener)来注册以及分发给对应的手势识别器,同样Scroll识别器也会被分发pointer。这些识别器被加入到Flutter的竞争场进行手势竞争,以保证只触发某一个具体操作(交互可控)。Scroll识别器会触发滚动区域的滚动操作,手势识别器则会通过标准的Web流程进行冒泡以及dispatch,最终开发者通过监听事件完成自定义行为。
  开发应用时,调试能力是必不可少的,前端开发效率高不止要归功于繁荣的生态,友好的开发调试体验一样是提升效率的神器。
  Kraken抽象了Inspector以通过ChromeDevToolsProtocol来对接ChromeDevTools,提供了一系列跟前端开发Web应用完全一致的调试体验,无论开发者喜欢使用Console。log还是通过JSDebugger,都可以快速上手。
  此外,Kraken也通过支持HMR的所有标准的WebAPI,来提供局部热更新的能力,使开发kraken应用能跟Web下一致的局部热更新的调试体验,大大提升了开发者的开发调试体验。
  最后,Kraken的所有代码都已经开源,Kraken提供了开放的TSC机制期望所有开发者可以平等地交流以及决策,使Kraken可以更好地发展,也欢迎更多的开发者一起来共建Kraken。
  作者:染陌
  原文链接:http:click。aliyun。comm1000298810
  本文为阿里云原创内容,未经允许不得转载。

长辛店,工运起点,工人的胜利长辛店铁路机厂车间中国共产党成立100周年前夕,中国共产党早期北京革命活动旧址正式面向社会公众开放,其中就包括位于丰台区永定河西岸的长辛店二七纪念馆和长辛店留法勤工俭学预……能不能给孩子看屏幕?不同年龄有讲究!05岁婴幼儿发育里程碑在现在这个时代出生的孩子,可以说是土生土长的互联网原住民,手机、电视、Pad等大大小小屏幕充斥着他们的生活。有的家长把这些电子设备看作洪水猛兽,不让孩子接触;有些家长则认……战争中阵地前的尸体去哪了?都怎么处理呢?衡阳保卫战打到1944年7月16日的时候,第十军已是死伤惨重:预备第10师伤亡90、第3师伤亡70、第190师只余400人,而配属给方先觉指挥的暂编第54师只剩下一个营的兵力。……高智陪毛主席去吃饭消费6元8角,结果忘了带钱,他是如何解决的毛主席作为我国的伟大领袖,每天日理万机,当然很多事情不能全都自己一个人来完成,所以他身边也有很多助手,今天要介绍的人物就是毛主席身边的秘书高智。高智和毛主席1928……8月24日中国股市即将开盘,刚刚得知3大消息,今天行情怎么走今天是8月24日,盘后证券市场传来三则重要消息,其中百亿基金经理抛弃所有框架,什么能涨我们就买,让人哭笑不得,A股还有价值投资可言吗?短期投机氛围浓郁,万千散户该如何应对?本期……尉迟恭几次救主李世民?尉迟恭的结局如何?尉迟恭,也叫尉迟敬德,是隋末唐初的名将,他起初是隋朝官吏,后来跟随刘武周起兵,和唐朝争夺山西失败,最后投降唐朝,成为秦王李世民麾下的一员将领。尉迟恭也是传统门神之一……明末清初吴三桂为何不攻入越南自立为帝?吴三桂在云南的小日子其实非常爽,他为了向清廷表忠心,甚至连前明的永历皇帝都给诛杀了。因此康熙朝的四大辅政大臣,对吴三桂很放心,加封他为亲王,让他永镇云南。既然得了平西王的……和珅在按照皇上的旨意向灾民施米粥时,为什么向大锅里撒一把沙子看过一个段子。说有个穿着邋遢的人,进了一家面馆,问老板能不能给碗面吃?自己的钱包丢了,回不去家了,现在特别饿。老板二话没说,转身走进了厨房,不一会端来一碗面,他狼吞虎咽的就吃了……请问成语饮鸩止渴中的鸩是什么?饮鸩止渴是一句有典故的成语。这局成语的的意思就是拿毒酒当饮料來止渴,是为了解决眼前的问题而采用极其危险的方法,不要命了。饮鸩止渴这句成语本身并不难理解,而且对于这句成语的……学好C语言真的值吗?最近一个技术交流群的大一童鞋说自己正在努力学习C语言,然后遭到了一群过来人的各种建议。他们有的说C语言是上个世纪的老古董,已经被淘汰了,有的说C语言啥都干不了,只能写写打印乘法……楚虽三户,亡秦必楚,秦朝被灭以后,为何老秦人没有复国?这个事儿看起来确实挺奇怪的,关东六国在秦朝末年纷纷复国,可是在秦朝灭亡之后,老秦人却老老实实地一直服从于统治者,从三秦(雍王章邯、翟王董翳、塞王司马欣)到汉高祖刘邦,都不例外。……注意了!6月15日起,夜游黄果树实行预约分时段入园日前,小编从黄果树夜游获悉,从6月15日起,夜游黄果树实行预约分时段入园。夜游黄果树据悉,按照景区错峰开放、预约开放、有序开放的有关要求,为全面做好疫情防控管理工作……
每日一学党史学习教育(一百九十八)党史知识问答1919年5月,中国最早的马克思主义者()在《新青年》上发表《我的马克思主义观》,系统介绍了马克思主义。A。陈独秀B。李大钊C。周恩来……宫井洞事件朴槿惠之父朴正熙之死朴正熙1917年11月14日出生于庆尚北道龟尾市,幼时家境贫寒,兄弟姐妹众多,据说他的母亲怀上他的时候,并不想再要一个孩子,试了各种土办法想流产,包括喝滚烫的酱油,从山上滚下来……特伦斯戴维斯福克斯绝对是全明星,入选全明星是他应得的国王以133128击败独行侠。赛后,国王球员特伦斯戴维斯接受媒体采访,谈到了队友达龙福克斯。这就是达龙福克斯应有的表现。戴维斯在采访中表示。他绝对是全明星,入……三皇五帝是谁,神话故事里的人真的存在吗?中国有5000年的历史,从秦始皇开始,中国有407位皇帝,但我们所说的三位皇帝和五位皇帝不在407位以内。那么这三位皇帝和五位皇帝呢?既然不在皇帝之列,为什么要称之为三皇五帝?……谁是三国第一小人?我认为是吕布,张飞经常骂吕布为三姓家奴!吕布见利忘义,首根丁原,认丁原为父,董卓进京后,专横跋扈,上欺天子,下压群臣,无人敢惹。丁原看不过董卓的骄横,起兵伐卓,吕布……卫星通信企业超2。5万家竞逐万亿级大市场本报记者李玉洋李正豪上海报道虽然卫星通信早已不是新鲜事,华为和苹果的新尝试却赋予消费者一份踏实感,让这种捅破天的功能攥在消费者的智能手机里。就在华为常务董事、终端事……一文了解清朝科举制选拔考试从破蒙到状元科举在漫长的历史发展中,科举制形成了完备的考试选拔体系,最大程度地实现了文官任用机会上的平等化,其公正的选拔方式成为世界上当前最广泛的选拔方式。第一步:开笔破蒙古代科举制……小米平板5和联想小新PadPro2022怎么选择?如果只是用来视频娱乐、游戏,那么价格更便宜的小米平板5就足够了。而且小米的软件系统、手机联动,都会比联想好一些,当然只是稍稍好一点而已。看看详细参数配置对比:……韦唯向美国人普及中国春节挂红灯笼,派利是,用西式餐具吃川菜作为一个经常出现在中国乐坛的歌手,韦唯因为嫁给美国人,并且生了三个儿子,如今还定居美国,估计早就不是中国国籍了。但从韦唯分享的中国除夕夜安排来看,虽然现在美国跟中国有时差,韦唯……他是邓小平的得力助手,年逾80时,致信中央,要求停播一部电视在革命年代,有无数的先辈和烈士,为了赶走侵略者,为了建立一个新中国,抛头颅洒热血,即便是付出自己的性命也在所不惜。也正是因为他们不怕苦不怕难的精神,才能有如今的新中国。他……世界上有没有龙,东方龙和西方龙的差距在哪中国的龙文化几乎有近万年的历史,是中国文化的重要的符号。也是我国的十二生肖之一,与其它生肖不同的是龙的形象对我们来说是虚无缥缈的,只能从一些文献来拼凑其原型。出现在我国古代一些……罕见一幕!继男子3米跳板后世锦赛再次出现0分跳水,裁判羞愧捂2022年FINA世锦赛,女子3米板预赛再现0分跳水。巴西选手罗德里格斯在第四轮完成107C时出现失误,结果0分。中国队表现出色,陈榛和常占据前两名,齐头并进!这次比赛出现了尴……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网