主打一个“小巧灵动”:Vite + Svelte
作者:来自 vivo 互联网大前端团队- Wei Xing
在研发小型项目时,传统的 Vue、React 显得太“笨重”。本文主要针对开发小型项目的场景,谈谈 Vite+Svelte 是如何让项目变得“小巧灵动”,并横向对比 Svelte 和 Vue 的性能表现,对二者的加载流程做详细分析。
一、背景
为了统一技术标准、提升协作效率,通常在前端团队内部只会保留一套通用的研发框架。尤其是在团队初创时期,团队成员会考虑易用性、社区活跃程度、学习成本等因素,选择一个合适的研发框架并一直推行和使用下去。
国内的前端团队比较青睐 Vue 和 React,我们团队内部的主要研发框架也是 Vue,包括组件库、工具库、脚手架等等,都是围绕 Vue 展开来做研发。
坚持使用一个技术栈虽然让团队协作变得高效,也不用重复“造轮子”,同时提升了人员“流通性”,有它不可忽略的优势。但没有任何一款框架是“银弹”,例如 Vue,它的通用性很好,但在某些特殊场景下,我们会有更好的选择。
例如,当我们在开发一些小型项目时,会发现至少有两个明显的问题:
框架太“重”了:通常一个小型项目只由少数几个简单页面构成,如果使用 Vue 或者 React 这些框架来研发的话,有点“大材小用”了。构建的产物中包含了不少框架运行时代码(虚拟 DOM、响应式、状态管理等),这些代码对于小型项目而言是冗余的,它们影响了包体大小,进而影响页面的启动速度和执行性能。
打包太慢了:以 Vue CLI 为例,它的底层基于 Webpack,虽然 Webpack 具备更强大的功能和灵活性,但相比于 Vite、Esbuild 这些以速度为标杆的构建工具来说,它的速度确实慢了一些,影响了研发效率。
面对这两个问题,我们似乎有更好的技术方案可选:使用更轻量的 Vite + Svelte。本文就是针对开发小型项目的场景,谈谈 Vite+Svelte 是如何让项目变得“小巧灵动”。
注意:本篇所有针对 Svelte 的性能观点,都是基于小型项目这个前提下提出。事实上,随着项目规模的增长, Svelte 的性能、包体大小优势会逐渐减小,甚至不如 Vue 或 React,详情可参考尤雨溪尤大本人针对 Svelte 和 Vue3的包体大小问题的分析。
理论上在普通 CSR 项目中,组件数量超过 19 个时, Svelte 就失去了它的包体大小优势。
二、Vite 和 Svelte 简介
先了解下 Vite 和 Svelte。
2.1 Vite
Vite 是尤雨溪尤大写的一款高效的前端构建工具,相比于 Webpack,它最大的优势就是“快”。
在开发环境下,Vite 使用高性能的 Esbuild 来进行预构建,并利用现代浏览器对 ESM 的支持,直接将预构建好的 ES 模块丢给浏览器进行解析执行,无需在每次变更代码时都重新编译代码,具有更快的冷启动速度和热更新效率。
在生产环境下,Vite 基于 Rollup 进行打包,Rollup 同样支持 ESM 语法,并且具有更快速高效的 Treeshaking,一般情况下,Rollup 具有更小的包体大小和更快的构建速度。
参考 github 上的构建工具横向对比 benchmark。

可以看到无论是冷启动、热更新还是生产环境打包,Vite 都是优于 Webpack 的。尤其是在开发过程中的热更新很快,大大优化了开发体验。
2.2 Svelte
Svelte 是由 Rollup 的作者 Rich Harris(前端轮子哥) 写的一款前端框架。在语法上,Svelte 和 Vue 类似。它和传统框架(如 Vue、React)的最大差异就在于:在构建阶段,Svelte 就将代码编译为“纯粹”的 JavaScript 代码,几乎没有运行时。
这意味着在小型项目中,它打出来的包更小,在运行时,它也不需要复杂的状态管理和虚拟 DOM,在性能上的表现也更好。
在前端大佬 Jacek Schae 的前端框架横向测评中(测评简述:使用各个前端框架来编写同一个标准 App - RealWorld,并横向对比它们的表现),可以看到,Svelte 无论是在首屏渲染速度、包体大小还是代码行数上都展现了较大的优势,全部跻身前三。
首屏渲染速度:

包体大小:

代码行数:

三、搭建 Vite+Svelte 项目
在基本了解了 Vite 和 Svelte 之后,来看看如何着手去搭建一个 Vite+Svelte 的项目。
3.1 全局安装 Vite
通过 npm 全局安装 Vite:
3.2 创建 Svelte 项目
Vite 原生支持直接通过脚手架创建 Svelte 项目,执行以下命令:
命令行中会出现引导,按照提示输入项目的名称并直接选择 Svelte 框架即可。
3.3 运行项目
通过以下命令运行项目:

这样一来,整个 Vite + Svelte 的项目结构就搭建好了,开箱即用。整个项目的目录结构如下:
可以看到,整个项目结构基本和 Vue 类似,只是组件的后缀名改为了.svelte,新增了 vite.config.js 和 svelte.config.js 两个配置文件。
3.4 配置
Vite+Svelte 支持开箱即用,项目的初始配置也很简单,没有任何额外配置。
vite.config.js:用于配置 Vite 构建工具的行为,例如入口文件、输出目录、插件、devServer 等。
svelte.config.js:用于配置 Svelte 项目的各种选项,例如别名、预处理器、插件等。
在工程配置这里,唯一需要注意的是,Vite 默认情况打出的包体仅支持现代浏览器(支持 ESM ),如果要兼容低版本浏览器,可以使用官方提供的 @vitejs/plugin-legacy 插件:
更多配置项可参考官网的 Vite 配置文档和 Svelte 配置文档。
四、开发体验优化
项目搭建完成后,后续就是根据业务需求来开发 Svelte 组件和完善业务逻辑。整个开发过程中,体验感还是不错的。
详细的开发流程不再赘述,想要了解更多关于 Vite 和 Svelte 内容,可以参考 Vite 官方文档和 Svelte 官方文档。这里我们主要来看看 Vite 和 Svelte 分别在开发体验上带来的一些优化。
4.1 Vite 的开发体验太棒了
首先,Vite 的开发体验太棒了。它的构建速度极快,对开发效率有很明显的提升。
在开发环境下,Webpack 每次都需要对改动的部分进行重新编译打包,耗时几秒钟,而 Vite 则不需要重新打包,只需要把更新后的 ESM 代码交付给浏览器就 ok,几乎是即时更新。
同时在构建生产环境包时,也明显比原先的 Vue 项目要快了近 50%。别小看这一点速度的提升,让整个开发体验好了不少。
4.2 Svelte 的语法更优雅?
如果你跟随上面步骤搭建了项目,那你可以打开项目中的 Counter.svelte 文件看看,会发现 Svelte 组件的基本结构和 Vue 几乎一致,也是由 script、template 和 style 三部分组成,唯一的差异在于 Svelte 中不需要像 Vue 一样额外使用来作为 DOM 结构的根标签。
在语法上,Svelte 和 Vue 也非常相似,但个人更喜欢 Svelte 的一些简洁的语法设计,举一些例子:
插值表达式:Svelte 的插值表达式只需要单个{},而 Vue 则需要两层{{}},并且 Svelte 还有一些简写语法,例如 src={src} 可以简写为 {src}。
响应式:Svelte 声明的变量直接支持响应式,而在 Vue 中则需要使用 ref 来声明。
computed 计算属性 / watch 监听:Svelte 的 $: 代码块类似于 Vue 的 computed 计算属性和 watch 状态监听的结合体。
虽然差异没有很大,但这些简洁的语法,至少让我个人感觉写项目时更流畅,体验感很不错。
这些就是 Vite 和 Svelte 带来的开发体验上的一些优化。
五、Svelte 和 Vue 性能对比
上面我们了解了如何搭建 Vite+Svelte 项目,并感受到 Vite 和 Svelte 带来的开发体验优化。那接下来看看这套方案在实际项目中的性能表现。
为了对比 Svelte 和 Vue 之间的性能差异,我特地找了一个小型项目进行改造,用 Svelte 对它重写,并通过 ABTest 进行线上的性能数据对比。
5.1 首先,来看打包之后的 bundle 大小对比
Vue 的包体:

Svelte 的包体:


可以看到 Svelte 相比于 Vue,在包体大小上确实优化了不少,基本在 40%左右,效果很明显。
5.2 其次,看看本地的启动速度(FCP)对比
在本地进行 10 次平均性能测试,发现 Svelte 的 FCP 指标比 Vue 要快了约 46%,说明 Svelte 的首屏渲染速度比 Vue 快了不少,提升很明显。

下面这个录屏是对比两个页面首次打开时的效果,左侧为 Svelte,右侧为 Vue。

5.3 最后,看看线上的启动速度数据对比
我们通过 ABTest 进行线上的启动速度数据对比,在投放了 1 周后,数据结论如下:


可以看到 Svelte 在线上的启动速度表现也比 Vue 要快一些,优化程度约为 14.5%。
注意:这里的平均启动速度指标是我们团队内部定义的页面启动速度指标,计算方式:业务启动速度 = 页面加载完成时间 - 页面入口点击时间。由于我们是在客户端 App 中进行测试,因此该时间包含了客户端 webview 的启动时间。所以实际上 Svelte 对前端部分的启动速度优化程度可能会更高,参考前面的 FCP 指标的本地测试结果。
总之,对于小型项目,Svelte 在包体大小和启动速度上还是有不少提升的,如果你的项目对启动速度有强要求,也可以尝试使用 Svelte 来开发或改造,应该会有不错的效果。
六、Svelte 比 Vue 快在哪?
通过上面的数据分析,虽然我们了解到 Svelte 在构建小型项目时确实有更快的页面启动速度,但具体快在哪,还需要进一步深入分析。
我们可以通过 Chrome 的 devtool 来观察 Svelte 和 Vue 两者打包后的页面在加载流程上的差异。
Vue 页面加载流程:

Svelte 页面加载流程:

对比二者的加载流程,可以看到耗时上有两个主要的差异点:

因此,在小型项目中,Svelte 相比于 Vue,有两个明显的优势:
资源加载更快:由于包体较小,所以加载首屏 JS Bundle 时网络耗时更短。
Html/JS 解析执行更快:由于 Svelte 几乎无运行时,因此在执行相同业务逻辑时,解析执行耗时更短。并且在解析执行过程中,没有二次加载更多的首屏 JS、CSS 资源,因此整体的解析执行速度更快。
七、总结
总之,对于小型项目而言,Vite + Svelte 这对组合还是很不错的,既提升了开发效率,又优化了页面性能,更加“小巧灵动”。而且这两者的学习曲线都比较缓和,基本在 2-3 天内就可以完成学习加一个简单项目的改造。
一点题外话,很多时候大家会低估“技术尝新”的重要性,我们被困在团队圈定的“技术穹顶”中,永远用一个“套路”去实现所有业务,这会让我们感到疲乏、缺乏价值感和动力,甚至影响工作的投入程度,久而久之,整个团队也会在技术上变得迟滞。
所以在有机会时,要尽量合理地发掘和尝试新的技术方案,一方面是让自己保持技术活力,另一方面也是在加强团队的技术沉淀。
版权声明: 本文为 InfoQ 作者【vivo互联网技术】的原创文章。
原文链接:【http://xie.infoq.cn/article/a7244035f53bd1a6bb5669462】。文章转载请联系作者。
评论