主题
第 1 章 Kuikly 是什么 & 为什么腾讯要再造一个跨端轮子
学习目标:能用一句话向产品经理讲清楚「Kuikly 到底是个啥」;能向面试官讲清楚「为什么腾讯不直接用 Flutter / RN,要自己搞」;理解 Kuikly 三大杀手锏 —— KMP 编译、原生渲染、两棵树架构 —— 各自解决了什么痛点。
1.1 一段「家谱」:Kuikly 从哪来
1.1.1 跨端框架简史(30 秒版本)
2009 ── PhoneGap (HTML 套壳,性能拉胯) ┐
2014 ── Cordova (PhoneGap 的 Apache 版本) │
2015 ── React Native (Facebook,JS 跑动态) │
2017 ── Flutter (Google,Dart 自绘 + Skia) │ 跨端框架"风云十年"
2018 ── Weex (阿里,类 Vue 语法) │
2019 ── Taro (京东,多端小程序) │
2020 ── Compose Multiplatform (JetBrains,Compose + Skia) │
2024 ── ★ Kuikly 项目内部立项 │
2025 ── Kuikly 1.0 内部,QQ / QQ 音乐落地 │
2025-04 ── 🎉 腾讯开源 Kuikly(Apache 2.0) │
2025-09 ── Kuikly 2.5 切换到 Compose DSL 双方案 │
2026-04 ── Kuikly 2.17 稳定版 ┘1.1.2 为什么腾讯要造一个新框架?
故事是这样的:腾讯内部跨端框架早有 Hippy(基于 JS,类 RN 思路,已开源),但跨到「Android + iOS + 鸿蒙 + 小程序 + Web」5 端时,发现几个老大难:
┌────────────────────────────────────────────────────────────┐
│ 腾讯用 Hippy/RN 时的 4 大痛点 │
├────────────────────────────────────────────────────────────┤
│ 1. JS 桥接性能差 —— 列表滑动 60→45fps,动画掉帧 │
│ 2. JS 包体积大 —— iOS 安装包动辄多 5-10MB │
│ 3. 业务团队混合 Kotlin + JS + OC + 鸿蒙 ArkTS,技术栈撕裂 │
│ 4. 鸿蒙原生(ArkTS)出来后,跨端方案要适配又得重写一遍 │
└────────────────────────────────────────────────────────────┘腾讯调研了一圈现成方案:
- Flutter:性能不错,但要学 Dart;自绘体验跟原生有差异;包体大;鸿蒙支持不好
- React Native:JS 桥接性能瓶颈;新架构 Fabric 还在演进
- Compose Multiplatform:JetBrains 出品,但走自绘路线,跟 Flutter 类似的体积/体验问题
- KMP(不带 UI):只共享业务逻辑,UI 还是各端写,工作量减半但还不够
最终结论:「那不如自己造一个 —— 用 KMP 共享 Kotlin 代码 + 各端原生控件渲染」。这就是 Kuikly 的诞生背景,由腾讯前端 Oteam(公司级前端委员会)牵头,2024 年立项,2025 年 4 月开源。
1.1.3 Kuikly 名字怎么来的?
Kuikly /ˈkwɪkli/ ≈ "Quickly"
─────────────────────────────────
★ 含义:快速开发、快速渲染、快速跨端
★ Logo:彩色多边形拼接,象征"一份代码、多端拼装"📌 念出来跟英文 "quickly" 几乎一样。腾讯起名时刻意把 "qu" 改成 "Ku",避免商标冲突,同时让 K 字母呼应 Kotlin。
1.2 Kuikly 是什么:一句话讲清
Kuikly 是一个基于 Kotlin Multiplatform、面向客户端开发、采用原生控件渲染的、跨 6 端通用的 UI 框架。
这句话信息量爆表,逐词拆开看:
| 词 | 含义 | 通俗类比 |
|---|---|---|
| 基于 KMP | 用 Kotlin 多平台编译能力做底座 | 跟 Compose Multiplatform 同根 |
| 面向客户端 | 不做后端、不做桌面应用,专攻移动 + 小程序 + Web | 类似 RN / Flutter 的定位 |
| 原生控件渲染 | 不自绘,用各平台的原生 UI 控件(Android View / iOS UIView / 鸿蒙 ArkUI) | 跟 RN 一个路线,跟 Flutter 反着来 |
| 跨 6 端通用 | Android / iOS / HarmonyOS / Web / 小程序 / macOS | 一份 Kotlin 代码 → 6 个产物 |
| UI 框架 | 提供 UI 组件 + 状态管理 + 路由,不管业务架构 | 类似 Compose / SwiftUI,不像 Spring 那样大而全 |
1.2.1 它是怎么"一份代码跑 6 端"的?
┌────────────────┐
│ 你的 Kotlin │
│ 业务代码 │
│ (commonMain) │
└────────┬───────┘
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Android │ │ iOS │ │ HarmonyOS│
│ KMP 编 │ │ KMP 编 │ │ KMP 编 │
│ 译 →aar │ │译→fwk │ │译 → so │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
▼ ▼ ▼
原生 View UIView ArkUI 组件
(Android) (iOS) (HarmonyOS)
另外还有:
Web / 小程序 → KMP 编译为 .js → DOM / 小程序原生组件
macOS → KMP 编译为 .framework → AppKit关键事实:Kuikly 编译出来的产物就是各平台的"标准模块" —— Android 看到的是 .aar、iOS 看到的是 .framework、鸿蒙看到的是 .so、Web 看到的是 .js。所以接入 Kuikly 跟接入一个普通的 SDK 没区别,"跨端"对宿主 App 完全透明。
1.3 Kuikly 三大杀手锏
讲完背景,看看 Kuikly 真正"打动人心"的 3 个特性。这也是面试官最爱问的"为什么 Kuikly 比 Flutter / RN 强"。
1.3.1 杀手锏 1:KMP 编译 —— 真·原生性能
痛点:RN 的 JS 桥接
RN 渲染一帧的链路:
─────────────────────────────
[JS 引擎] ─序列化─► [Bridge] ─反序列化─► [原生 UI]
高频调用时,序列化/反序列化的开销直接打爆主线程
列表滑动 60→45fps,复杂动画卡顿明显Kuikly 怎么救你
Kuikly 渲染一帧的链路:
─────────────────────────────
[Kotlin 业务代码] ─直接函数调用─► [Kotlin 渲染层] ─直接 JNI/OC 桥─► [原生 UI]
※ 没有序列化、没有 JS 引擎、调用就是函数调用
※ Android 端是 .aar,跟你自己写的 Kotlin 代码 0 区别📌 生活化类比:RN 像「两国之间靠翻译沟通」,每说一句话都要翻译一次,沟通频繁时翻译累瘫;Kuikly 像「两个会同一种语言的人直接对话」,效率拉满。Android 上 Kuikly 编出的
.aar跟你写的 Kotlin 模块就是同一种东西。
1.3.2 杀手锏 2:原生渲染 —— 体积小、体验真原生
痛点:Flutter 的 Skia 自绘
Flutter 的"自绘渲染"代价:
───────────────────────────
1. 自带 Skia 渲染引擎,iOS 包多 6MB+,Android 多 4MB+
2. 滚动条、菜单、键盘、表单组件全是"画"出来的,跟系统原生有微妙差别
3. 无障碍、文字选择、长按弹菜单等系统能力需要重新模拟Kuikly 怎么救你
Kuikly 的"原生渲染"优势:
──────────────────────
1. 不带额外渲染引擎,Android SDK 体积 ~300KB,iOS ~1.2MB
2. 滚动条 / 菜单 / 键盘等通通是系统原生,跟手感 100% 一致
3. 无障碍、文字选择、复制粘贴 0 适配成本
4. 安装包小 = 用户下载快 = 应用商店转化率高📌 生活化类比:Flutter 像「自己带一套全套餐具去别人家吃饭」,餐具好看是好看,但占行李箱;Kuikly 像「用主人家的餐具吃饭」,就地取材,轻装上阵,吃饭手感跟主人完全一样。
1.3.3 杀手锏 3:两棵树架构 —— 比 RN/Flutter 都轻
痛点:传统跨端的"虚拟 DOM 三棵树"
RN / Flutter 的渲染流程:
─────────────────────────
业务 DSL → 虚拟 DOM 树 → Diff → 渲染对象树 → 平台原生树
(3 棵树 + 2 次 diff,开销不小)Kuikly 怎么救你
Kuikly 的渲染流程:
──────────────────
业务 DSL → BuildTree(原型树) → Diff → RenderTree(渲染树) → 直接发指令到原生
↑ ↑
Kotlin 跨平台层(90%) 各平台 Native 渲染层(10%)
★ 只有 2 棵树,O(1) 精细化 diff
★ 测量、布局都在 Kotlin 层完成(跨端一致),只把"绘制"留给原生(保留原生体验)📌 生活化类比:传统三棵树像「先把图纸画好(DOM),再画施工图(渲染对象),再交给工人(原生 View)」三道转手;Kuikly 两棵树像「画完图纸直接发指令给工人」,少一道工序、少一次失真。
1.4 Kuikly vs Flutter vs RN vs Compose Multiplatform 全方位对比
| 维度 | Kuikly | Flutter | React Native | Compose MP |
|---|---|---|---|---|
| 开发语言 | Kotlin | Dart | JavaScript | Kotlin |
| 渲染方式 | 原生控件 | Skia 自绘 | 原生控件 | Skia 自绘 |
| 平台覆盖 | Android/iOS/鸿蒙/Web/小程序/Mac | Android/iOS/Web/桌面 | Android/iOS/Web | Android/iOS/桌面/Web |
| 鸿蒙原生 | ✅ 一等公民 | ⚠️ 第三方插件 | ⚠️ 第三方插件 | ⚠️ 不支持 |
| 小程序 | ✅ 内置支持 | ❌ | ❌ | ❌ |
| SDK 体积 | 小(~300KB-1MB) | 大(4-6MB) | 中(1-3MB) | 大(4-6MB) |
| 性能 | 接近原生 | 接近原生(自绘) | 桥接性能瓶颈 | 接近原生(自绘) |
| 动态下发 | ✅ 支持 | ⚠️ 受应用商店限制 | ✅ CodePush | ⚠️ 受限 |
| 学习曲线 | Kotlin/Compose 经验秒上手 | 学 Dart 1-2 周 | 学 React 1-2 周 | 学 Compose 1-2 周 |
| Android 团队迁移 | 0 语言成本 | 要学 Dart | 要学 JS/React | 0 语言成本 |
| iOS 团队迁移 | 要学 Kotlin | 要学 Dart | 要学 JS | 要学 Kotlin |
| 生态成熟度 | 新(2025 开源) | 成熟(2017 至今) | 非常成熟 | 早期 |
| 大厂背书 | 腾讯(QQ/QQ 音乐) | Google(多个产品) | Meta(Facebook) | JetBrains |
| 国产化 | ✅ 国内大厂 | 国外 | 国外 | 国外 |
1.4.1 一段代码看尽差距
需求:写一个居中显示的 "Hello" 文本 + 一个右下角的"点击 +1"按钮,点击让计数器自增。
RN 版本(约 30 行):
javascript
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
export default function App() {
const [count, setCount] = useState(0);
return (
<View style={styles.container}>
<Text style={styles.text}>Hello {count}</Text>
<TouchableOpacity style={styles.btn} onPress={() => setCount(count + 1)}>
<Text style={{color: 'white'}}>点击 +1</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
text: { fontSize: 20, fontWeight: 'bold' },
btn: {
position: 'absolute', bottom: 30, right: 30,
width: 80, height: 80, borderRadius: 10,
backgroundColor: 'blue', justifyContent: 'center', alignItems: 'center'
}
});Flutter 版本(约 30 行):
dart
class CounterPage extends StatefulWidget {
@override _State createState() => _State();
}
class _State extends State<CounterPage> {
int count = 0;
@override
Widget build(BuildContext ctx) => Scaffold(
body: Stack(children: [
Center(child: Text('Hello $count', style: TextStyle(fontSize: 20))),
Positioned(right: 30, bottom: 30, child: GestureDetector(
onTap: () => setState(() => count++),
child: Container(width: 80, height: 80,
decoration: BoxDecoration(color: Colors.blue,
borderRadius: BorderRadius.circular(10)),
child: Center(child: Text('点击 +1', style: TextStyle(color: Colors.white)))),
)),
]),
);
}Kuikly 版本(约 25 行):
kotlin
@Page("CounterPage")
internal class CounterPage : Pager() {
private var count by observable(0)
override fun body(): ViewBuilder {
val ctx = this
return {
attr { allCenter(); backgroundColor(Color.WHITE) }
Text {
attr {
text("Hello ${ctx.count}")
fontSize(20f)
fontWeightBold()
}
}
Button {
attr {
absolutePosition(bottom = 30f, right = 30f)
size(80f, 80f)
borderRadius(10f)
backgroundColor(Color.BLUE)
titleAttr { text("点击 +1"); color(Color.WHITE) }
}
event { click { ctx.count++ } }
}
}
}
}同样需求,Kuikly 行数相当 / 略少,关键是用的是 Kotlin —— Android 团队 0 学习成本,iOS 团队也比学 Dart / JS 快得多。
1.5 Kuikly 适用场景全景图
★ Kuikly 全场景能力雷达 ★
动态化业务 ⭐⭐⭐⭐⭐
│
Android │ iOS
⭐⭐⭐⭐⭐──────┼────⭐⭐⭐⭐
│
───────── │ ─────────
│
鸿蒙业务 │ 小程序
⭐⭐⭐⭐⭐ │ ⭐⭐⭐
│
桌面 / Web
⭐⭐⭐1.5.1 主战场 1:移动 App 跨端业务
- 典型场景:电商详情页、内容类瀑布流、活动运营页面
- 优势:一份代码同时支持 Android / iOS / 鸿蒙;性能贴近原生,体积小
- 腾讯案例:QQ 群聊、QQ 浏览器小说、腾讯新闻信息流
1.5.2 主战场 2:动态化运营页面
- 优势:Kotlin 代码可编译成"动态产物"下发,类似 RN 热更新但性能更好
- 限制:iOS 端动态化需要遵守 Apple 审核策略
- 典型用法:双 11 活动页、节日皮肤、A/B 测试
1.5.3 主战场 3:鸿蒙 Next 适配
- 优势:Kuikly 鸿蒙端是官方一等公民,启动场景性能提升 20%
- 背景:HarmonyOS Next 不再兼容 Android,跨端框架是"快速适配鸿蒙"的关键路径
- 大厂选择:QQ / QQ 音乐 / 腾讯新闻已基于 Kuikly 适配鸿蒙
1.5.4 跨界场景:跨端工具 / SDK
- 典型场景:埋点 SDK、网络监控、调试工具、IM SDK 等需要多端一致性的库
- 优势:业务逻辑用 Kotlin 写一次,编译出 6 个平台的产物
1.5.5 不太适合的场景(你应该知道)
| 场景 | 为啥不适合 | 推荐方案 |
|---|---|---|
| 重度 3D 游戏 | Kuikly 不是游戏引擎 | Unity / Unreal |
| 复杂自定义动画(粒子效果、Lottie 滥用) | 原生渲染层灵活度不如自绘 | Flutter / 各端原生 |
| 后端服务 | Kuikly 是 UI 框架 | Ktor / Spring Boot |
| 桌面专业软件(Photoshop 级别) | 桌面端尚为 Alpha | Compose Desktop / Electron |
1.6 学 Kuikly 之前你需要知道的 5 件事
1.6.1 Kuikly 不是"新语言"
它是一个框架,运行在 Kotlin 之上。所有学过的 Kotlin 语法都能直接用。
1.6.2 Kuikly 跟 Compose Multiplatform 的关系
别搞混:
| 维度 | Kuikly | Compose Multiplatform |
|---|---|---|
| 渲染 | 各端原生控件 | Skia 自绘 |
| 体积 | 极小 | 较大 |
| 体验 | 真原生 | 跨端一致但与原生有差异 |
| 平台 | 6 端(含小程序、鸿蒙) | 4 端(无小程序、无鸿蒙) |
| 关系 | 可使用 Compose DSL,但底层走 Kuikly 渲染层 | 自己用 Skia 渲染 |
📌 Kuikly 2.5+ 提供了 Compose DSL,意思是你可以用 Compose 的写法(
@Composable+Modifier),但底层渲染仍然走 Kuikly 的两棵树→原生控件,不走 Skia。这是个很巧妙的设计。
1.6.3 Kuikly 的两套 DSL
| DSL | 写法 | 何时用 |
|---|---|---|
| Kuikly 自研 DSL | View { attr { } event { } } | 性能敏感、追求底层控制 |
| Compose DSL | Box(modifier = Modifier.size(...)) { } | 团队已熟 Compose、新项目 |
本笔记主讲自研 DSL(更能体现 Kuikly 设计哲学),第 4 章会简单介绍 Compose DSL 的差异。
1.6.4 Kuikly 的产物形态
┌───────────────────────────────────────────────────────┐
│ Android 端 → .aar ──┐ │
│ iOS 端 → .framework ──┤ │
│ 鸿蒙端 → .so ──┤ ─► 接入到宿主 App,跟普通 SDK 一样 │
│ Web 端 → .js ──┤ │
│ 小程序 → .js ──┘ │
└───────────────────────────────────────────────────────┘关键认知:Kuikly 不是一个独立的 App,它是一个嵌入到原生 App 里的 UI 模块。一个原生 App 可以有 0 到 N 个 Kuikly 页面,新老页面共存。
1.6.5 学完后你需要继续学的方向
┌──────────────────────────────────────────────────────────┐
│ 方向 A:Kuikly Compose DSL → JetPack Compose 进阶 │
│ 方向 B:动态化 → KSP 注解处理 + 产物分发 + 加固签名 │
│ 方向 C:鸿蒙原生 → ArkTS / DevEco Studio │
│ 方向 D:Native Module 开发 → JNI / OC 桥接 / Web 桥 │
└──────────────────────────────────────────────────────────┘1.7 章末小结
记住这张图,第 1 章你就毕业了:
★ 第 1 章核心知识图谱 ★
│
┌─────────────────────────┼──────────────────────────┐
│ │ │
┌────▼─────┐ ┌────▼──────┐ ┌────▼────┐
│ 是什么 │ │ 凭啥能赢 │ │ 适用场景 │
├──────────┤ ├───────────┤ ├─────────┤
│ KMP 框架 │ │ KMP 编译 │ │ 移动 App│
│ 6 端覆盖 │ │ 原生渲染 │ │ 动态运营│
│ Kotlin 写│ │ 两棵树架构 │ │ 鸿蒙适配│
│ 原生产物 │ │ 体积小 │ │ 跨端 SDK│
└──────────┘ └───────────┘ └─────────┘🎤 1.8 章末面试题(10 道高频题)
Q1. Kuikly 是什么?跟 Flutter / RN 的核心区别是什么?
答:Kuikly 是腾讯开源的、基于 Kotlin Multiplatform 的跨端 UI 框架,支持 Android/iOS/HarmonyOS/Web/小程序/macOS 6 端。
与 Flutter 区别:Flutter 用 Dart + Skia 自绘 渲染,Kuikly 用 Kotlin + 各端原生控件 渲染。带来的差别是 Kuikly 包体积更小(300KB vs 4MB)、用户体验更接近原生(系统组件直接复用),代价是跨端 UI 一致性需要靠"轻原生层 + 跨端组件库"来保证。
与 RN 区别:RN 用 JS Bridge 跟原生通信,频繁调用时序列化/反序列化是性能瓶颈;Kuikly 是 Kotlin 编译成各平台原生模块(aar/framework/so),调用就是普通函数调用,没有桥接开销。
Q2. 为什么腾讯不用 Flutter / RN,要自己做 Kuikly?
答:3 个原因:
- 性能要求:QQ / 浏览器等核心场景对滑动帧率、内存极度敏感,RN 的桥接成本不可接受
- 鸿蒙 Next 适配:HarmonyOS Next 不兼容 Android,国外框架(Flutter/RN)适配进度跟不上,腾讯需要自主可控的方案
- 技术栈统一:腾讯 Android 团队本来就用 Kotlin,让他们写 Dart / JS 学习成本高、招聘也难;用 Kotlin 直接复用人才
Q3. Kuikly 是怎么做到"一份代码 6 端通用"的?
答:靠 Kotlin Multiplatform(KMP) 的多平台编译能力。
业务代码写在 commonMain 目录下,KMP 编译器会针对不同目标平台生成对应产物:
- Android →
.aar(Kotlin/JVM) - iOS / macOS →
.framework(Kotlin/Native) - HarmonyOS →
.so(Kotlin/Native) - Web / 小程序 →
.js(Kotlin/JS)
各平台再有一个轻原生渲染层(core-render-android / core-render-ios 等),负责把跨端的渲染指令翻译成原生控件操作。
Q4. Kuikly 用「两棵树」是什么意思?跟 Flutter 的「三棵树」有什么区别?
答:Kuikly 的两棵树是 BuildTree(原型树) 和 RenderTree(渲染树):
- BuildTree:DSL 直接生成的"组件原型树",包含逻辑节点和布局节点
- RenderTree:从 BuildTree 中 剔除非渲染节点 后的、跟原生控件 1:1 映射的树
Flutter 的三棵树是 Widget Tree → Element Tree → RenderObject Tree,多了一层中间表示。Kuikly 通过两棵树 + O(1) 精细化 diff,实现了更轻量的渲染流程。
更关键的是:Kuikly 把测量、布局放在 Kotlin 层 完成(保证跨端一致),把绘制留给 各端 Native 层(保留原生体验),这是它"两棵树"的架构分层含义。
Q5. Kuikly 的 attr 和 event 为什么要分开?
答:3 个原因:
- 职责清晰:
attr描述视觉(样式 + 布局 + 数据),event描述交互,DSL 一眼就能扫出"长啥样"和"会响应啥" - 响应式追踪精度:把
attr单独建块,可以精确追踪哪些响应式字段被属性引用,更新时只刷该属性,不重建整个组件 - 渲染指令拆分:
attr内的属性变更直接映射成"setProp"指令;event监听器映射成"addEventListener"指令;分开方便底层渲染引擎做指令合并和批量更新
对比 Compose 的 Modifier 链式:Compose 把样式、布局、事件全塞进 Modifier,写起来流畅,但底层 diff 难度更大(Compose 内部其实也做了不少优化才达到现在的性能)。
Q6. Kuikly 的 SDK 体积为什么这么小(Android ~300KB)?
答:核心原因是 不带渲染引擎。
Flutter 要带一份 Skia 渲染引擎(>5MB),自己画所有像素。Kuikly 直接复用各平台已有的原生 UI 系统(Android 的 View、iOS 的 UIView 等),渲染层只负责"翻译指令",所以非常轻。
300KB 主要包含:
- core 跨平台逻辑(DSL 解析、两棵树管理、布局算法)
- core-render-android(原生渲染层)
- 必要的 Kotlin 标准库依赖
Q7. Kuikly 自研 DSL 和 Compose DSL 怎么选?
答:
| 选 Kuikly 自研 DSL | 选 Compose DSL |
|---|---|
| 性能敏感(首屏、列表、动画) | 团队已熟 Compose |
| 需要细粒度控制渲染指令 | 新项目,未来想跟 Android Compose 共享代码 |
| 包体敏感 | 享受 Compose 庞大组件生态 |
| 老项目从 Hippy 迁移 | 写法更"现代",函数式风格强 |
重要事实:两种 DSL 底层都走同一个 Kuikly 渲染引擎,最终产物都是原生控件。你可以在同一个工程里混用:核心页面用自研 DSL(追求性能),运营页面用 Compose DSL(追求开发效率)。
Q8. Kuikly 怎么做动态化?跟 RN 的 CodePush 有什么区别?
答:Kuikly 通过 KMP + 产物拆分 实现动态化:
- 业务 Kotlin 代码可以编译成"动态产物"(如 Android 上的 dex、iOS 上需要解释执行)
- 客户端启动时从 CDN 拉取产物,加载执行
- 框架 SDK 部分仍然在宿主 App 内(保证基础能力稳定)
与 CodePush(RN)的区别:
- RN 下发的是 JS bundle,本身就是"解释执行"的,动态性好但性能差一点
- Kuikly 下发的是更接近编译产物的二进制,性能更好,但 iOS 端因为 Apple 审核政策,动态化能力受限(具体方案在第 9 章详细讲)
Q9. Kuikly 适合什么场景?什么场景不适合?
适合:
- 移动 App 跨端业务(Android + iOS + 鸿蒙)
- 动态化运营页面(电商详情、活动页)
- 内容信息流(瀑布流、长列表)
- 需要"跨端一致 + 接近原生体验"的所有场景
不适合:
- 重度 3D 游戏(用 Unity / Unreal)
- 复杂帧动画 / 粒子效果(自绘框架更灵活)
- 桌面专业软件(Kuikly macOS 端尚为 Alpha)
- 后端服务(Kuikly 是 UI 框架,写后端用 Ktor / Spring Boot)
Q10. 学 Kuikly 之前最好先具备哪些基础?
答:按重要性排序:
- Kotlin 基础(必备):变量、类、Lambda、扩展函数、数据类、空安全
- Android 开发基础(强烈推荐):能跑通一个 Android 项目,理解 Activity、布局
- Gradle 基础(推荐):看得懂
build.gradle.kts,会改依赖 - Compose 经验(加分项):理解声明式 UI 心智模型,学 Kuikly 飞起
- iOS / 鸿蒙 / Web 经验(按需):要做对应端就要补对应端的工程化知识
完全零基础?建议先看本仓库的 kotlin/ 笔记,别上来就直接学 Kuikly,会被 DSL + KMP + Gradle 三连打懵。
下一站 → 第 2 章 · 环境搭建 & Hello Kuikly →
🎬 可视化演示
演示加载缓慢或样式异常?点此在新标签页打开 ↗
💻 示例代码
markdown
# 跨端方案速查表(Kuikly vs Flutter vs RN vs Compose MP)
打印出来贴墙上,面试 / 选型时用。
## 1. 一句话定位
| 框架 | 定位 |
|------|------|
| **Kuikly** | 腾讯 · Kotlin + 原生渲染 · 6 端通用 · 包小性能强 |
| **Flutter** | Google · Dart + Skia 自绘 · UI 一致性强但包大 |
| **React Native** | Meta · JS + 原生渲染 · 生态成熟但桥接性能瓶颈 |
| **Compose Multiplatform** | JetBrains · Kotlin + Skia 自绘 · 跟 Compose 同语法 |
## 2. 渲染路线对比RN: DSL → 虚拟 DOM → JS Bridge → Native View 3 棵树 + 2 次序列化
Flutter: DSL → Widget → Element → RenderObject → Skia 自绘 自带画笔,跟系统原生有差异
Compose MP: DSL → Composable Tree → Layout → Skia 自绘 自带画笔(同上)
Kuikly: DSL → BuildTree → RenderTree → 直接发指令到 Native View 2 棵树,无桥接,原生体验
## 3. 关键指标对比表
| 指标 | Kuikly | Flutter | RN | Compose MP |
|------|--------|---------|-----|-----------|
| 启动速度 | 快 | 中 | 中 | 中 |
| 滑动帧率 | 接近原生 | 接近原生 | 中(桥接瓶颈) | 接近原生 |
| 内存占用 | 低 | 中 | 中 | 中 |
| iOS 包体增量 | ~1.2MB | ~6MB | ~3MB | ~6MB |
| Android 包体增量 | ~300KB | ~4MB | ~2MB | ~4MB |
| 学习曲线(已会 Kotlin) | 低 | 高(学 Dart) | 高(学 JS) | 中 |
| 生态成熟度 | 新 | 高 | 非常高 | 中 |
| 招聘难度 | 较难(新框架) | 易 | 易 | 中 |
## 4. 选型决策树你的团队主语言是什么? ├── Kotlin / Android │ ├── 性能极致,包体敏感 → ★ Kuikly │ ├── UI 想完全一致,无所谓包大 → Compose MP │ └── 已有大量 Compose 代码想复用 → Compose MP ├── JavaScript / 前端 │ ├── 已有 React 项目 → RN │ └── 全新项目 → 看团队意愿(学 Kotlin 选 Kuikly,留 JS 选 RN) ├── 不限语言,看效果 │ ├── 优先 UI 一致性 → Flutter │ ├── 优先原生体验 → ★ Kuikly 或 RN │ └── 必须支持鸿蒙 → ★ Kuikly(其他框架鸿蒙支持都不好)
## 5. 大厂用谁
| 公司 | 用什么 |
|-----|-------|
| 腾讯 QQ / 浏览器 / 音乐 | Kuikly |
| Google Pay / Stadia | Flutter |
| Meta / Facebook / Instagram | RN |
| 字节跳动 / 抖音 | Lynx(自家) + RN |
| 阿里 / 钉钉 | Weex / Flutter |
| 美团 | RN + Picasso(自家) |
| 京东 | Taro(小程序)+ RN |
| 携程 | Flutter + RN |
## 6. 一段话面试模板
> 「跨端框架可以分两类:**自绘派**(Flutter、Compose MP)和**原生派**(RN、Kuikly)。自绘派用统一渲染引擎画像素,跨端一致性强但包体大、跟系统原生有差异;原生派用各端原生控件,包体小、体验真原生,但需要解决跨端 UI 一致性问题。
>
> Kuikly 是腾讯开源的原生派代表,核心创新有三点:第一,基于 KMP 编译,业务代码用 Kotlin 写一份,编译出 6 个平台的原生产物;第二,两棵树架构(BuildTree + RenderTree),相比 Flutter/RN 的三棵树更轻量;第三,把测量布局放在 Kotlin 层(保证一致),把绘制留给 Native(保留体验),这是它'轻原生层'的设计精髓。」kotlin
/**
* 第 1 章配套代码 · Hello Kuikly 最小示例
*
* 这是一个最小可运行的 Kuikly 页面。先看一眼整体结构,理解每一部分是干啥的,
* 不需要完全看懂细节 —— 后面 3、4、5 章会逐个拆开讲。
*
* 文件应放置在你的 KMP 工程 `commonMain/kotlin/com/example/` 目录下。
*/
package com.example.kuikly.demo
import com.tencent.kuikly.core.annotations.Page
import com.tencent.kuikly.core.base.Color
import com.tencent.kuikly.core.base.ViewBuilder
import com.tencent.kuikly.core.pager.Pager
import com.tencent.kuikly.core.reactive.handler.observable
import com.tencent.kuikly.core.views.Button
import com.tencent.kuikly.core.views.Text
/**
* @Page 注解:把这个类注册成一个可以被路由的页面。
* - "HelloKuikly" 是页面名字,宿主 App 通过这个名字跳转到本页面
* - KSP 在编译期会扫描所有 @Page 注解,自动生成路由注册代码
*/
@Page("HelloKuikly")
internal class HelloKuiklyPage : Pager() {
/**
* 响应式字段:每次 +1 都会触发 UI 自动更新,不需要手动刷新。
* `by observable(0)` 让 count 这个变量"被监听",谁读它谁就被自动追踪。
*/
private var count by observable(0)
/**
* body() 是 Pager 必须实现的方法,返回一个 ViewBuilder 闭包。
* ViewBuilder 描述了"页面长什么样",Kuikly 引擎会按这个描述渲染。
*/
override fun body(): ViewBuilder {
// 把 this 存成 ctx,方便在闭包里访问页面的字段(这是 Kuikly 的常见写法)
val ctx = this
return {
// 整个页面的根布局属性
attr {
allCenter() // 所有子组件居中
backgroundColor(Color.WHITE)
}
// 文本组件:显示当前计数
Text {
attr {
text("Hello Kuikly! 计数: ${ctx.count}")
fontSize(20f)
fontWeightBold()
color(Color(0xFF7F52FFL)) // Kotlin 紫
}
}
// 右下角的按钮
Button {
attr {
absolutePosition(bottom = 30f, right = 30f)
size(80f, 80f)
borderRadius(10f)
backgroundColor(Color.BLUE)
titleAttr {
text("点我 +1")
fontSize(14f)
color(Color.WHITE)
fontWeightBold()
}
}
event {
click {
// 点击 → count + 1 → Text 自动重新渲染
ctx.count++
}
}
}
}
}
}