跳到正文
原文
少数派· Tw93·· 4 天前精选AI 评分70

客户端开发技术选型探讨

你不知道的客户端开发:AI 时代下的选型、原生与借力

AI 摘要

在 AI 时代下,客户端开发主要面临 Web、跨端和原生三种技术选型,每种选型各有优劣,需根据应用场景和需求进行选择。Web 技术开发效率高但性能较差;原生技术性能和体验好但开发效率低;跨端技术则介于两者之间。随着 AI 技术的发展

正文 · 中文整理稿

做过前端客户端的小伙伴应该都知道,这些年端的开发一般是这三条路。 第一种最简单方便的是,直接写 Web 代码,塞到浏览器就能跑,包括早年的 PhoneGap、Cordova 就是把网页塞进一个原生壳里,然后提供一些 bridge 的能力让 JS 可以调用到一些原生的能力,比如唤起手机摄像头这类的 Web 不好做的事情。 第二种是跨端开发,也就是早年大家常听到的一码多端。 当时移动端有 React Native、Weex 这一类技术,主要是为了解决 Web 性能差的问题,一份代码同时打包 iOS 和 Android。

国内大厂当时重度用跨端还有一个非常大的原因,就是动态化和热更新,讲得土一点就是可以绕过商店审核直接下发新页面,这也是国内跨端在移动互联网高速发展时特别流行的重要原因。 桌面端大家熟悉的就是 Electron,现在不少 AI 桌面端、VS Code、Slack 是用这个做的,代价是相当于每个应用都自带一份 Chromium 和 Node.js,安装包 100 多 MB,内存也占得多。

但好处是在 Chromium 渲染引擎的统一下能够很好地保持多端的展示一致性,加上里面写的代码非常好写,后续不少桌面的速成就会用这个技术。 跨端后面也慢慢延伸出更多有趣的解决方案,类似 Flutter 自己实现一套渲染引擎,早期靠 Skia,现在换成了自研的 Impeller 渲染引擎来保障多端一致和性能效率的均衡,包括桌面端上老牌的 Qt,和 Flutter 一样自己画界面。

这两年桌面跨端也出现了用 Rust 写的 Tauri、Go 写的 Wails,它们和 Electron 不一样的地方就是,没有塞一个 Chromium 进去,而是使用系统自带的 WebView,包会小非常多,但是整体还是基于 Web 这一套研发思路和对应实现语言去进行桥接交互,但是由于系统 WebView 每个平台不一样,Windows 上是 WebView2,Mac 上是 WKWebView,Linux 上是 WebKitGTK,所以多端显示的一致性反而不如 Electron,还是要写兼容代码。

所以这种情况下,即使 Electron 很大内存占用也不低,还是会被选择更多。 第三种是原生开发,也是没有 AI 之前大家觉得难度最大的一种方式。 早年苹果系的 Objective-C、Android Java、Windows C++ 和 C#,都需要花很多时间去学习、看书、手编代码,深入研究系统底层原理,才能写出性能更好、更稳定的代码,属于前期投入大、后期用户很享受的技术。

我 17 年那会儿刚工作不久,职业发展比较爽的一个很大原因,是抽了半年时间学习 Objective-C 和 iOS 研发,让本职是前端的工作提前往跨端方向走了,刚好可以解决一些只懂前端或只懂客户端都搞不定的难题,那也是我做一线开发非常快乐有趣的一段时间。 等到后面 Swift + SwiftUI、Kotlin + Jetpack Compose、C# + WinUI 3 慢慢出来成熟后,这些原生端语言的写法也慢慢向前端的声明式写法靠齐,也更易写了,声明式代码更短、更好读了。

但是在国内,原生完全被 React Native、Flutter、Electron 的广泛使用盖过去了,开发者不多,生态发展完全靠官方推动,这也是为什么很多 App 出活很快,但大家普遍觉得用久了卡卡的,而且这类 App 还占了大头。 想迁移到原生的话,假如之前架构实现得不好,大概率只能重写,完全不能复用,实现得好,比如你早就把业务逻辑抽出来了,类似 Kotlin Multiplatform 这类方案把业务逻辑共享、界面各写各的原生,算是第四条路,也是最近几年的趋势。

聊到这里大家应该大概明白了,这里也有一个不可能三角,就是研发效率、体验、性能这三者,选择 Web 是多效率少性能,选原生是多性能体验少效率,选跨端刚好是在这三者取一个中间,做得好容易都占,做得不好,容易没有一边占到好处的尴尬局面。 研发效率、体验、性能的不可能三角,Web 靠近效率,原生靠近体验和性能,跨端取中间那么在现在 AI 写代码不是大问题的情况下,该怎么选呢? 很多时候还是看场景。 如果是重内容的浏览、阅读这类轻应用,直接用 Web 技术最省心;

但如果是需要深度调用系统底层能力,或者追求更低内存和更顺手交互的应用,我依然更推荐原生技术,可以第一时间享受到系统官方本身的众多调优。 有了 AI 之后,一个人写两套原生的成本其实大幅下来了,效率那一边被补上了不少,调试和体验验证反而成了人最需要花心思的地方。 当然假如实在技术选型不那么重要,工作量非常之大,以及业务效果远大于技术体验选择,选择跨端技术也是可以的,这样快,迭代发布也快,能以最快速度把新功能推给用户。

Windows 版为什么还是选了 C# 和 WinUI 3 技术栈上, Mac 版本的 Mole 使用的也是原生的 Swift + SwiftUI,能够让我很好调用系统能力,并且有着非常好的性能体验,想着不将就,所以在 Windows 上我也是想着直接用本身写 Windows 软件最直接的语言,C# 加 WinUI 3,跑在 .NET 10 上,过程虽然难搞,但是相比十年前我了解朋友谈的 Windows 开发要简单好理解一些了。

Windows 上的原生界面框架其实挺多的,包括很多年前了解过的 Win32、WinForms、WPF、UWP 这一波,WPF 是 2006 年出的,到现在还在维护,但控件和设计语言不是很好看,非常上一代的感觉,然后 UWP 又被沙盒和应用商店给绑定住,现在微软主推的是 Windows App SDK 里的 WinUI 3,界面框架从系统里面拆出来单独发版,这样就有一个好处,普通的 Win32 程序也能用,基础组件就是 Windows 11 自己的 Fluent 风格,我还挺喜欢,高分屏缩放和 ARM64 都是原生支持。

然后这里 .NET 10 是去年 11 月发的长期支持版本,打包时我把运行时一起打进去,用户不需要另外装 .NET,x64 和 ARM64 这里各出了一个原生安装包,骁龙的 Windows 笔记本就不要走转译了,相当于尽量让用户使用简单不折腾。 这里安装和更新用的是开源的 Velopack 框架,可以很方便做增量更新,也很好用。

工程师开始写代码时候肯定会想到能复用尽量复用,所以我开始写的时候也非常想复用 Mac 的 Swift 代码,后面让 AI 分析了一下,十几万行 Swift 代码可以脱离 AppKit、SwiftUI 这些系统框架使用的 20% 都没有,处理的逻辑也是 ~/Library 这类 macOS 自己的路径规则,基本用不上,所以 Windows 版几乎是从零开始写的。

代码各写各的,两边怎么保持一致两边的关系其实非常简单,外观和交互我尽量完全一致,尽可能让大家意识里面认为的 Windows 软件不那么精致美观的感觉在这里也保持我认为好的水平,然后底层代码各写各的,关于视觉的一致性还原有了 AI 以后很简单,我把原本的 Mac 版写在 Swift 里的颜色、字号、间距、圆角这些设计 token,直接写了一个脚本生成为 Windows 里面 XAML 资源,文案也是从 Mac 的多语言文件转成 Windows 的格式,11 种语言一起转过来,甚至大家看到的菜单栏里面的那个 runner 动画也是用的同一个脚本同步来的。

虽说同步,可能大家会觉得很简单,其实这里需要花点精力防止 AI 直接给你跑偏了,每次同步其实我会记录对应的是 Mac 的哪一个提交,这样两边就不会走偏去,然后功能上会有一份 SYNC.md 当作对账表,Mac 每加一个功能、修一个安全问题,Windows 这边都会标清楚哪些是已经实现、哪些是刻意不同还是不适用,以及为什么这样判断。

通过这两个机制,我可以很好地让两边的底层完全各写各的,但是又能很好地保持功能对齐,完全不需要刻意去硬写一层兼容去磨平,反而会变复杂,这里能复用的反而是设计、文案以及踩坑后定下来的各种规则,反而这些是 AI 非常喜欢的「能力抽象层」,也就是说随着时代发展,慢慢所谓的代码抽象没有那么重要了,反而是规则抽象更重要。

签名比 Mac 麻烦不少另外 Windows 开发还有一块比 Mac 要麻烦不少,就是证书签名,没有签名的,一打开会出现「Windows 已保护你的电脑」,甚至 Windows 11 的智能应用控制会直接不让运行,国内不少安全软件也会把没签名的程序当成可疑报毒,这和 Mac 上没签名、没公证的软件提示「已损坏」差不多,平时 Mac 上大家还可以跑一条命令解掉,Windows 上想正规分发,这一步没有啥好办法,就是需要签名。

调研下来微软的签名生态的确比苹果差太多了,微软有自己的 Azure Artifact Signing,一个月 9.99 美元最省事,居然个人只开放给美国和加拿大的开发者,没办法使用,很奇葩的规定,然后行业还规定从 2023 年起签名私钥必须放在硬件或者云端 HSM 里,不能再是电脑上的一个文件,今年起单张证书最长只能用 460 天,差不多一年多就得换一次证书。

来源:少数派 · sspai.com

00