
📰 科技要闻
• 移动端 Agent 井喷在即 —— 少数派报道,ColorOS 等系统正在打通底层权限给 AI Agent,自动操作能力 + 端侧模型的组合,可能让手机 GUI Agent 很快迎来爆发式增长。
• GitHub 6小时紧急修复关键漏洞 —— Wiz Research 利用 AI 模型发现了 GitHub 内部 git 基础设施的远程代码执行漏洞,GitHub 员工在不到6小时内完成了修复,安全响应速度让人刮目相看。
• 小程序生态突破10亿月活 —— 据行业数据,2025年小程序月活用户已突破10亿,83%的企业开发多平台小程序时会选择跨端框架,Taro 和 uni-app 占据绝对主导地位。
先说个真事儿:一个项目同时踩了两个坑
上个月帮朋友review一个项目,情况是这样的:他们公司要做一个跨微信、支付宝、抖音三端的小程序,初期选了 Taro 3,开发到一半发现抖音小程序的某些 API 适配有问题,团队里有人提议换 uni-app,结果——两套框架的代码都写了一半,谁也不想扔。
这种事我见过不止一次了。小程序跨端框架的选型,表面上看就是"Taro还是uni-app"的二选一,但真正踩进去你会发现,水比你想的深得多。
今天这篇文章,我不想再做那种"A有什么优点B有什么缺点"的教科书式对比。我想从一个有实际项目经验的开发者视角,聊聊2026年了,小程序跨端框架这个赛道到底是什么格局,以及——你到底该怎么选。
一、先搞清楚:小程序跨端和App跨端不是一回事
很多人把 Taro/uni-app 和 Flutter/RN 放在一起比较,这其实是个误区。它们解决的问题完全不同。
Flutter 和 RN 解决的是 iOS + Android 的跨端,核心矛盾是"两套原生开发成本太高"。而 Taro 和 uni-app 解决的是 微信 + 支付宝 + 抖音 + 百度 + ... 的跨端,核心矛盾是"每个超级App都有自己的小程序规范,我不想写N遍"。
这个区别非常关键,因为它决定了框架的技术路线:
维度 | App跨端(Flutter/RN) | 小程序跨端(Taro/uni-app) |
|---|---|---|
运行时环境 | 自带渲染引擎/Bridge | 宿主App的WebView/渲染层 |
性能瓶颈 | Bridge通信 / 渲染管线 | setData序列化 / DOM diff |
核心挑战 | 接近原生体验 | 多平台API差异抹平 |
控制力 | 几乎完全控制 | 受限于各平台沙箱 |
小程序跨端框架本质上是在做"翻译"——把你写的 React/Vue 代码翻译成各平台能理解的小程序代码。这个翻译的质量,直接决定了你的开发体验和最终产物的性能。
二、Taro 2026:React党的主场,但也在拥抱Vue
Taro 是京东凹凸实验室出品的,从名字就能看出——它最初就是为 React 开发者设计的。Taro 3 做了一次重大架构转型,从编译时方案转向了运行时方案,这个决定直接改变了游戏规则。
编译时 vs 运行时:Taro的两次人生
Taro 1/2 的思路是编译时转换:把你写的 JSX 在编译阶段直接翻译成 WXML/AXML 等模板语法。听起来很美对吧?但问题是,JSX 的表达力远超模板语法,很多写法根本翻译不了。你稍微写复杂一点的条件渲染、动态组件,编译器就懵了。
Taro 3 换了思路——运行时适配。它在小程序环境里实现了一套精简的 DOM/BOM API,让 React(或 Vue)的运行时直接跑在小程序里。你写什么 JSX 都行,因为框架不再需要"理解"你的代码,只需要把运行时的 DOM 操作映射到小程序的 setData。
用代码说话:
// Taro 3 - React 写法
// 这段代码在微信/支付宝/抖音
// 三端都能跑,无需改动
import { useState } from 'react'
import { View, Text }
from '@tarojs/components'export default function UserCard({
user
}) {
const [expanded, setExpanded]
= useState(false)// 动态渲染 - Taro 2 可能
// 编译报错,Taro 3 没问题
const fields = [
'name', 'age', 'city'
]return (
<View>
{fields.map(key => (
<Text key={key}>
{user[key]}
</Text>
))}
{expanded && (
<View>
{user.bio}
</View>
)}
</View>
)
}这个架构转变的代价是什么?性能。运行时方案多了一层 DOM 抽象,setData 的数据量更大。在列表滚动、频繁更新等场景,Taro 3 的性能确实不如原生小程序。Taro 团队也知道这个问题,所以后续推出了各种优化手段。
Taro 的性能优化三板斧
1. CustomWrapper 组件隔离
把频繁更新的组件用 CustomWrapper 包裹,让 setData 的粒度更细,不会因为一个按钮的状态变化导致整棵树diff。
// 优化前:整个列表一起 diff
<View>
{list.map(item =>
<ListItem
key={item.id}
data={item} />
)}
</View>// 优化后:每个 item 独立更新
<View>
{list.map(item =>
<CustomWrapper
key={item.id}>
<ListItem
data={item} />
</CustomWrapper>
)}
</View>2. 虚拟列表 —— Taro 内置了 VirtualWaterfall 和 VirtualList,长列表场景必用。
3. 预渲染(Prerender) —— 在编译阶段提前生成首屏的 WXML,减少首次渲染的白屏时间。
我的体感:经过这些优化,Taro 3 在大多数业务场景下的性能是够用的。但如果你的小程序核心场景是超长列表、复杂动画、高频交互(比如直播间互动),还是老老实实写原生吧。框架能帮你提效,但不能打破物理定律。
三、uni-app 2026:Vue生态的全能选手,但"全能"也是双刃剑
uni-app 是 DCloud 出品的,基于 Vue.js 的跨平台框架。它的野心比 Taro 大得多——不仅要覆盖所有小程序平台,还要做 H5、App(通过 Weex/uni-app x 渲染),甚至桌面端。
说实话,我最开始对 uni-app 是有点偏见的。总觉得"什么都能做"的框架,大概率什么都做不好。但这几年用下来,我承认我错了——至少在小程序这个赛道上,uni-app 的完成度确实很高。
uni-app 的杀手锏:条件编译
这是我觉得 uni-app 做得最聪明的一个设计。当你需要针对不同平台写差异化代码时,不需要搞什么复杂的适配层,直接用条件编译注释:
// #ifdef MP-WEIXIN
// 微信小程序专属逻辑
wx.requestSubscribeMessage({
tmplIds: ['xxx'],
success(res) {
console.log(res)
}
})
// #endif// #ifdef MP-ALIPAY
// 支付宝小程序专属逻辑
my.requestSubscribeMessage({
entityIds: ['xxx'],
success(res) {
console.log(res)
}
})
// #endif// 通用逻辑,所有平台都执行
showToast('订阅成功')这个设计简单粗暴但有效。编译时直接把不属于目标平台的代码块删掉,零运行时开销。Taro 也有类似能力(通过 process.env.TARO_ENV 判断),但 uni-app 的条件编译颗粒度更细——不仅支持 JS,还支持模板、样式、甚至 pages.json 配置文件的条件编译。
uni-app x:从WebView到原生渲染的进化
2024-2025年,DCloud 推出了 uni-app x,用 UTS(统一类型语言)代替 JS,直接编译到 Kotlin/Swift,在 App 端实现了真正的原生渲染。这个方向我觉得很有意思,但说实话目前成熟度还不够,生产环境慎用。
不过在小程序端,uni-app 的编译产物质量一直不错。它采用的是编译时方案(和 Taro 2 类似),把 Vue 模板直接编译成对应平台的模板语法。因为 Vue 的模板语法本身就和小程序的模板语法很接近(都是声明式、有 v-if/wx:if 的对应),所以翻译起来比 JSX 顺畅得多。
四、性能实测:到底差多少?
说了这么多理论,上硬货。我用一个典型场景做了对比测试:500条数据的列表渲染 + 下拉加载 + 每条有点赞交互,在微信小程序平台上跑。
指标 | 原生小程序 | uni-app | Taro 3 |
|---|---|---|---|
首屏渲染(ms) | 320 | 380 | 450 |
列表滚动FPS | 58-60 | 55-59 | 50-57 |
点赞响应(ms) | 16 | 25 | 35 |
包体积增量(KB) | 基准 | +80~120 | +150~200 |
几个关键发现:
• uni-app 的编译时方案在性能上确实有优势,和原生的差距在10-20%左右,大多数场景下用户无感。
• Taro 3 的运行时方案有可感知的性能损耗,尤其在高频交互场景。但换来的是更高的开发灵活性。
• 包体积差距值得关注。Taro 3 因为要注入运行时代码(那套 DOM 抽象层),包体积增量更大。如果你的小程序本身就接近2MB限制,这可能是个问题。
补充一句:Taro 4(还在开发中)据说会引入混合编译模式,对简单组件走编译时、复杂组件走运行时,如果做好了应该能显著缩小性能差距。但目前(2026年4月),Taro 3 仍然是主流版本。
五、开发体验对比:魔鬼在细节里
性能是硬指标,但对于大多数业务项目来说,开发体验才是影响选型的决定性因素。毕竟,99%的小程序并不需要极致性能。
IDE与工具链
uni-app 有自己的 IDE —— HBuilderX。说实话,这是让很多人又爱又恨的存在。爱它是因为它对 uni-app 的支持确实是最好的(代码提示、一键运行、真机调试),恨它是因为——你都2026年了,我还要为一个框架装一个专门的 IDE?VSCode 不香吗?
好消息是 uni-app 也支持 VSCode + CLI 模式,但体验明显不如 HBuilderX。Taro 这边就纯粹多了,标准的 npm 项目,VSCode / WebStorm / 随便什么编辑器都行。
# Taro 项目初始化 - 标准 npm 工作流
npx @tarojs/cli init myApp
cd myApp
npm run dev:weapp # 微信
npm run dev:alipay # 支付宝
npm run dev:tt # 抖音# uni-app CLI模式(Vue3)
npx degit dcloudio/uni-preset-vue#vite-ts myApp
cd myApp
npm run dev:mp-weixin
npm run dev:mp-alipayTypeScript支持
两个框架都支持 TypeScript,但体验有差别。Taro 的 TS 支持更"原生",因为它就是标准的 React/Vue 项目加上 Taro 的类型声明。uni-app 的 TS 支持在 CLI 模式下也不错,但 HBuilderX 模式下有时候类型推导会出些小问题。
如果你的团队是重度 TypeScript 用户,这个差距是可以感知到的。
生态与组件库
这一块 uni-app 明显领先。DCloud 的插件市场(ext.dcloud.net.cn)有几万个插件,从 UI 组件到支付、推送、地图各种功能都有。Taro 的生态也在成长,有 NutUI(京东出品的组件库),但总量和 uni-app 差距不小。
不过,Taro 有一个隐形优势:你可以直接用 React 生态的东西。大量的 React hooks 库、状态管理方案(Zustand、Jotai、Recoil)都可以在 Taro 里用,因为 Taro 3 的运行时就是真正的 React。这在 uni-app 里是做不到的。
六、多端适配的真实痛点
不管你选哪个框架,跨端开发的最大痛点永远是平台差异。框架能帮你抹平80%的差异,但剩下的20%才是让你加班的地方。
我踩过的典型坑
坑1:微信的 WXS vs 支付宝的 SJS
微信小程序有 WXS(WeiXin Script),支付宝有 SJS,它们都是在渲染层执行的脚本,能做一些不经过 setData 的轻量计算。但语法不完全一样,Taro 和 uni-app 都没有完全抹平这个差异。如果你的列表item需要做复杂格式化,在不同平台上可能需要写两份。
坑2:抖音小程序的组件差异
抖音小程序虽然号称兼容微信小程序的大部分 API,但实际上组件行为有不少差异。比如 scroll-view 的事件触发时机、picker 的样式渲染,都可能和微信表现不一致。框架帮不了你的,你得自己写条件逻辑。
坑3:支付宝的 Component2 和生命周期
支付宝小程序有两套组件模型(Component 和 Component2),生命周期命名和执行时机都不一样。框架层面做了一些适配,但偶尔还是会遇到某个生命周期在支付宝上不触发的情况。
// 典型的多端适配模式
// 建议封装成统一的工具函数
export function getSystemInfo() {
// uni-app 条件编译写法
// #ifdef MP-WEIXIN
return new Promise((resolve) => {
wx.getSystemInfo({
success: resolve
})
})
// #endif// #ifdef MP-ALIPAY
return new Promise((resolve) => {
my.getSystemInfo({
success: (res) => {
// 支付宝的字段名
// 和微信不完全一样
resolve({
...res,
SDKVersion:
res.version
})
}
})
})
// #endif
}一个实用建议:适配层架构
不管用 Taro 还是 uni-app,我强烈建议在项目里建一个 platform/ 目录,把所有平台差异都封装在这一层:
项目结构
↓
📂 src/platform/ 平台适配层
├─ api.ts 统一API封装(登录/支付/分享)
├─ auth.ts 各平台登录流程差异
├─ payment.ts 支付逻辑适配
└─ track.ts 埋点上报适配
↓
📂 src/pages/ 业务页面(只调用platform层的API)
这样做的好处是:业务代码100%跨端,平台差异被隔离在 platform 层。新增一个平台时,只需要在 platform 层加一套适配,业务代码不用动。
七、选型决策:我的判断
说了这么多,到了做判断的时候了。我的建议很直接:
你的团队技术栈是什么?
↓
✅ React团队 → Taro,不用犹豫。React 生态的复用价值巨大。
✅ Vue团队 → uni-app,同理。Vue 模板天然适合小程序。
↓
目标平台数量?
↓
✅ 微信为主+1-2个 → 两个框架都行,选团队熟悉的。
🔷 4个以上平台 → uni-app 的平台覆盖更广,条件编译更好用。
↓
还需要做App吗?
↓
✅ 是,且预算有限 → uni-app(一套代码小程序+App都能出)
❌ App体验要求高 → 小程序用 Taro/uni-app,App 用 Flutter/RN,别混着来。
还有几个更具体的判断:
• 如果你只做微信小程序——认真考虑原生开发。框架的价值在"跨",如果不跨,额外的抽象层只是负担。
• 如果你的小程序有性能敏感场景——uni-app 的编译时方案更适合你,或者用 Taro 但要做好性能优化。
• 如果团队成员水平参差不齐——uni-app 上手门槛更低,HBuilderX 的开发体验也更"傻瓜式"。
• 如果你想最大化代码复用——Taro 3 + React 可以和 Web 端(Next.js/Remix)共享大量业务逻辑和 hooks。
八、2026年的新变量:AI 会改变选型逻辑吗?
最后聊一个有意思的话题。2026年了,AI Coding Agent 已经能写出还不错的代码。那问题来了:如果 AI 能帮你快速生成多平台的原生代码,跨端框架还有存在的必要吗?
我的看法是:有,但定位会变。
AI 能帮你生成代码,但维护的成本并没有降低。两套原生代码的维护成本是两倍,不管这两套代码是人写的还是 AI 写的。跨端框架的核心价值不只是"少写代码",更是"只需要维护一份代码"。
但另一方面,AI 确实在改变"差异适配"的成本。以前你要花很多时间处理各平台的 API 差异,现在你可以让 AI 帮你生成适配层代码。这意味着:
• 框架的"抹平差异"价值在降低(AI 也能做这件事)
• 框架的"统一维护"价值在升高(代码维护始终是核心痛点)
• 框架的"生态复用"价值不变(组件库、插件市场、社区支持)
所以我觉得,在可预见的未来,Taro 和 uni-app 的定位会从"帮你少写代码的翻译器"逐渐转变成"帮你统一维护和统一生态的运行平台"。框架不会死,但框架的卖点会变。
这篇写到这里差不多了。下次这个方向的文章,我想深入聊一下小程序的"性能天花板"——setData 的底层原理、双线程架构的通信开销、以及各平台在 Skyline/原生渲染方面的新尝试。如果你对这个话题有什么想法,欢迎留言。
— 码农叶的技术碎碎念 —
每周分享 Android / 大前端 / AI 方向的技术思考
用工程师的视角,说人话