二手钢结构新闻
Kuikly跨端开发框架:适配鸿蒙,提升腾讯多端业务开发效率
2025-06-08 13:04  浏览:136

一 背景

Kuikly 是腾讯广泛采纳的跨平台开发框架,依托 Kotlin Multiplatform 技术,构建而成,旨在为开发者带来更加统一的跨平台开发体验,并由腾讯公司内部的大前端团队 Oteam(公司级别)负责推出。基于Android和iOS的开源框架,此次开源的鸿蒙操作系统平台新增了对Compose DSL的支持,这有效地增强了业务在不同平台间的适配能力,并提高了鸿蒙系统的开发效率。目前,Kuikly的鸿蒙版本已经整合了腾讯的多项业务,成功开发并发布了多个鸿蒙应用,包括QQ浏览器、腾讯新闻、搜狗输入法、全民K歌以及自选股等。

二 鸿蒙效果适配方案

Kuikly将高性能与动态化作为其框架的核心追求。自鸿蒙Next系统发布以来,Kuikly迅速展开了适配工作。得益于其轻量级的渲染架构设计,初版很快便告完成。经过不断的迭代与精心优化,Kuikly的鸿蒙版本实现了全面适配,并展现了与原生相媲美的性能表现。

实测数据如下:

测试环境涉及一个结构相对复杂的Feed流系统,且所使用的设备型号均为华为Mate60。

在鸿蒙平台上,Kuiky打开页面速度比RN快6倍:

图片

Kuikly的鸿蒙版本在性能上与Android版本相媲美,其启动速度与原生版本几乎持平。

图片

三 总体适配方案1、Kuikly架构回顾和优势

Kuikly是一款多端兼容、追求卓越性能、具备动态特性及原生级体验的开发框架。在技术层面,它以Kotlin Multiplatform为基础,有效解决了以往跨端框架中普遍存在的性能、体验与原生应用不一致以及开发环境的问题;在设计理念上,Kuikly将逻辑实现尽可能集中在Kotlin的跨端部分,从而使得原生侧的逻辑实现更加轻巧高效。

Kuikly包括两部分:

KuiklyUI平台提供业务功能,支持用户使用自主研发的领域特定语言(DSL)以及Compose DSL进行用户界面(UI)的跨平台开发。它采用了轻量级和原生渲染技术,并且能够实现页面级别的动态化处理。

Kuiklybase平台提供全面跨端的基础功能与设施,涵盖UI界面和KMP逻辑的全面支持,拥有多样化的跨端组件,以及一套完整的调试、构建、发布和监控工具链,并具备强大的稳定性监控能力。

Kuikly框架优势:

一码五端,兼容Android、iOS、HarmonyOS、网络版以及小程序五大平台(其中网络版和小程序计划于第二季度开放源代码)。

得益于KMP的跨平台特性,Kuikly能够将Kotlin代码编译成不同平台的原生产物,因此实现了与原生平台几乎相同的执行性能体验。

Kotlin语言作为驱动,打造了纯原生的开发工具链;该工具链支持复用Android Studio或VS Code等原生IDE以及性能分析工具;它贯穿业务代码至框架代码的各个层级;通过统一的技术栈,我们得以完成开发、调试以及性能分析的任务;最终,实现了框架开发技术栈的闭环。

本产品采用自研的声明式与响应式领域特定语言,显著提高了用户界面设计的开发速度。此外,Compose DSL亦同步发布了开源的Beta版本。

页面级动态化得到支持:可灵活运用内置及动态化模式,确保运行稳定且高效;在Android平台,动态化模式依托平台特性,实现性能损耗极低,即便在配置较低的中低端设备上,也能展现出与原生应用相近的流畅度。

轻量级、稳定且易于维护:该框架的整体设计巧妙,不依赖复杂的外部元素,因而具备较高的稳定性、可控性以及维护便捷性。

2、总体适配方案概述

Kuikly鸿蒙系统的适配过程既繁杂又系统化,而且为了实现高性能、原生级渲染以及动态化等多重适配目标,我们一直在不懈地进行探索与不断优化。核心适配任务涵盖:与鸿蒙用户界面系统相连接,对基础组件进行封装,与事件管理系统对接,对性能和稳定性问题进行优化与解决;将Kotlin跨平台层的逻辑编译成鸿蒙平台高效运行的本地化产品,研究Kotlin Javascript和Kotlin Native在鸿蒙平台上的适配实施及其性能提升;实现跨平台层与鸿蒙原生层之间的互操作路径,并确保框架及应用程序的整体运作;构建调试插件和崩溃监控等开发与运营阶段所需的基础设施。

限于本文篇幅无法一一介绍,本文将选取部分核心工作进行展开。

四、关于渲染层的适配问题1、在ArkUI中的渲染指令映射问题a)原本的疑问:如何通过声明式接口实现渲染指令的映射

在Android和iOS系统中,均设有命令型用户界面接口,此类接口与Kuikly的渲染层抽象理念相契合,能够直接调用系统接口以操作原生控件。但鸿蒙系统的用户界面则采用声明式的ArkUI进行编写,其UI组件由数据与界面描述构成,而界面的更新则需通过调整其关联的数据来完成。渲染层如何激发声明式的ArkUI发展,成为了适配鸿蒙系统的首要挑战。

b)初步解决方案:统一Builder入口,全量属性绑定

经过一系列的探索尝试,我们全新设计了鸿蒙版的渲染层方案:

组件属性的调整涉及在渲染层对渲染节点的数据模型进行管理,这些节点与 ArkUI 组件通过装饰器机制实现关联。通过这种方式,对渲染节点属性的添加、删除或修改操作,将直接导致 UI 属性的相应更新。

UI树的构建与维护过程中,我们采用了名为ForEach的循环渲染接口,该接口允许绑定数组类型的数据,进而生成子UI元素。我们通过将渲染节点的数据抽象化,形成节点树结构,并以节点的子节点作为数据来源,结合ArkUI的递归构建方法,成功实现了对整个UI树的详细描述以及增删改操作。

c)新的问题:声明式接口映射方案性能不理想

在运用ArkUI声明式UI技术实现功能的过程中,我们迅速完成了首个版本的发布。然而,性能评估的结果并未达到预期目标,其背后的原因主要包括:

组件外层属性一旦设定,便会使其实际层级增加一倍,从而对性能产生不利影响;

由于无法根据需求进行属性绑定,我们只能对全部属性进行统一设置,因此,对某个对象的修改可能会引发所有属性的全面更新。

尽管借助组件的便利性有限,这是因为准备组件复用时所需的调用时间可能成为制约因素。

Kotlin JS转鸿蒙字节码模式效率不高。

d)终极解决方案:采用命令式CAPI实现指令的映射

重新审视先前的Android和iOS实现案例,可以发现,处理渲染指令的最理想途径是采用命令式接口。在与鸿蒙系统端的交流后,我们获得了体验版的API。经过深入调查,我们了解到其性能优势显著:采用C风格的API实际上更符合Kuikly的使用需求,而且其运行效率更高,并且能够与Kotlin Native直接调用,无需额外的虚拟机或语言转换开销。尽管早期CAPI版本存在若干缺陷以及功能上的不足,且其开发过程更为艰难,复杂度也较高,然而,鉴于对极致性能的追求,我们最终还是选择了CAPI方案。

新旧方案渲染层级变化:

2、C节点和ArkTS组件嵌套问题

在实际的业务应用中,常常会遇到自定义控件与Kuikly自带的控件相互混合并嵌套使用的情况,具体表现为C节点与ArkTS组件的混合嵌套。鉴于ArkTS组件均为声明式设计,在早期阶段,并未有相应的策略来动态地为它们添加C节点的子节点,因此,直接解决这种混合嵌套的问题变得十分困难。

解决:影子节点无痛兼容现有组件,内容插槽方案兜底

CAPI命令式接口具备为C节点增添C子节点的功能,同时亦能在C节点之上附加ArkTS节点作为其子节点。鉴于此,我们精心设计了一套规避直接对ArkTS节点执行操作的手段,旨在有效解决嵌套所带来的问题。

我们首先引入一个与业务自定义组件面积相等的C类影子节点,并将基础属性自动赋予该节点,并同步传递给业务自定义组件;随后,在需要为业务自定义组件添加子节点时,只需将子节点附加至影子节点上,从而在视觉上达到预期的效果。

这种方式能够完美地处理嵌套问题,其优势在于无需任何修改即可无缝地与业务中现有的组件以及第三方组件实现兼容,然而,它的一个缺点在于,实际上将原本应该存在父子关系的自定义节点及其子节点转变为了兄弟节点关系,这样一来,当业务需要对自定义节点执行特定的操作,比如进行transform操作时,就很容易引发UI显示上的异常。

自鸿蒙API 12版本发布以来,我们对其功能进行了扩展,新增了对自定义节点内容插槽的兼容性。在业务需求特殊的情况下,用户可依据既定规范在自定义组件中增设内容插槽。采用此模式时,系统将不会自动创建影子节点,同时子节点也将被附加到相应的插槽中,确保UI树与预期效果保持一致。

文本渲染效能的提升,首先采用了创新的方法:将文本的测量与渲染过程分离开来。

鉴于我们最终选择了CAPI作为方案,因此此处不再详细阐述基于ArkTS接口的文本展示方法。

在CAPI版本里,我们首次尝试了将文本的测量与渲染过程分开,具体来说,在测量环节,我们仅将文本的大小数据应用于整体布局的计算;而在渲染环节,则直接运用了鸿蒙系统的文本控件来完成渲染任务。

在性能分析中,我们发现当List滚动时,文本测量所耗费的时间超过了父容器(即List)布局时间的50%以上。这种情况显然不符合预期,因此我们必须寻求一种方法来复用文本布局阶段的结果,以防止在上屏时再次进行布局操作。

腾讯Kuikly框架鸿蒙版正式开源 —— 揭秘卓越性能适配之旅_腾讯Kuikly框架鸿蒙版正式开源 —— 揭秘卓越性能适配之旅_

b)初步优化方案:部分复用布局产物

鸿蒙API 12版本的发布,引入了全新的文本渲染功能,这一功能不仅允许我们在文本布局完成后,除了利用文本尺寸信息外,还能保留布局过程中的中间结果。这一特性为提升文字渲染性能带来了新的可能性。针对此,我们进行了实践和测试,结果显示性能得到了显著提高,然而,二次布局的问题依然存在。

c)最终方案:利用系统提供的文本绘制能力按需绘制

我们转而采用直接调用系统文本绘制接口的方法来实施绘制计划,此方案在先前版本的基础上进行了深化,并对布局结果进行了二次利用。经过详尽的分析,我们确信该方案已完全解决了文本重新布局的问题。综合比较之前提出的多个方案,在上屏阶段进行文本布局所耗费的时间:

系统API根据需求绘制的方案展现了令人满意的性能。此外,我们还完善了无障碍访问功能、调整了局部背景色彩、实现了子串区域的点击回调响应,并增强了系统文本控件的对齐功能。

4、其他典型性能和稳定性问题a)高频节点创建和释放性能问题

在处理长列表或类似极端情况时,频繁的节点创建与销毁操作会消耗大量时间,且在渲染过程中也构成了不小的负担。鉴于此,为了达到性能的极致优化,我们采纳了节点复用的策略。

在节点复用过程中,我们遭遇了节点属性难以恢复、重置操作导致崩溃等问题。为了实现较高的节点复用率与系统稳定性,我们制定了以下复用方案:在节点层面,我们引入了白名单制度,将部分常用节点纳入复用白名单;在节点属性层面,我们实施了黑名单制度,将那些无法恢复的属性排除在外,确保它们不会进入节点复用池。

b)稳定性优化

采用CAPI方案后,开发过程中的难度和复杂度显著提升,且在适配阶段频繁遭遇稳定性难题。这些问题的诊断与解决均需付出较高的成本。

在早期版本中,当XComponent面临频繁创建与销毁场景时,我们遭遇了高频率的崩溃问题;此外,一些系统接口,如系统日志打印接口、节点ID读取接口等,也较易被误用而引发崩溃。幸运的是,这些问题在后续的迭代开发中均得到了妥善的解决。经过一年多时间的线上多业务验证,该产品的Crash率始终保持在较低状态,其稳定性得到了充分保障。

五 Kuiklybase适配鸿蒙平台

为了助力Kuikly及其业务顺利适配鸿蒙系统,Kuiklybase进行了功能升级,强化了对鸿蒙系统的兼容性。这一升级涵盖了Kotlin Native技术、跨端组件的兼容以及一系列基础设施的适配。

1、Kotlin Native鸿蒙适配

在项目初期阶段,我们迅速对Kotlin JS开发模式进行了测试,但发现其性能表现并不符合我们的预期需求。

Kotlin官方的基准测试结果显示,原生代码的性能比Javascript高出950%,性能差距显著,并且无法通过系统AOT编译来缩小这一差距。

在鸿蒙系统上采用Kotlin JS开发模式存在不少局限,例如它不具备多线程处理能力,无法实现真正的并行执行;JS代码的执行必须依赖于worker,这导致内存隔离对性能产生了较大影响;此外,Kotlin代码转换为JS后,数值计算效率较低。相较之下,Kotlin Native模式则不存在这些问题。

解决方案:

鸿蒙平台对Kotlin Native的适配涉及编译阶段与执行阶段的双重任务,以对象生成过程为实例,可以更深入地掌握这两个阶段的特点。

编译期的适配

Kotlin 1.9.x版本采用了LLVM 11,而Kotlin 2.1版本则升级至LLVM 16。不过,在鸿蒙平台上,所支持的LLVM版本范围是12到15。苹果和鸿蒙系统均基于同一公共版本的LLVM进行了定制,并各自添加了特有的功能和优化。苹果的优势之一是,其公共版LLVM中内置了苹果的target,因此,鸿蒙版的LLVM不仅能够兼容iOS系统,还能同时支持鸿蒙操作系统。

常规的Kotlin适配方法涉及利用鸿蒙系统和苹果的LLVM编译器分别进行编译。此方法的优势在于易于修改,且不会出现兼容性问题。然而,由于Kotlin本身不兼容多个LLVM架构,因此在鸿蒙平台和iOS平台上分别编译Kotlin时,必须依赖不同的Kotlin版本。

Kuiklybase方案中,第一步将Kotlin的中间表示(IR)转换为LLVM IR时选用苹果的LLVM 11版本,而在生成可执行文件的过程中,则采用了鸿蒙系统的LLVM 12版本。这样的做法既能够满足需求,同时也不需要对Kotlin进行架构上的调整。

运行时的适配和优化

_腾讯Kuikly框架鸿蒙版正式开源 —— 揭秘卓越性能适配之旅_腾讯Kuikly框架鸿蒙版正式开源 —— 揭秘卓越性能适配之旅

为Kotlin Native拓展兼容鸿蒙系统的互操作文件,实现与系统API的对接,并对运行时中的架构和平台相关判断逻辑进行优化调整,确保对鸿蒙平台提供全面支持。

在完成初步适配环节后,我们借助Kotlin官方的Benchmark工具进行了性能对比测试,结果显示,在鸿蒙系统上运行的时间是相同性能的iOS设备上的2.48倍。针对这一情况,我们针对鸿蒙平台实施了一系列优化措施,涵盖了内联优化、ThreadLocal优化以及协程性能的改进等方面。经过优化,鸿蒙系统的Kotlin Native性能实现了显著增长,增幅达到数倍,完全达到了产品实际应用的标准。此外,针对这一领域的适配与改进工作,我们将在后续的独立文章中提供更为详尽的阐述。

调试效率的提升:借助插件,鸿蒙集成开发环境得以实现Kotlin语言的调试功能。

在鸿蒙集成开发环境(IDE)中应用Kotlin Native技术时,调试过程遭遇了显著的挑战,尤其是调试困难。虽然可以利用Kotlin官方的LLDB插件来尝试解决这一问题,但该插件在变量查看方面的效率极低,几乎处于无法使用的状态。

为了提升效率并确保其可用性,我们对Kotlin的调试插件及其相关运行时进行了优化处理。我们增强了调试信息的复用和缓存功能,并实现了调用合并、信息预加载等改进措施。这些优化使得插件的速度提升了40倍,从而使其从原本几乎无法使用转变为基本能够满足日常开发调试的需求。

调试功能一旦投入使用,却发现操作难度较大,对鸿蒙集成开发环境(IDE)的配置要求复杂,必须进行一系列手动调整。设置断点前,还需在文件系统中搜寻源代码文件,并将其拖拽至鸿蒙IDE中打开,方能进行断点配置;或者,选择更为复杂的命令行方式来设置断点。

因此,我们为鸿蒙IDE量身打造了一款自动化调试插件,该插件可自动完成调试设置并同步产物代码。用户只需切换至Kuikly界面,即可直观地查看项目中的SO产物及其相关文件。在此界面双击文件即可打开,无需手动拖拽至鸿蒙IDE,显著提升了日常调试的便捷性与效率。待该工具在内部经过更广泛的测试与确认,我们将着手将其推广至鸿蒙IDE的插件平台,以回馈广大开发者社区。

六 ComposeDSL Beta版本发布

依托于Kuikly的核心架构以及通用的渲染技术,我们对标准的Compose DSL进行了更深入的兼容性扩展,目前这一Beta版本已经正式推出。通过增强对Compose DSL的支持,Kuikly能够有效减少客户端开发的入门难度,其显著优势主要体现在:

Kuikly Compose得益于对Kuikly通用渲染层的复用,不仅兼容标准Compose DSL语法,还能实现与Android、iOS、HarmonyOS、Web等主流平台的完美适配,甚至涵盖国内流行的小程序平台,从而显著增强了应用的广泛覆盖和易用性。

在 Kuikly 跨端框架的基础上,我们对其进行了扩展,加入了 Compose DSL 的支持。这样一来,Kuikly Compose 就自然拥有了 Kuikly 所具备的动态化功能,涵盖了热更新、动态下发等众多特性。

Kuikly Compose 与官方 Compose 的自渲染模式不同,它继承了 Kuikly 的原生渲染特长,确保了在各种平台上都能提供高效且原生级别的用户界面体验。

关于ComposeDSL支持详情,可查阅官方文档

与ovCompose的差异

这两个框架在渲染技术、动态功能支持、性能展现以及跨平台兼容性方面各有其独特之处。为了适应不同业务场景的多样化需求,腾讯大前端Oteam团队正同时深入探索两种不同的方案。

KuiklyUI原生渲染方案,强调静态与动态的双重运行机制,通过轻量级原生渲染技术,确保用户界面体验的原始性和高度统一性。此外,该方案还基于原生组件的映射方式,对Compose API提供支持,并且兼容H5和小程序平台(预计6月底正式推出)。

ovCompose自渲染方案致力于与Compose Multiplatform标准API的全面契合,通过自渲染技术为鸿蒙平台提供适配,以此保障三端在用户体验上的高度统一。同时,考虑到iOS平台上大量现存的业务需求,该方案还特别提出了适用于多模态的渲染策略,旨在有效解决UI元素混排的问题。

七 技术展望

鸿蒙系统正处于快速发展的阶段,我们对此持续保持高度关注,并持续致力于为鸿蒙系统提供优良的适配服务。

Kotlin Native的垃圾回收算法目前仍有较大的提升潜力,未来将继续努力,力求在性能上与Java的GC相媲美。

目前调试工作主要依赖鸿蒙IDE完成,未来计划是,要么在Android Studio中引入KMP插件,要么为其添加一个专门支持鸿蒙的插件,以实现Android和iOS在Android Studio中开发调试体验的统一。

我们热切期望社区中的杰出开发者们能够踊跃加入,携手共创一个:跨平台、操作简便、适应性强的高性能开发框架体系。

立即体验 Kuikly,加入开源社区。

GitHub 仓库 |  官方文档

欢迎关注