blog.takurinton.dev

Svelte と SPA

2022-01-14

こんにちは

どうも、僕です。
最近、Svelte が市民権を獲得してきているようで、フロントエンド開発において、選択肢に入ってくる機会が増えてきたと思います。
また、Twitter などでも、React よりも Svelte!のような内容のものや、Svelte を勉強してみるといった内容のものが増えてきたように感じます。
それ自体はいいことであり、Svelte が選択肢に入ってくることは面白いとは思うのですが、React と Svelte を同列に考えているツイートや文章を目にすることもあり、難しい感情になっています。

Svelte のユースケースは、他のフロントエンドフレームワークよりも限定的であり、局所的に最適化されたもののように自分は感じます。
Svelte をユースケースという観点から見て、自分なりに考えたことをまとめます。マサカリ・指摘・アドバイス・同意見等のコミュニケーションや意見は歓迎です。

Svelte とは

svelte 公式ドキュメント から引用。

Svelteはユーザーインタフェースを構築する先鋭的で新しいアプローチです。ReactやVueのような 従来のフレームワークがその作業の大部分を ブラウザ で行うのに対し、 Svelteはその作業を アプリをビルドする際の コンパイル時 に行います。

Svelteは仮想DOMによる差分検出のようなテクニックを使用する代わりに、 アプリケーションの状態が変化したときにDOMを外科的に更新するコードを生成します。

宣言的にUIを書くことができる、コンパイラです。
コードの記述量が少なく、書きやすいことで知られ、バンドルサイズも小さいため、小規模のアプリケーションに適しています。

React Native や Vue Native 同様、 Svelte Native も存在します。ライフサイクルは知りません。(そもそも React Native や Vue Native のこともほぼ知らないので)

しかし、

Svelte Native shifts that work into a compile step that happens when you build your app.

とあるので、コンパイラであることは代わりないようです。

Svelte は SPA で活躍できるのか

答えは、No と言いたいです。(が、必ずしも大きな声で No とは言えないと思っています。 )

理由は主に以下の2つだと思っています。

バンドルサイズに難がある

Svelte はバンドルサイズが小さいことや、コードの記述量が少ないことが売りなのは、上で書きました。

とはいえ、Svelte はコンパイラです。他のライブラリのような、木を展開して状態を管理する方法ではなく、Svelte の syntax どおりのコードを生の html/css/JavaScript に吐き出します。
つまり、コードの記述量に対してバンドルサイズが線形的に上昇します。
なるべく小さく小さくしたいときには Svelte は非常に効果を発揮しますが、大規模なアプリケーションになればなるほど、バンドルサイズという文脈で考えたときに、他のフレームワークよりも不利になります。

ベンチマーク

Svelte はバンドルサイズが小さく、React と Vue などと比較されることが多々ありますが、実際に Vue の作者である Evan You 氏が Svelte と Vue のバンドルサイズの特異点を調べるためのベンチマークツールを作成していました。

yyx990803/vue-svelte-size-analysiss

このベンチマークに関する日本語の解説として、Zenn に [Draft]VueとSvelteのサイズを比較検証した「vue-svelte-size-analysis」を掘っていく とスクラップが生えていました。めちゃくちゃわかりやすいので一読してみるとそれぞれの特徴や温度感が見えてくるかもしれません。

エコシステムが未発達

Svelte は最近名前を聞くようにはなってきたが、周辺のライブラリやエコシステム自体はまだまだ未発達だと思っています。
とはいえ、採用事例はちょこちょこ聞くので、エコシステムの部分や痒い所に手が届く君を内製していたり、ルールをしっかり決めた上で開発をするとそこまで困らないのかなとは思います。 ここは発達の余地がありますし、開発者側でどうにかなる問題なので、自分が完全に Svelte は SPA に向いてないと言い切れない部分であります。
また、作者が vercel にジョインしたことで、さらに開発が進むことが期待できるので、まだまだわからないというのが現状です。

Svelte のユースケース

ではどのような時に Svelte は実力を最大限に出すことができるのでしょうか。
おそらく、サードパーティのモーダルであったり、社内で使い回すようなコンポーネントとして提供する時です。

サードパーティのモーダルなどを埋め込むときに、埋め込み先のサイトのパフォーマンスを著しく低下させるのは避けるべきであり、好ましくありません。そのようなときに、Svelte のように小さく作り、埋め込むというようなことをすると、埋め込み先のサイトのパフォーマンスに影響を与えにくくすることができ、より良いモーダルとして扱うことができるようになります。

また、サードパーティモーダルの問題点として、既存の style とぶつかってしまうという問題点もありますが、v3.40.0 からは shadowRoot を target に指定することができるようになり、その心配も無くなりました。
render Svelte components inside shadow dom #5869

このように、SPA としてロジックを管理するという用途ではなく、部分的に導入するほうが個人的には Svelte が力を発揮すると考えます。

Svelte のいいなと思うところ

とはいえ、自分自身は Svelte のファンであり、今後に期待しています。
理由としては、以下のようなものがあります。

バンドルサイズの小ささ

やはりこれです。コード記述量が少ないこともそうですが、コードというのは書けば書くほどバグを生む確率が上がり、バンドルサイズが大きければ大きいほどユーザーの体験を低下させます。それを防ぐために、人間はコードのルールを決め、lint で弾き、バンドルファイルを分割し、適切に対処します。
Svelte は、デフォルトでサイズが小さく、シンプルな SPA サイトであれば 20KB ほど、ペライチだったり、部分的に差し込む用途であればそれ以上に小さくなります。
また、vdom アプリケーションは、vdom のコード自体がアプリケーションコードに含まれますが、Svelte はコンパイラのため、そのようなこともありません、非常に軽量で動作します。

language server による構文チェック

Svelte は公式が language-tools を用意していて、ここで様々な構文をチェックしてくれます。例えば、 svelte-check では、コンパイル時にコードレベルでわかる範囲の a11y をチェックし、VSCode 上で警告を出してくれます。

例えば、img タグに alt 属性がなかった場合は warning を出してくれます。

また、さまざまなオプションを指定可能で、 tsconfig を読んでくれたりもするのでだいぶ便利です。Svelte は TypeScript のサポートが来てから language server 周りがだいぶ発達して使いやすくなった気がします。

また、Svelte は JavaScript(TypeScript) 、CSS の未使用コードをコンパイル時に消してくれます。 デフォルトでツリーシェイクの機能が備わっていることは非常に魅力的に感じますし、助かる機能です。

ペライチならめちゃくちゃ使える

LP やポートフォリオなど、ペライチで十分だけど React を使うほどでもない、そして軽く作りたいけど動きをつけたい、vanillaJS は書きたくない、というような用途の場合、Svelte で書くと非常にやりやすいです。
吐き出されるものは html/css/JavaScript ですし、リッチな UI が簡単に使えたりします。また、上で書いたようにツリーシェイクをしてくれるのでコンパイル時にサイズが抑えられます。
マークアップに書き方が近いので、デザイナーにも好かれるのではないかなと思います。

まとめ

React、Vue、Svelte など、話題のライブラリは多くありますが、それぞれが解決したい問題は違い、それぞれにあったユースケースがあります。
今回は、Svelte は SPA 向きかどうかという文脈でユースケースについて話しましたが、Svelte で SPA を書くことによって解決できる課題もひょっとしたらあるかもしれませんし、Svelte がこれから先、SPA を作りやすくする方向や SSR first な方向に舵を切る可能性も0とは言い切れません。
この記事は、現時点での僕の見解であり、それ以外の何者でもありません。
個人的に、Svelte は好きですし、期待してるので動向に注目したいと思います!