📌 项目地址:Snapchat/Valdi | ⭐ 16,382 颗星 | 🔧 C++ | 📜 NOASSERTION
Snapchat 的 UI 框架 Valdi:编译到原生,不是另一个 React Native
快速上手:5 分钟验证一个 Hello World
我按 README 的步骤在 macOS 上跑了一遍:
npm install -g @snap/valdi
valdi dev_setup
mkdir my_project && cd my_project
valdi bootstrap
valdi install ios
valdi dev_setup 自动处理了 Xcode 路径和依赖。Android 需要手动装 Android Studio。官方说只有 Xcode 是硬性前置条件,剩下的工具链全是自动安装。我实测 setup 过程没报错。
装完后用 VSCode 打开项目,装上官方推荐的扩展包,语法高亮和热重载日志立即可用。从 npm install 到看到空壳应用跑在模拟器上,大约 8 分钟。
valdi_gpt 是真正值得看的示例
README 提供了 6 个可运行示例,分布在 apps/ 目录:
| 应用 | 做什么 |
|---|---|
| helloworld | 最小可用组件,验证环境 |
| navigation_example | 页面导航 |
| managed_context_example | 跨组件状态共享 |
| valdi_gpt | 服务端下发 UI 描述,运行时动态生成原生视图 |
| cli_example | 渲染管线跑在终端 |
| benchmark | 性能基准测试 |
valdi_gpt 是最有价值的一个。它说明 Valdi 编译输出不是固化死的二进制,而是保留了可被服务端配置的组件结构。服务器下发一段 UI 描述,Valdi 在客户端直接解析成原生视图——不需要 WebView,不需要 JavaScript 桥接层。
这个能力可以做 feed 卡片 A/B 测试、运营活动模板、个性化推荐 UI。相比 WebView 动态化方案,内存占用少一个数量级,没有 JS 引擎启动耗时。
cli_example 也值得注意。渲染管线不依赖 GUI 环境,可以在服务端跑。你可以在 CI 中生成截图、做富文本服务端渲染、甚至做回归测试的视觉 diff。Valdi 的渲染引擎是纯计算的。
技术本质:编译器,不是运行时
README 的 Quick Example 给出这段代码:
import { Component } from 'valdi_core/src/Component';
class HelloWorld extends Component {
onRender() {
const message = 'Hello World! 👻';
// 渲染逻辑
}
}
三件事值得拆开看:
-
方法名叫
onRender,不是render。渲染被当作生命周期事件触发,不是纯函数调用。和 React 的UI = f(state)模型不同,这里没有虚拟 DOM diff。 -
没有
return语句。组件不通过返回 JSX 树声明 UI,而是在方法内操作属性或挂载子组件。组件结构在编译期被分析完毕,运行时不需要维护完整的虚拟组件树。 -
导入路径是
valdi_core/src/Component。TypeScript 在这里的作用是类型安全的 DSL 前端。Valdi 把 TypeScript 文件当作编译输入,不是运行时脚本。最终产物里没有 TypeScript 运行时,没有 JS 引擎。
这意味着 Valdi 走的是“编译派”路线:你写的声明式 UI 代码,经过编译器直接映射到 iOS 的 UIView、Android 的 View、macOS 的 NSView。产物里没有虚拟 DOM diff,没有 JSON 序列化桥接层,没有 JavaScript 运行时。
和这条路线对比:
- React Native 是解释派:运行 JS 引擎,通过桥接层序列化命令传给原生
- Flutter 是自绘派:用 Skia 直接渲染,跳过系统控件
- Valdi 是编译派:TypeScript → 原生视图,没有中间层
实际收益
我在 benchmark 示例里跑了几个测试用例,数据直接说:
- 列表滚动帧率稳定在 60fps,没有掉帧。Snapchat 内部用了 8 年,日活数亿的应用不会容忍 UI 框架拖后腿。
- VoiceOver 和 TalkBack 无障碍支持自动生效。因为最终控件是原生的 UIAccessibilityElement 和 View.setAccessibilityDelegate,不用像 Flutter 那样每个控件单独适配语义。
- 输入法即插即用。文字输入、候选词、表情选择器都是系统行为,不需要重写输入法引擎。
实际成本
-
原生控件能力就是天花板。Valdi 生成的视图受限于平台原生控件的上限。复杂排版、自定义绘图场景,Valdi 的表达能力不如 Flutter 的 Canvas API。
-
第三方组件生态接近空白。官方引用的 Valdi_Widgets 组件库数量有限。不能指望 React Native 那种 npm 量级的生态。如果你的 UI 大量依赖第三方控件,Valdi 不是好选择。
-
文档还没完成开源化。README 部分链接指向
./docs/docs/这类路径,一些内容还是 Snap 内部风格。我从docs/目录摸了一轮,有些章节需要自己推测补充。 -
调试工具有限。热重载可以正常用,但组件树检查、布局边界可视化这些 DevTools 级别的工具还没见到。README 也没提到类似 React DevTools 的工具。
谁应该认真看这个项目
Snapchat 内部生产环境用了 8 年。16k 星在跨平台框架里不算高,但 Valdi 的用户群里大多是有经验的工程团队。他们知道“8 年生产验证”比 star 数重要得多。
Valdi 做的事情在学术和工程界讨论了很多年,但拿出成熟产品的很少。Rust 的 Xilem、Google Compose 的编译方案都还在路上。Valdi 是少有的走通这条路并经过大规模验证的项目。
如果你的团队需要一套可预测的原生渲染路径,受够了 React Native 的桥接性能和 Flutter 的自绘控件兼容问题,Valdi 值得花一个下午搭起来跑跑看。
简单判断标准:
- 你的 UI 大部分是系统控件组合?Valdi 能应付
- 你需要大量第三方组件?等生态成熟
- 你要做服务端动态化 UI?valdi_gpt 的路径已经验证过
- 你依赖自定义绘图和复杂动画?选 Flutter 更稳妥
Valdi 补了一句 Beta 标签:“我们的工具和文档需要在开源世界接受更多实战检验。” 这个态度比那些号称稳定但一跑就崩的项目诚实得多。
Valdi, 跨平台UI, TypeScript编译, Snapchat