最近在开发一款跨平台的工业软件,需求是需要支持 macOS、Windows 以及 Linux,并且最好能同时兼容 arm 和 x86 架构。因此,我研究了一下现有的跨平台方案。首先排除了 Avalonia,因为它和 WPF 很像,使用的 XAML 语法比较啰嗦。我个人认为,像 SwiftUI 和 Compose 那种现代化的声明式 UI 才是未来的趋势。然而,SwiftUI 不能跨平台,而 Compose Multiplatform 的基础功能也才刚刚完善。综合考虑后,我选择了几个不同的方案并逐一进行了尝试。下面是我测试后得到的结果。
框架特性对比 Link to heading
特性 | Compose Multiplatform | Flutter | Tauri | Electron |
---|---|---|---|---|
主要语言 | Kotlin | Dart | Rust + Web技术 | JavaScript/TypeScript |
UI渲染 | 原生渲染 | 自带渲染引擎 | 系统WebView | Chromium |
包体积 | 中等 | 中等 | 小 (几MB) | 大 (>100MB) |
内存占用 | 中等 | 中等 | 低 | 高 |
跨平台支持 | 桌面、Android、iOS、Web | 移动端优先,桌面端使用的不多 | 仅桌面端 | 仅桌面端 |
生态系统 | 发展中 | 丰富 | 可用Web生态 | 非常丰富 |
开发体验 | 类SwiftUI,声明式 | 声明式,但不是SwiftUI那种 | Web + Rust | Web技术栈 |
热重载 | 支持(alpha) | 支持 | 支持 | 支持 |
编译速度 | 快 | 快 | 慢 | 快 |
调试工具 | 一般 | 优秀 | 一般 | 优秀 |
Linux支持 | 取决于JVM | 没试 | V1打包报错,V2依赖glibc2.35,系统版本不够新就没法用 | 完美 |
适用平台 | 全平台应用,iOS是beta阶段 | 移动应用为主 | 轻量级桌面应用 | 重型桌面应用 |
技术复用性 | 高(Kotlin全栈) | 低(仅Flutter生态) | 中(Web技术) | 中(Web技术) |
Compose Multiplatform Link to heading
谷歌在 2021 年 7 月宣布 Android 官方支持 Jetpack Compose(1.0 版本发布),将其作为现代 Android UI 开发工具包推广。随后,JetBrains 扩展为 Compose Multiplatform,支持桌面、Web 和移动端。我测试后发现,它与 SwiftUI 的声明式 UI 风格高度相似,这种语法(称为"声明式编程"或"Declarative UI")是未来的趋势。
让我们通过一个用户信息卡片的实现来对比不同框架的语法差异:
SwiftUI 实现 Link to heading
struct UserCard: View {
let user: User
var body: some View {
VStack(alignment: .leading, spacing: 8) {
HStack {
Image(user.avatarName)
.resizable()
.frame(width: 50, height: 50)
.clipShape(Circle())
VStack(alignment: .leading) {
Text(user.name)
.font(.headline)
Text(user.title)
.font(.subheadline)
.foregroundColor(.gray)
}
}
Text(user.bio)
.font(.body)
.lineLimit(3)
}
.padding()
.background(Color.white)
.cornerRadius(10)
.shadow(radius: 5)
}
}
Compose Multiplatform 实现 Link to heading
@Composable
fun UserCard(user: User) {
Column(
modifier = Modifier
.padding(16.dp)
.background(Color.White)
.clip(RoundedCornerShape(10.dp))
.shadow(5.dp)
) {
Row(
modifier = Modifier.padding(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Image(
painter = painterResource(user.avatarRes),
contentDescription = null,
modifier = Modifier
.size(50.dp)
.clip(CircleShape)
)
Column(
modifier = Modifier.padding(start = 8.dp)
) {
Text(
text = user.name,
style = MaterialTheme.typography.h6
)
Text(
text = user.title,
style = MaterialTheme.typography.subtitle1,
color = Color.Gray
)
}
}
Text(
text = user.bio,
style = MaterialTheme.typography.body1,
maxLines = 3,
overflow = TextOverflow.Ellipsis
)
}
}
React 实现 Link to heading
import styled from 'styled-components';
const Card = styled.div`
padding: 16px;
background: white;
border-radius: 10px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
`;
const TopSection = styled.div`
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
`;
const Avatar = styled.img`
width: 50px;
height: 50px;
border-radius: 50%;
object-fit: cover;
`;
const UserInfo = styled.div`
display: flex;
flex-direction: column;
`;
const Name = styled.h3`
margin: 0;
font-size: 1.1rem;
font-weight: 600;
`;
const Title = styled.p`
margin: 0;
color: gray;
font-size: 0.9rem;
`;
const Bio = styled.p`
margin: 0;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
`;
const UserCard: React.FC<UserCardProps> = ({ user }) => {
return (
<Card>
<TopSection>
<Avatar src={user.avatarUrl} alt={user.name} />
<UserInfo>
<Name>{user.name}</Name>
<Title>{user.title}</Title>
</UserInfo>
</TopSection>
<Bio>{user.bio}</Bio>
</Card>
);
};
从代码对比可以看出,SwiftUI 和 Compose Multiplatform 的声明式语法更为简洁优雅,而 React 虽然也是声明式,但需要更多的样式代码和结构分离。
Flutter Link to heading
Flutter 由谷歌推出,已非常成熟,凭借 Dart 和自渲染引擎在移动端表现优异。能快速构建漂亮的 UI,社区活跃。然而,Dart 的经验难以复用到其他领域,除非专职 Flutter 开发,否则投入回报比不高。
适用场景:专注移动端的团队。
Tauri Link to heading
Tauri 使用系统自带 WebView,搭配 Rust 后端,主打轻量和高性能。在 macOS 和 Windows 测试顺利,包体积小、性能略优于 Electron。但 Linux 兼容性存在问题:v1 打包 AppImage 问题多,v2 在 Ubuntu 22.04 以下因 glibc 版本无法运行。
适用场景:不考虑 Linux 或能解决兼容性的团队。
Electron Link to heading
Electron 基于 Chromium 和 Node.js,跨平台支持最完善。只要会 Web 开发就能上手,macOS 上甚至能轻松编译 ARM 版本。但包体积大、性能开销高,移动端经验无法复用。
适用场景:熟悉 Web 技术、追求快速上手的开发者。
我的选择:Compose Multiplatform Link to heading
我最终选择 Compose Multiplatform,原因有三:
- Kotlin 优势:语言多用途,后端、前端皆宜
- 声明式语法:与 SwiftUI 一致的 Declarative UI 是未来趋势,代码简洁且直观
- 未来潜力:JetBrains 的推动加上语法的前瞻性,让我相信它是跨平台开发的未来
如果精通 Web,Electron 是首选;不考虑 Linux,Tauri 的轻量很吸引人;Flutter 则适合专注移动端。但综合来看,Compose Multiplatform 更符合我的长期目标。