この記事は さいが崖 Advent Calendar 2025 17日目 の記事です。
Vue 3.6 なんかすごそう
こんにちは。ここのえです。
Vueの次期バージョンである 3.6 のalpha版が、今年7月12日にリリースされました。Vueを使っていない人にとっては「あ、そう……」という感想しか出てこないと思います(それはそう)。マイナーバージョンの更新ですが、今回採用される Vapor Mode と alien-signals によってVueの開発体験が大きく変わります。簡単に言うと、めちゃくちゃ早くなります。
本記事ではVue 3.6の主要機能であるこの二点に絞って、解説とサンプルコード・現alphaバージョンでの注意点について説明していきます。
Vapor Modeとは?
Vapor Mode(蒸気モード1)は、Vueのシングルファイルコンポーネント (.vue)のための新しいコンパイルモードで、バンドルサイズの削減・パフォーマンスの向上を目的としています。
今までのVueでは仮想DOMを用いてDOMの変更を行っていましたが、Vapor Modeでは仮想DOMを廃止し、solid.js と同様にDOMを直接操作します。ただしコンポーネントの実装においては、これまでと変わらない .vue ファイルで、 ref や computed がいつも通り使えます。
Vapor Modeはコンパイルモードの一種であるため、オプトイン機能として提供されます。アプリケーション全体に適用する必要はなく、コンポーネント単位で有効・無効化でき、既存のSFCと混在して使用することができます。そのため既存のライブラリと共存することもでき、段階的に移行できる点もgoodです。
注意点としては、Composition API形式のコンポーネントしか対応していません。まさか2025年の新規実装で今更Options APIでVueを書いていることはないと思いますが、Vue 2.x時代から既存のプロジェクトをアップグレードしている場合は注意が必要です。いい機会なので、そろそろComposition APIへの移行はどうでしょうか……?(小声)
Vapor Modeの使い方(1) 仮想DOMと一緒にハイブリッドに使う
通常の仮想DOMと混在させて使う場合は、 main.ts で vaporInteropPlugin を読み込みます。3.6が出てしばらくの間はライブラリの対応待ちになるので、基本的にこの使い方がメインになると思います。
import { createApp, vaporInteropPlugin } from 'vue'
import App from './App.vue'
createApp(App)
.use(vaporInteropPlugin) // プラグインとして読み込む
.mount('#app')Vapor Modeを使うコンポーネントは、<script setup vapor> とします。
<script setup vapor lang="ts">
import { ref } from 'vue'
const count = ref(0)
</script>
<template>
<div>
<h2>Vapor Counter</h2>
<p>これはVapor Modeのコンポーネントです</p>
<button @click="count++">count is: {{ count }}</button>
</div>
</template>
呼び出し元のコードは普通にコンポーネントを呼び出せばOKです。
<script setup lang="ts">
import VaporTest from '@/VaporTest.vue'
</script>
<template>
<h1>Vapor Test App</h1>
<p>ここは普通のVDOMです</p>
<VaporTest />
</template>
<style scoped></style>
無事表示されました。

Vapor Modeの使い方(2) 全部Vapor Modeにする
「俺は常に最新を走ってるからよ……」という漢気プログラミングをするならアプリケーション全体をVapor Modeにすることもできます。main.ts で createVaporApp() します。
import { createVaporApp } from 'vue'
import App from './App.vue'
createVaporApp(App).mount('#app')最初に読み込む App.vue から、読み込むコンポーネントはすべて <script setup vapor> でなければいけません。
<script setup vapor lang="ts">
import VaporTest from '@/VaporTest.vue'
</script>
<template>
<h1>Vapor Test App</h1>
<p>App.vueもvaporにする必要があります</p>
<VaporTest />
</template>
<style scoped></style>で、実際速くなるの?
速くなるかならないか、それが一番気になるところでしょう。js-framework-benchmark の結果を見てみましょう。vue-vaporを軸にしてcompareすると以下の通りです。

仮想DOMを使った今までのVueと比べても、明らかに速度が出ています。solid, svelteにはやや負けているものの、そこまで差は離れていないので許容できるレベルの速度差といったところでしょうか。ただclear rowsについてはvue-vaporが恐ろしく速く、solidにも大差をつけて勝っています。
ではメモリのアロケーションと、転送サイズについてはどうでしょうか?

仮想DOMに割いていたメモリが削減されたおかげで、消費量が抑えられています。全体的に見てもsolid, svelteとほぼ同水準まで下がっています。転送サイズについてはさすがにsolidには遠く及びませんが、compressed sizeはそこそこ健闘してるといったところでしょうか。早くなったとはいえ、first paintがまだ遅いですね。この辺りは3.6正式版のベンチマークで改善がみられるか期待したいですね。
alien-signals
ちがいます。
こっちです。
alien-signals はVue 3.6より導入されるリアクティビティシステムです。こちらはVapor Modeとは関係なく、独立した別機能なのでアップデートするだけで恩恵が受けられます。
開発者のJohnson氏はVue 3.4のリアクティビティシステム最適化に関わっていた方で、Push-Pull方式のsignalアルゴリズムを採用しています。コアになるアルゴリズムにおいて「Array/Set/Mapを使用しない」、「関数の再帰を禁止する」といった制約で徹底した最適化を行うことで、最大限のパフォーマンスを引き出しているそうです。
肝心の速度ですが、上記のalien-signalsのリポジトリにあるVue 3.4との比較を見てもわかる通り、圧倒的に速くなっています。加えて、リアクティビティシステムのベンチマークであるJS Reactivity Benchmarkの結果ではSolidやPreact Signals、Svelte 5を抜いて最速です。現verのVueと比べると250msぐらい速いです。そんなに早いのかコレ。
こちらはVue 3.6にするだけで速度差を実感できると思うので、ぜひ既存のプロジェクトをアップグレードして試してみてください。
まとめ
今回はVue 3.6の主要機能であるVapor Modeとalien-signalsについて紹介しました。Vapor Modeは昨年、Misskey開発者のしゅいろさんの記事で知ったのですが、3.6の記事を書こうとしたら正式に採用されており「ついに来たか……」という感じです。全体的なトレンドを見ても、メモリ削減・パフォーマンス向上のためのVDOM脱却の流れなのかなあとは思います。
Vue 3.6のVapor Mode・alien-signalsの詳細については、こちらが非常に分かりやすく、これまでのVueの歴史についても学べるのでオススメです。正直これを読めば、私の記事は全く読まなくてもいいかもしれませんが……
Vue 3.6は特にパフォーマンスの向上に力が入ってるなあという印象です。もしかしたら、「Vueは遅いよね」という定説はもはや過去のものになりつつあるのかもしれません……。というかそうあってほしい。世の中全部とは言わないけど50%ぐらいVueのプロジェクトになってほしい。
参考
- 【日本語版】All we know about Vue 3’s Vapor Mode
- Vue 3.6 ALPHA is out! All you need to know 👀
- Vue 3.6: Vapor Mode opening virtual DOM era
- Webフロントエンドでのリアクティビティからalien-signalsを知ろう
- リアクティブシステムの変遷から理解するalien-signals
- vaporwave の “vapor” と同じ、”蒸気”の意です ↩︎
- https://github.com/stackblitz/alien-signals?tab=readme-ov-file#background ↩︎

コメント