Skip to content

第 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 全方位对比

维度KuiklyFlutterReact NativeCompose MP
开发语言KotlinDartJavaScriptKotlin
渲染方式原生控件Skia 自绘原生控件Skia 自绘
平台覆盖Android/iOS/鸿蒙/Web/小程序/MacAndroid/iOS/Web/桌面Android/iOS/WebAndroid/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/React0 语言成本
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 级别)桌面端尚为 AlphaCompose Desktop / Electron

1.6 学 Kuikly 之前你需要知道的 5 件事

1.6.1 Kuikly 不是"新语言"

它是一个框架,运行在 Kotlin 之上。所有学过的 Kotlin 语法都能直接用。

1.6.2 Kuikly 跟 Compose Multiplatform 的关系

别搞混

维度KuiklyCompose 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 自研 DSLView { attr { } event { } }性能敏感、追求底层控制
Compose DSLBox(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 个原因:

  1. 性能要求:QQ / 浏览器等核心场景对滑动帧率、内存极度敏感,RN 的桥接成本不可接受
  2. 鸿蒙 Next 适配:HarmonyOS Next 不兼容 Android,国外框架(Flutter/RN)适配进度跟不上,腾讯需要自主可控的方案
  3. 技术栈统一:腾讯 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 个原因:

  1. 职责清晰attr 描述视觉(样式 + 布局 + 数据),event 描述交互,DSL 一眼就能扫出"长啥样"和"会响应啥"
  2. 响应式追踪精度:把 attr 单独建块,可以精确追踪哪些响应式字段被属性引用,更新时只刷该属性,不重建整个组件
  3. 渲染指令拆分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 之前最好先具备哪些基础?

:按重要性排序:

  1. Kotlin 基础(必备):变量、类、Lambda、扩展函数、数据类、空安全
  2. Android 开发基础(强烈推荐):能跑通一个 Android 项目,理解 Activity、布局
  3. Gradle 基础(推荐):看得懂 build.gradle.kts,会改依赖
  4. Compose 经验(加分项):理解声明式 UI 心智模型,学 Kuikly 飞起
  5. 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++
                    }
                }
            }
        }
    }
}

CrossPlatformComparison.md ↗ · HelloKuikly.kt ↗