Svelteを中心にVue.jsとの違いをざっくり掴む

# 始めに

## この記事でわかること

Svelte と Vue.js の違いがざっくりとわかります。
但しこの記事では、Svelteを中心に、比較材料としてVue.jsを扱うため、Svelte寄りの記事であることをご了承ください。
(そのためSvelte寄りな印象を受ける方もいらっしゃると思います。)

## この記事でわからないこと

Svelte と Vue.js のどちらが凄いのかについては言及しません。(それは観点によって異なるため)

## 対象読者

- フロントエンドの技術選定をしている方
- Svelteの概観を掴みたい かつ Vue.js の嗜みがある方

## 筆者について

大手SIerで5年間ソフトウエアエンジニアをした後、現在は [Flyle](https://flyle.io/jp) というスタートアップでフルスタックエンジニアをしています。
本業では、フロントエンドに Vue.js を使用しています。
趣味で Svelte のコントリビューターをしています。
最近 [MacBook Pro M1 Pro](https://www.apple.com/jp/macbook-pro-14-and-16/) を購入しました。
マシンは充分に速くなったので今度は僕が速くなる番だなと思いつつブラックフライデーに間違えて [Yogibo Max](https://yogibo.jp/products/detail/max) を購入してしまいました。
届くのが楽しみです。

# 本題

## 基本情報

両者とも、宣言的UIを実現するフロントエンドフレームワークです。
それぞれ以下のようなコードで記述します。
(Vue.js は SFC (Single File Components) で記述します。)

**Svelteのコードスタイル**

```HTML
<script>
	const name = 'world';
</script>

<h1 class="title">Hello {name}!</h1>

<style>
	.title {
		color: red;
	}
</style>
```

**Vue.js のコードスタイル**

```vuejs
<script setup>
	const name = 'world';
</script>

<template>
	<h1 class="title">Hello {{name}}!</h1>
</template>

<style>
	.title {
		color: red;
	}
</style>
```

Svelteの各機能を使用したサンプルは、[公式HP/Exapmles](https://svelte.dev/examples) で確認することができます。
また、Svelteのコードは [公式HP/REPL](https://svelte.dev/repl) で試すことができます。

Vue.js のコードは [ここ](https://sfc.vuejs.org/) で試すことができます。

### 主な違い
ここでは、主な違いとして以下の3個を挙げます。

**コンパイラ VS 仮想DOM**
[Svelte](https://svelte.dev/) はコンパイルによって多くの処理を実施して、小さく無駄のないランタイムコードを生成します。
[Vue.js](https://vuejs.org/) は [仮想DOM](https://reactjs.org/docs/faq-internals.html) を使用して、変更すべきDOMだけを更新します。

Svelteの作者の [Rich Harris](https://twitter.com/Rich_Harris) 氏 は、[仮想DOMは純粋なオーバーヘッド](https://svelte.jp/blog/virtual-dom-is-pure-overhead) と主張しています。
また、実際に[Rethinking reactivity](https://youtu.be/AdNJ3fydeao?t=1134) では、仮想DOMを使用しないことによる性能の差をデモしています。

**真のリアクティブ**
リアクティブとは、簡単に言えば、変数やオブジェクトが変化したら、それに関連する箇所も自動的に更新される特性のことを指します。
Svelteの作者のRich氏は、真のリアクティブのメタファーとして、スプレッドシートを挙げています。[講演はこちら](https://youtu.be/gJ2P6hGwcgo?t=15)
僕の解釈では、スプレッドシートの計算式がセルの値を変更すると計算式の結果も自動的に更新されるように、特別な記述なしに自然とリアクティブが実現されるべきだ、ということだと思います。

これをSvelteでは実現しています。具体的には `$` という記号を用いることでリアクティブを実現できます。

```HTML
<script>
	let count = 1;

	// the `$:` means 're-run whenever these values change'
	$: doubled = count * 2;
	$: quadrupled = doubled * 2;

	function handleClick() {
		count += 1;
	}
</script>

<button on:click={handleClick}>
	Count: {count}
</button>

<p>{count} * 2 = {doubled}</p>
<p>{doubled} * 2 = {quadrupled}</p>
```

[実際に動かせるサンブルコードはこちら](https://svelte.dev/examples#reactive-declarations)。

**少ないコード**
例えば、[Vuex](https://vuex.vuejs.org/) を使用して storeを管理する場合、[Flux](https://qiita.com/knhr__/items/5fec7571dab80e2dcd92#%E3%81%9D%E3%81%97%E3%81%A6flux) パターンに基づいて、定型的なプログラムを記述する必要があります。
Svelteの場合、そのような定型文は不要です。以下のように、`store` で管理している項目を読み取るには、単に `$` を変数名の前に付与するだけです。

```HTML
<script>
	import { writable } from 'svelte/store';
 	const count = writable(1);
</script>

<h1>The count is {$count}</h1>
```

Svelteでは、ボイラープレートを極力排除して、短くコードを記述できるように設計されています。
詳細な説明は、[コード量を減らす(Write less code)](https://svelte.jp/blog/write-less-code) を参照ください。

## 文法の観点

個人的に、全体的に Vue.js と Svelte は文法が似ていると思います。
少なくとも僕はすぐにSvelteの文法に対応することができました。

文法の詳細に関しては、以下の記事がわかりやすいなと感じたのでリンクを貼ります。
(車輪の再開発を避けると言いつつ勝手にリンクを貼って良いのでしょうか)

https://tech.smartcamp.co.jp/entry/svelte-feature-for-vuejs-engineer

## エコシステムの観点

ここでいうエコシステムとは、単に開発する上で便利な何か、という意味です。
どんなに良いプログラミング言語、フレームワークであっても、テキストエディタでしか開発できなければ開発しづらいです。
エコシステムが充実しているかどうかは、導入検討においては重要な観点の一つだと思います。

**開発開始時の体験**
Selteは、`npx degit sveltejs/template my-project` コマンドでプロジェクトを初期化します。
Vue.js の場合は [Vue CLI](https://cli.vuejs.org/) を使用するなら `vue create my-project` コマンドでプロジェクトを初期化します。

どちらも素晴らしい体験を提供しますが、Svelteの場合は、単に [テンプレート](https://github.com/sveltejs/template) をコピーするだけなので、Vue.jsよりも処理速度が速いです。


**開発中の体験**
Svelteは [language-tools](https://github.com/sveltejs/language-tools) によって VSCode拡張を通じて開発体験を提供しています。
具体的な機能は [ここ](https://github.com/sveltejs/language-tools/issues/83) で整理されています。
Vueは [vetur](https://github.com/vuejs/vetur) によって VSCode拡張を通じて開発体験を提供しています。
具体的な機能は[ここ](https://github.com/vuejs/vetur#features)で整理されています。

個人的な手触り感を含めた雑感を以下に記載します。

- 両方とも TypeScript をサポートしている
- 両方とも HMR　(Hot Module Replacement) をサポートしている
- Svelteはコンパイラ組み込みで未使用のCSSを検出する機能がある　(Vue.jsにはメンテナが作成した [非公式の ESLintプラグイン](https://github.com/future-architect/eslint-plugin-vue-scoped-css) があります。)
- Svelteはコンパイラ組み込みでアクセシビリティの検査機能がある ([該当のissue](https://github.com/sveltejs/svelte/issues/820))
- `language-tools` は、 `vetur` に影響を受けて作成されたツール。なので、長期的に見ても、`vetur` の良い特徴は、`language-tools`にも取り込まれると想像。 (つまり導入を躊躇するような開発体験の差異は将来に渡って発生しないと想定できる)

**デプロイの体験**
どちらも `npm` コマンドでバンドルすることができます。簡単です。

## アプリケーションフレームワークの観点

Svelte には [kit](https://kit.svelte.dev/) と呼ばれるフレームワークがあります。
これはまだベータ版ですが、もうすぐ1.0版がリリースされると思います。

Vue.js には [Nuxt.js](https://nuxtjs.org/) と呼ばれるフレームワークがあります。

私は kit のコントリビューターでもありますが、kitの利用者としては、簡単な自分のホームページを作った程度です。
また、Nuxt.js の経験は一切ありません。
なので、比較するほどの知識がありません。
😩😩😩

ただ、一つ言えることは、kitは事実として1.0版ではないため、短期でプロジェクトの立ち上げが求められる現場では、導入すべきではないと思います。kit側の問題や1.0版までに発生する破壊的変更への対応を求められる可能性があるからです。
また、ネットの情報も Nuxt.js と比較すると少ないため、問題に直面した際、自力でライブラリの内部実装を見てワークアラウンドを見つけたり、自力で kit にパッチを送るスキルが必要かもしれません。

## 成長性の観点

[Open Collective](https://opencollective.com/vuejs) を見ると、Vue.js は作者の[Evan You](https://github.com/yyx990803) 氏の他に、フルタイムのコミッターが少なくとも1名いるようです。
一方Svelteは先月、[作者の Rich Harris 氏が Vercel に移籍](https://vercel.com/blog/vercel-welcomes-rich-harris-creator-of-svelte) し、フルタイムコミッターとしてSvelteに参加しました。
直近は、kitを1.0版にするべく、活動されているようです。
SvelteもVue.js もフルタイムのコミッターがいると言う点において、今後も活発に活動が続いていくのではないかと思います。
よって、どちらを選択しても成長性や継続的なメンテナンスの点では心配は不要そうです。

ちなみに、現時点の Svelte と Vue.js の利用者数の外観を掴むために、米国の掲示板である、[reddit](https://www.reddit.com/) を見ると、記事執筆日時点で、Svelte のコミュニティには 11,033人が参加しており、 Vue.js のコミュニティには 79,776人が参加しています。よって現時点では、Vue.jsの方が圧倒的にユーザーは多そうです。

しかし一方で、[Stack Overflow](https://insights.stackoverflow.com/survey/2021#section-most-loved-dreaded-and-wanted-web-frameworks) の調査によると、最も愛されるフレームワークの一位は Svelteでした。(Vue.js は5位)
今後 Svelte の勢いが増して Vue.js との差が縮まっていく可能性があります。

## 人材の観点

記事執筆日時点で、
例えば、米国の求人サイトの[indeed.com](https://www.indeed.com/)で、[Vue.jsの求人](https://www.indeed.com/jobs?q=Vue.js&l&vjk=5a75e1e57727decd) を調べると、4,400件ヒットします。
一方で、[Svelteの求人](https://www.indeed.com/jobs?q=Svelte&l&vjk=1a5fb733a3879396) を調べると、484件ヒットします。
米国のトレンドが数年遅れて日本に来ることを考えても、数年は、圧倒的に Vue.js の方が求人が多そうです。
求人が多いということは、開発者の数も多いといってよいと思います。
よって、例えば大規模な開発を想定した現場では、Svelteの開発者を確保するのに苦労する可能性があります。

## 個人的に気づいたその他の観点

- Svelteは公式HPに多くのサンプルコードやREPLがあるので、初学者にとって理解がしやすい。
- SvelteはCSSを子コンポーネントに伝搬することができない ([該当のRFC](https://github.com/sveltejs/rfcs/pull/22))

**ランタイムのサイズについて**
Svelteはコンパイルによって多くの処理をするために生成されるランタイムコードが小さいと言われているが、大きなアプリになると逆にランタイムコードが大きくなるようです。(例えば、Vue.jsの作者である [Evan You氏による調査](https://github.com/yyx990803/vue-svelte-size-analysis))
しかし、個人的には、5Gの時代にバンドルサイズの細かな違いを気にする必要があるのか疑問なのと、DOM更新時に実行するJavaScriptが少ないことの方が重要ではないかと思いました。

また、SPAは初回ロード時に大きなファイルをダウンロードする必要があるため、ロード時の体験が悪いとされています。
これに対して kit や Nuxt.js では JAMstack などの技術を用いて、ユーザー体験を向上しています。
今後、SPAよりも SSG / JAMstack が主流になっていくとすると、大きなアプリをバンドルしたランタイムコードを生成すること自体がないので、これは実際の問題ではないのではないかと思います。

# まとめ

- Svelteは、仮想DOMを使用しないので高性能
- Svelteは、ボイラープレートを極力排除して短く書けるように工夫されている
- 開発体験はどちらも素晴らしい (と思う)
- kitはまだベータ版
- どちらもフルタイムコミッターがいるので将来性は今のところ安心
- Vue.js の求人の方が断然多いので大規模なチームを目指す場合はVue.jsが有利

間違いや追記、削除、編集すべき点があればコメントをいただけると幸いです。