Svelte是这几年很火的前端框架,以编译时优化、无虚拟DOM、代码量少著称。作者Rich Harris是Rollup的作者,2016年发布了Svelte,2019年Svelte 3发布后开始火起来,2021年已经是GitHub上star数增长最快的前端框架之一。

我从2018年开始关注Svelte,2019年Svelte 3发布后正式用到项目里,到现在用了三年多了。做过几个中小型项目,有后台管理系统,有企业官网,有数据可视化页面,也踩了很多坑。从最开始的惊艳,到中间的怀疑,再到现在的理性看待,我对Svelte有了很多体会。

这篇文章分享用了三年Svelte后总结的经验和道理,包括Svelte的优缺点、适用场景、和React/Vue的对比,以及给新手的建议。希望能帮正在考虑用Svelte的朋友做决策。

先说明一下,以下是我的个人体验和观点,比较主观,不同的项目和团队感受可能不一样。Svelte还在快速发展,我说的可能在未来版本会变化。

一、我为什么选择Svelte

先说说我为什么选择Svelte,而不是React或Vue。

2019年的时候,我做一个中小型的企业官网项目,需要交互比较多,页面也不少。当时React和Vue都很成熟了,但我想试试新东西。Svelte 3刚发布不久,口碑很好,我就试着用了一下,结果一发不可收拾。

选择Svelte的原因主要有几个:

第一,代码量少。Svelte的语法非常简洁,一个组件就是一个.svelte文件,包含HTML、CSS、JS,不需要写类组件或者函数组件的模板代码。响应式数据用$:标记就行,不需要useState、useEffect这些Hook,也不需要this.setState。同样的功能,Svelte的代码量比React少30%到50%,写起来很爽。

第二,性能好。Svelte是编译时框架,在构建的时候把组件编译成原生的DOM操作,没有虚拟DOM,运行时开销小。打包出来的bundle也小,因为不需要带整个框架的运行时。对于首屏加载要求高的项目,Svelte很有优势。

第三,学习成本低。Svelte的语法很接近原生HTML/CSS/JS,只要会前端基础就能很快上手。不像React需要理解JSX、Hooks、状态管理这些概念,也不像Vue需要理解指令、响应式原理。Svelte的学习曲线很平缓。

第四,内置CSS作用域和动画。Svelte的CSS默认就是组件作用域的,不需要CSS Modules或者styled-components。动画和过渡也是内置的,用transition和animate指令就能做很流畅的动画,不需要额外的动画库。

当时用Svelte做那个项目,开发效率很高,代码也很清爽,性能也不错。从那以后我就开始在更多项目里用Svelte了。

二、Svelte的优点

用了三年,我觉得Svelte的优点确实很突出。

1. 语法简洁,开发效率高

这是Svelte最大的优点。写Svelte组件真的很舒服,代码量少,逻辑清晰。比如一个计数器组件:

<script>
  let count = 0;
  function increment() {
    count++;
  }
</script>

<button on:click={increment}>
  Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

同样的功能用React写,需要import React、useState,代码量多不少。Svelte的写法更接近原生,心智负担小。

响应式也很简单,用$:标记响应式语句:

<script>
  let count = 0;
  $: doubled = count * 2;
  $: if (count > 10) {
    console.log('count is too big');
  }
</script>

count变了,doubled自动更新,if语句也自动重新执行。不需要useEffect依赖数组,也不需要watch,非常直观。

2. 性能好,包体积小

Svelte编译时优化,没有虚拟DOM的diff开销,运行时性能很好。尤其是更新频繁的场景,Svelte直接更新对应的DOM,比虚拟DOM的diff更高效。

包体积也是Svelte的优势。一个简单的Svelte应用打包后可能只有几KB,而React应用光React和ReactDOM就有几十KB(gzip后)。对于小项目和对首屏加载要求高的项目,Svelte很有优势。

我做过一个企业官网,用Svelte写的,首屏JS只有20多KB,加载非常快,Lighthouse性能评分95以上。如果用React写,估计要大不少。

3. CSS作用域和动画内置

Svelte的CSS默认就是组件作用域的,写起来很方便,不用担心样式污染。也支持全局样式(:global()),需要的时候可以用。

动画和过渡是Svelte的一大亮点。内置了fade、slide、scale等过渡效果,还有spring和tweened动画,用起来很简单:

<script>
  import { fade, slide } from 'svelte/transition';
  let show = true;
</script>

{#if show}
  <div transition:fade>Hello</div>
{/if}

几行代码就能做出很流畅的动画,不需要额外的动画库。这对于需要动画效果的项目来说非常方便。

4. 学习成本低,上手快

Svelte的学习曲线很平缓。只要会HTML、CSS、JavaScript,看一遍官方教程就能写组件了。不需要理解JSX、虚拟DOM、Hooks、Vue的指令系统这些概念。

我带过几个新人,学Svelte一两天就能上手写业务组件,学React可能要一两周。对于团队来说,Svelte的培训成本比较低。

5. SvelteKit越来越成熟

Svelte的全栈框架SvelteKit(类似Next.js)在2021年已经比较成熟了,支持SSR、SSG、路由、API routes等功能。用SvelteKit可以快速开发全栈应用,部署也方便。SvelteKit的出现弥补了Svelte在工程化方面的短板。

三、Svelte的缺点和坑

说了优点,再说说缺点和坑,这部分可能更有参考价值。Svelte不是银弹,用了三年我也遇到了不少问题。

1. 生态不如React和Vue

这是Svelte最大的问题。虽然Svelte发展很快,但生态和React、Vue比还是差不少。

组件库方面,React有Ant Design、Material UI、Chakra UI等一大堆成熟的组件库,Vue有Element UI、Vuetify等。Svelte的组件库选择少很多,比较知名的有Svelte Material UI、Smelte、Carbon Components Svelte,但成熟度和完善度都不如React和Vue的组件库。很多时候需要自己写组件,或者用第三方的小库。

第三方库方面,很多前端库只提供React和Vue的封装,没有Svelte的。比如一些图表库、编辑器、地图SDK,虽然可以用原生JS版本自己封装,但总是麻烦一些。

社区方面,Svelte的社区比React和Vue小,遇到问题搜索到的解决方案少,Stack Overflow上的问答也少。有时候遇到一个bug,搜半天找不到答案,只能自己看源码或者去Discord问。

2. 类型Script支持不够完善

Svelte对TypeScript的支持在2021年有了很大改善,但还是不如React和Vue完善。.svelte文件里的TypeScript类型检查有时候会出问题,IDE的智能提示也不如.tsx文件。类型定义有时候需要自己写,比较麻烦。

对于大型项目,TypeScript支持很重要。Svelte在这方面还需要改进。不过Svelte团队一直在改善TypeScript支持,未来应该会越来越好。

3. 大型项目的状态管理和架构

Svelte内置了store做状态管理,简单好用,但对于复杂的大型项目,store的能力有限。没有Redux DevTools那样强大的调试工具,也没有成熟的状态管理最佳实践。大型项目的状态管理需要自己设计,容易写乱。

React有Redux、Zustand、Recoil等成熟的状态管理方案,Vue有Vuex/Pinia,都有完善的工具和最佳实践。Svelte在这方面还比较初级。

另外,Svelte的组件通信方式比较简单(props、事件、store、context),对于复杂的跨组件通信,有时候会觉得不够用。大型项目的架构设计需要更多的经验和规范。

4. 就业市场和招聘

这是很现实的问题。用Svelte的公司比用React和Vue的少很多,招聘市场上Svelte的岗位也少。如果你是为了找工作学前端,还是学React或Vue更稳妥。

如果你的团队用Svelte,招人也比较难,会Svelte的人少,需要招进来再培训。虽然Svelte学习成本低,但还是有成本。

我自己的情况是,个人项目和小公司项目用Svelte没问题,但如果去大公司,基本还是React和Vue的天下。

5. 一些小坑

用了三年,还遇到了一些小坑:

  • 响应式的$:有时候会有意外的触发,需要注意依赖关系。
  • 组件的事件转发(event forwarding)有时候会搞混,需要仔细处理。
  • 插槽(slot)的功能不如Vue的插槽强大,命名插槽和作用域插槽用起来有点别扭。
  • 第三方UI库少,很多时候要自己写组件,开发效率在复杂项目里反而不如React(因为React有成熟的组件库)。
  • Svelte的编译器有时候会有奇怪的bug,虽然不多,但遇到了比较难排查。

四、Svelte vs React vs Vue

很多人问我Svelte和React、Vue怎么选。我的看法是:

React:生态最成熟,就业市场最好,适合大型项目和团队协作。Hooks虽然有学习成本,但一旦掌握非常灵活。组件库和工具链最完善。缺点是代码量多,心智负担重,性能需要手动优化(memo、useMemo等)。

Vue:中文社区好,国内用的公司多,文档友好,学习曲线平缓。Vue 3的Composition API很强大,性能也不错。组件库丰富(Element Plus等)。缺点是国际影响力不如React,高级进阶的资料相对少。

Svelte:语法最简洁,开发体验好,性能好包体积小。适合中小型项目、个人项目、对性能和包体积要求高的项目。缺点是生态不够成熟,大型项目和团队协作的工具链不如React和Vue。

我的建议是:

  • 如果是找工作或者做大型企业项目,选React或Vue。
  • 如果是个人项目、小团队项目、中小型网站、对包体积敏感的项目,Svelte是很好的选择。
  • 如果团队已经有React或Vue的技术栈和积累,不要轻易换Svelte,迁移成本和生态成本要考虑。
  • 如果你是前端新手,先学React或Vue打基础,再学Svelte拓展视野。

五、用了三年才明白的道理

最后,说说用了三年Svelte才明白的一些道理,这些不仅适用于Svelte,也适用于其他技术选型。

第一,没有最好的框架,只有最合适的框架。 刚用Svelte的时候,我觉得Svelte哪都好,想把所有项目都换成Svelte。后来发现,有些项目用Svelte并不合适,比如需要大量成熟组件库的后台管理系统,用React加Ant Design效率更高。框架只是工具,要根据项目需求和团队情况选,不要盲目追新。

第二,生态比框架本身更重要。 框架的语法和性能差异其实没有想象中那么大,真正影响开发效率的是生态。有没有成熟的组件库、有没有丰富的第三方工具、有没有活跃的社区、遇到问题能不能快速找到答案,这些比框架本身的语法简洁与否重要得多。Svelte语法再好,生态跟不上,在某些场景下就是不如React。

第三,学习成本要算总账。 Svelte本身学习成本低,但如果生态不完善,需要自己造轮子、自己封装组件、自己解决问题,整体的学习和使用成本反而高。React本身学习成本高,但生态成熟,很多东西有现成的方案,长期来看效率可能更高。选型的时候要算总账,不要只看框架本身的学习成本。

第四,小项目用Svelte真的很爽。 虽然说了Svelte的很多缺点,但在中小型项目里,Svelte真的很爽。代码少,性能好,开发快,没有那么多繁琐的东西。做个官网、做个小工具、做个活动页,Svelte是非常好的选择。我现在个人项目基本都用Svelte,效率很高。

第五,技术选型要考虑团队和未来。 选框架不只是看技术,还要看团队会不会、好不好招人、未来好不好维护。如果团队都熟悉React,强行换Svelte,大家要重新学,招人也难,反而降低效率。技术选型是团队决策,不是个人喜好。

第六,保持学习,但不要盲目跟风。 前端框架更新很快,每年都有新东西出来。保持学习新东西是好事,但不要盲目跟风,看到新框架就想换。要理性评估新技术的优缺点和适用场景,在合适的项目里用合适的技术。Svelte是好框架,但不是所有项目都适合。

六、给想入坑Svelte的人的建议

最后,给想入坑Svelte的朋友一些建议。

第一,先看官方教程。Svelte的官方教程做得非常好,交互式的,边学边练,几个小时就能入门。不要上来就看第三方教程,官方教程是最好的入门材料。

第二,从小项目开始。不要一上来就用Svelte做大型项目,先从个人项目、小工具、活动页开始,熟悉Svelte的语法和特性,积累经验。

第三,善用Svelte REPL。Svelte官网有在线REPL,可以快速测试代码片段,分享给别人。遇到问题可以在REPL里复现,方便求助。

第四,关注SvelteKit。如果做全栈应用,直接用SvelteKit,不要自己搭工程化。SvelteKit是官方维护的,越来越成熟。

第五,加入社区。Svelte的Discord社区很活跃,遇到问题可以去问。也可以关注Svelte的GitHub和博客,了解最新动态。

第六,理性看待。不要因为Svelte火就盲目用,也不要因为生态不如React就否定它。根据项目需求和团队情况做决策,适合的就是最好的。

七、写在最后

用了三年Svelte,我对它的感情很复杂。一方面,我真的很喜欢Svelte的简洁和优雅,写Svelte代码是一种享受,小项目里效率很高。另一方面,我也清楚它的不足,生态不够成熟,大型项目和团队协作还有差距。

Svelte不是银弹,它不能解决所有问题,也不适合所有场景。但它确实是一个优秀的前端框架,在适合的场景下能带来很好的开发体验和性能。

2021年了,前端框架的格局基本是React、Vue、Svelte三足鼎立,还有Solid、Astro等新框架在崛起。前端的世界永远不缺新东西,保持学习,理性选择,才是正确的态度。

如果你还没试过Svelte,我建议你找个小项目试试,体验一下编译时框架的魅力。也许你会像我一样,一用就喜欢上。但也要清楚它的边界,不要盲目把所有项目都换成Svelte。

技术在变,但解决问题的本质不变。选什么框架不重要,重要的是用合适的工具解决实际的问题,做出好的产品。

祝大家都能找到适合自己的技术栈,写代码写得开心,做产品做得成功。