大家好,这里是大家的林语冰。
在前端框架的"诸神之战"中,性能往往选用框架的是一个敏感的指标,比敏感肌还敏感。您可能会在社区看到有人提问"为什么 Vue 的性能比 React 好",也可能看到另一个人提问"为什么 React 的性能比 Vue 好"......
唯一的事实是,性能固然重要,但性能不是选用某框架的唯一因素,因为性能不是现代化前端框架的"阿喀琉斯之踵"。
我们之前共享了某企业将项目从 Vue 2 迁移到 Svelte 的技术博客,但该博客选用框架的反向教学给尤大整麻了......本期《前端翻译计划》我们共享的是尤大对 Vue 3 vs Svelte 框架选用的观点。刚好 Vue 2 即将结束开源维护生涯,此博客也可以给大家带来启发。
最近,某企业共享了一篇博客,谈论它们从 Vue 2 迁移到 Svelte,并用 Vue 3 与 Svelte 测评跑分。我们发现该博客纰漏百出。在本文中,我们将从 Vue 团队官方视角共享若干想法,并希望澄清该博客可能引起的潜在误解。
在我们深入讨论细节之前,我们想强调,我们尊重开发者对技术的选择,且相信您应该使用能够提高工作效率的技术。我们也十分尊重 Svelte 团队,尤其是它们在 API 设计上追求精简。
要点说明
原始帖子包含一个跑分图表,其中包含一大坨值得澄清的问题:
类型体验
有人说,"Vue 3 不支持类型事件。"
君不见,Vue 3 从 3.2 开始就可用类型事件。
除此之外,我们不同意"Svelte 提供更棒的类型体验"的结论。据我们所知,Vue 3 和 Svelte 对 TS 支持现状平分秋色。
全局变量访问限制
有人说,"无法在 Vue 组件中导入和使用 TS 枚举。"
这大错特错。事实上,Vue 和 Svelte 这方面的工作原理完全相同。
外部响应式对象
这有点含糊不清,该博客没有进一步解释,但所有 Vue 的响应性 API,包括但不限于 ref/computed/watch
,都可以在组件外使用,作为简单的跨组件 store
。
错误边界
Vue 始终提供通过 onErrorCaptured
生命周期钩子捕获从祖先组件中的后代组件树抛出的错误的功能。这还包括从异步事件处理程序和生命周期钩子引发的错误。
Vue 没有直接在模板中处理 Promise
状态的内置函数,但这可以通过 vue-promised
等库轻松实现。
与库集成
有人说,"在 Svelte 中添加纯 JS 插件更简单。"
该博客包含一个与 Prism.js 集成的示例来支持此观点。虽然但是,在 Vue 中,使用 <script setup>
时,其工作方式完全相同。
元框架
该博客还比较了基于 Vue 和 Svelte 构建的元框架,即 Nuxt 和 SvelteKit,并将 Vite 列为 SvelteKit 的优势。虽然但是,Nuxt 3 刚刚稳定,默认也使用 Vite。Nuxt 团队和 SvelteKit 团队都与 Vite 团队有着密切的合作关系。
语法
我们尊重不同的语法偏好,但讨论设计之间的权衡也很重要。
首先,我们不认为诸如单花括号与双花括号、元素绑定指令与 {}
样式控制流,或需要额外的 <template>
标签之类的差异会对您的长期生产造成重大影响。模板语法随着时间的推移很快会内化。
当我们谈论响应性时,Svelte 确实提供了一种十分简洁的语法来声明和改变组件状态,并且有几点值得讨论:
- 为了表达响应性,存在 3 个基本概念:状态、派生状态和效应(effect)。Svelte 使用普通变量表示状态,使用神奇的
$
符号表示派生状态和效应。Vue 使用显式 API 来声明(ref/computed/watchEffect
)。某些用户可能更喜欢魔术语法,而另一些用户可能更喜欢显式 API ------ 两个阵营都有空间。 - Svelte 基于编译器的响应性限制了可以使用此类语法的地方。它不能在 Svelte 组件外使用,也不支持构建步骤的用例中使用。而对于 Vue,组合式 API 可以在组件内外同样使用,甚至可以在无构建步骤设置中使用。
- 由于上述 (2),Svelte 需要提供一组额外的 API(存储)来管理组件外部的同款响应性概念。由于这两种语法不容易相互转换,因此在将逻辑移出组件/重构组件时会产生阻力。
话虽如此,我们一直在尝试 Vue 中名为 Reactivity Transform(响应性转换)的功能,它允许您编写如下所示的 Vue 组件:
它提供了类似 Svelte 的简洁性,但也可在纯 JS/TS 文件中使用。自动将语法脱糖(de-sugar)为简单的组合式 API 代码也很简单。
性能和打包体积
优化性能和打包体积是迁移的原因之一。毫无疑问,Svelte 具有高性能和轻量级,但也无法保证比其他框架有所改进。实际上,这可能取决于其他因素,包括实际实现、优化空间和 App 的规模。
作为参考,Vue 3 通过少量优化就能在 js-framework-benchmark
(JS 框架寄存测试)中超越 Svelte。Vue 3 通过运行时/编译器混合渲染模型实现了这一点,我们称之为编译器通知虚拟 DOM。它利用编译时已知的信息来优化运行时性能,同时保留与手动编写的渲染函数的兼容性。
就打包体积而言,Svelte 十分适合生成仅包含单个或几个组件的小部件或 Web Components,但与其他框架相比,其较小的运行时大小可以通过其更详细的每个组件代码输出来抵消。这项研究表明,Svelte App 的打包体积可能会成为大型 App 开发中的劣势,尤其是在启用 SSR 水合作用的情况下。
值得一提的是,Svelte 和 Vue 3 的性能很可能足以满足您的用例,并且这两个框架都将继续发展和改进。Svelte 团队提到了在 Svelte 4 中改进每个组件代码输出大小的计划。Vue 方面,我们也在探索一种受 Solid.js 启发的替代性、性能更高的编译策略(代号:Vapor)。Vapor 模式(蒸汽模式)将允许 Vue 组件被编译成不涉及 Virtual DOM 运行时的格式。目前仍处于研究阶段,我们之后会共享更多细节。
JS 现状调查中的留存率数据
此外,该博客提到的一个主要考虑点涉及 JS 现状调查的满意度评级。虽然 Svelte 在调查中绝对值得获得高评级,但使用此类评级来决定是否应该迁移 App 可能会对您的团队产生负面影响,因为缺少一大坨上下文。
在调查中,框架的满意度被定义为会再次使用该框架的用户数量与不会再次使用该框架的用户数量的比率。粉丝请注意,该数字仅根据使用过框架的用户的反应来计算。平心而论,此公式自然有利于更新的技术。理论上而言,如果 1 个框架有且仅有 1 个用户,并且该用户报告它会再次使用此框架,那么该框架将获得 100% 的满分!
处于早期阶段的技术主要吸引的是喜欢该技术本身的用户。虽然但是,当它成为主流时,它开始在更大规模的组织中采用,在这些组织中,技术选择决策是自上而下做出的。这意味着,无论用户的个人喜好如何,将会有越来越多的用户不得不使用它。它还吸引了更多的"路转粉",它们纯粹是因为它的高人气而尝试它,但可能不是目标受众。此外,更广泛的采用在更广泛的场景中对技术提出了挑战,暴露了只有在更苛刻的情况下才可能出现的问题。
另一方面,如果一项新技术未能在早期采用者中获得比现有技术更高的分数,那么它甚至可能不会进入调查。
这绝不是要贬低 Svelte 的成就,也不是我们的借口。Vue 2 到 Vue 3 的过渡并不顺利,并且肯定影响了满意度得分。我们希望能够通过继续改进 Vue 3 来扭转局面。但希望您能明白这一点:仅凭此数字并不能完全代表一个框架有多"好",更不用说它如何适合您的用例了。粉丝请记住,调查通常会受到一大坨令人困惑的变量和背景的影响,这些变量和背景可能不适用于您的情况,因此请谨慎将其视为福音。
完结撒花
归根结底,我们认为 Svelte 是一个很棒的框架,我们祝愿某企业与 Svelte 的"梦幻联动"一切顺利!毕竟,虽然我们想澄清一若干测评跑分,但同一个社区同一个梦想,我们希望帮助人们为用户构建令人惊叹的产品。
最后,如果您有 Vue 2 代码库,且担心其生命周期即将结束,那么迁移不一定是唯一的选择。Vue 2 是一项稳定、经过验证且经过实战考验的技术,将继续发光发热。在进行大规模迁移之前,请务必评估您的实际收益和成本。对于那些需要处理安全合规性问题的人,我们正在与 HeroDevs 合作,为 Vue 2 提供企业付费扩展支持。
免责声明
本文属于是语冰的直男翻译了属于是,略有删改,仅供粉丝参考,英文原味版请传送 On Escape's Vue 2 to Svelte Migration。
您现在收看的是《前端翻译计划》,学废了的小伙伴可以订阅此专栏合集,我们每天佛系投稿,欢迎持续关注前端生态。谢谢大家的点赞,掰掰~