Vapor Modeは、Vue.js の仮想 DOM を持たないコンパイル戦略の一つであり、コードを効率的な JavaScript 出力にコンパイルし、メモリを使用し、実行時の負荷を軽減し、コンパイル後のサイズを小さくすることで、Vue.js アプリケーションのパフォーマンスを向上させます。
Vue Vapor SFC Playgroundを使用して Vapor Mode を体験することができます。
Vue Volar Template Explorerを使用してテンプレートの変換方法を探究することができます。
自分の Vite プロジェクトで Vapor Mode を有効にする方法#
デモはsxzz/vue-vapor-demoを参照してください。
vue と @vitejs/plugin-vue のバージョンを vapor 版にアップグレードします
package.json
"dependencies": {
"vue": "npm:@vue-vapor/vue@latest"
},
"devDependencies": {
"@vitejs/plugin-vue": "npm:@vue-vapor/vite-plugin-vue@latest",
}
createApp を createVaporApp に変更します
import { createVaporApp } from 'vue/vapor'
import './style.css'
import App from './App.vue'
const create = createVaporApp
create(App as any).mount('#app')
Vapor が有効かどうかをチェックする方法#
import { ref, getCurrentInstance } from 'vue'
const msg = ref('Hello World!')
// @ts-expect-error
const isVapor = getCurrentInstance().vapor
Vapor Mode でコンパイルされた js を探索する#
ここでは、Vapor Mode のコンパイル結果を探索するために、非常にシンプルな vue ファイルを作成します。
<script setup lang="ts">
import { ref } from 'vue'
const msg = ref('Hello World!')
const classes = ref('p')
</script>
<template>
<h1 :class="classes">{{ msg }}</h1>
</template>
VAPOR ON
/* Analyzed bindings: {
"ref": "setup-const",
"msg": "setup-ref"
} */
import { defineComponent as _defineComponent } from 'vue/vapor'
import { renderEffect as _renderEffect, setText as _setText, setClass as _setClass, template as _template } from 'vue/vapor';
const t0 = _template("<h1></h1>")
import { ref } from 'vue'
const __sfc__ = _defineComponent({
vapor: true,
__name: 'App',
setup(__props) {
const msg = ref('Hello World!')
return (() => {
const n0 = t0()
_renderEffect(() => _setText(n0, msg.value))
_renderEffect(() => _setClass(n0, classes.value))
return n0
})()
}
})
__sfc__.__file = "src/App.vue"
export default __sfc__
VAPOR OFF
/* Analyzed bindings: {
"ref": "setup-const",
"msg": "setup-ref"
} */
import { defineComponent as _defineComponent } from 'vue'
import { toDisplayString as _toDisplayString, normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
import { ref } from 'vue'
const __sfc__ = _defineComponent({
__name: 'App',
setup(__props) {
const msg = ref('Hello World!')
const classes = ref('p')
return (_ctx,_cache) => {
return (_openBlock(), _createElementBlock("h1", {
class: _normalizeClass(classes.value)
}, _toDisplayString(msg.value), 3 /* TEXT, CLASS */))
}
}
})
__sfc__.__file = "src/App.vue"
export default __sfc__
Vapor Mode が有効な場合のコンパイル結果の特徴:#
- テンプレートのコンパイル:
_template
関数を使用してテンプレートを定義し、これは Vue 内部でテンプレートを生成するために使用される関数です。 - レンダリング効果:
_renderEffect
を使用して、リアクティブデータのレンダリングを処理し、Vapor Mode 下でより効率的に DOM を更新します。 - テキストの設定:
_setText
関数を使用して、要素のテキストコンテンツを設定します。これは Vapor Mode がテキストノードを更新するためにより直接的な方法を使用していることを示しています。
Vapor Mode が無効な場合のコンパイル結果の特徴:#
- テンプレートのコンパイル:従来の
createElementBlock
を使用して要素を作成します。これは、Vue の標準的なコンパイルプロセスで仮想 DOM ノードを生成するための関数です。 - テキストの変換:
_toDisplayString
を使用してデータを表示可能な文字列に変換します。これは、データバインディングを処理する際の Vue の標準的な方法です。 - ブロックレベルのレンダリング:
_openBlock
を使用してブロックレベルのレンダリングを処理します。これは、複数の同じレベルのノードを処理する際の Vue の標準的な方法です。
コンパイル結果の比較:#
- パフォーマンスの最適化:Vapor Mode のコンパイル結果は、実行時の DOM 操作を減らし、レンダリング効率を向上させるために、より多くの最適化が施されています。
- API の使用:Vapor Mode では、
_renderEffect
や_setText
など、標準モードとは異なる API が使用されており、より効率的なレンダリングロジックを実現しています。
Vapor Mode API#
- renderEffect:この関数は、クラス、属性、およびテキストの変更を監視し、これらのノードを正しく変更するための役割を担います。
- setClass:その名前からもわかるように、この関数は要素にクラスを割り当てます。2 つの引数、要素(またはノード)と要素に割り当てるクラスを受け取ります。
- setDynamicProp:この関数は、要素の動的なプロパティを設定するために使用されます。3 つの引数、要素、キー、および値が必要です。これらは、関数が呼び出されるたびに割り当てられるか更新される適切な値を決定するために使用されます。
- setText:この関数は、ノードと可能な値を受け取ります。与えられた値をノードの textContent に設定し、同時に内容が変更されたかどうかを検証します。
- template:この関数は、有効な HTML 文字列を受け取り、要素を作成します。この関数を調べると、基本的な DOM 操作メソッドが使用されていることがわかります。具体的には、document.createElement を使用して要素を作成し、innerHTML を使用して要素の内容を追加します。innerHTML は HTML 文字列を受け入れます。
まとめ#
2024 年、Vue の Vapor Mode はフロントエンド開発の領域に革新をもたらし、優れたパフォーマンス向上により、Vue エコシステムに前例のない変革をもたらしました。私たちは Vapor Mode の将来のパフォーマンスに期待を寄せながら、開発者によりスムーズで効率的な開発体験をもたらすと信じています。