Vue 3.2 は速くなったのか？

以前に [Vue 3 は速くなったのか？](https://qiita.com/sg0hsmt/items/1dd2944b577191729cb6) という記事で Vue 2 と Vue 3 の性能比較を行いました。
残念ながら期待した結果は得られなかったのですが Vue 3.2 で性能改善されたとのことなので再び比較してみました。

https://blog.vuejs.org/posts/vue-3.2.html

※ 特に記載がない限り 2021 年 8 月 24 日時点の情報になります。

## 短い結論

- Vue 2 から Vue 3.2 に更新しても速くなるとは限らない。むしろ遅くなることもある。
- Vue 3.2 は Vue 3 より少しだけ速くなった。

## 測定方法

調査するにあたって次の記事で紹介されているコードをお借りしました。

https://ics.media/entry/190731/

https://github.com/ics-creative/160916_performance_js_framework

フレームレートの測定は DevTools の FPS メーターを使用しています。
前回の記事では Frames に表示されているパーセントを記録しましたが Chrome 90 で FPS 表示に戻ったため FPS を記録しています。

測定環境は Windows 10 21H1 上の Chrome 92 です。
60 Hz の Full HD ディスプレイにシークレットウィンドウをフルスクリーン表示したうえで強制再読み込みを行いながら 3 回測定して最も大きな数値を記録しています。

### コードに対する変更

測定しなおすにあたり一部コード修正や依存パッケージ更新を行っています。
変更したコードは次のリポジトリの vue3.2 ブランチに push しました。

https://github.com/sg0hsmt/160916_performance_js_framework

前回の記事で行った変更に加えて次の変更を行っています。

- 依存パッケージを更新しました。
- `vue3-svg-composition` にてデータが格納された配列をコピーする代わりに元の生配列を更新してから [`triggerRef()`](https://v3.vuejs.org/api/refs-api.html#triggerref) を呼ぶように変更しました。 [^1]
  - これは vue-next の Issue コメント [^2] を参考にした変更です。
- Vue 3 実装をもとに Vue 3.2 実装を追加しました。
  - Vue 3 実装から Vue.js のバージョンを更新してリビルドしました。
- `vue3.2-svg-setup` 実装を追加しました。
  - Vue 3.2 で stable になった [`<script setup>`](https://v3.vuejs.org/api/sfc-script-setup.html) を使用した実装です。

Vue.js はそれぞれ次のバージョンを使用しています。

| 実装    | Vue.js バージョン                                                 |
| ------- | ----------------------------------------------------------------- |
| Vue 2   | [v2.6.14](https://github.com/vuejs/vue/releases/tag/v2.6.14)      |
| Vue 3   | [v3.0.11](https://github.com/vuejs/vue-next/releases/tag/v3.0.11) |
| Vue 3.2 | [v3.2.4](https://github.com/vuejs/vue-next/releases/tag/v3.2.4)   |

## 結果

測定環境が良くないせいか Frames が安定しなかったため結果の精度は低いものと考えてください。

| 実装                | Frames   | JavaScript メモリ | 転送サイズ |
| ------------------- | -------- | ----------------- | ---------- |
| Vanilla JS          | 10.8 fps | 8620 KB           | 5.5 kB     |
| Vue 2               | 5.7 fps  | 112008 KB         | 107 kB     |
| Vue 2 functional    | 9.6 fps  | 42556 KB          | 108 kB     |
| Vue 3               | 4.8 fps  | 68040 KB          | 102 kB     |
| Vue 3 functional    | 9.9 fps  | 34620 KB          | 100 kB     |
| Vue 3 composition   | 7.5 fps  | 43068 KB          | 97.2 kB    |
| Vue 3.2             | 5.1 fps  | 70088KB           | 102 kB     |
| Vue 3.2 functional  | 9.9 fps  | 36156 KB          | 104 kB     |
| Vue 3.2 composition | 7.8 fps  | 41556 KB          | 100 kB     |
| Vue 3.2 setup       | 7.8 fps  | 41044 KB          | 99.7 kB    |

従来からある Data オプションを使用したコンポーネント実装では Vue 3 にすることで遅くなるという結果が出ました。
ただし、Vue 2 より Vue 3 / Vue 3.2 のほうが消費メモリが大きく減っており転送サイズもやや小さくなっています。
また、 Vue 3 と Vue 3.2 の比較だと Vue 3.2 のほうが少しだけ速いようです。

関数コンポーネントを使用した実装では Vue 2 より Vue 3 / Vue 3.2 のほうが少しだけ速くなりました。

Composition API を使用した実装では Vue 3 より Vue 3.2 のほうが少しだけ速くなりました。

`<script setup>` は Composition API のシンタックスシュガーですので基本的な性能は変わりません。
同一スコープの場合はプロキシを省略することで実行時パフォーマンスが向上するとされていますが今回の測定では差が出ませんでした。

Vue 3 ではステートフルコンポーネント (通常のコンポーネント) のパフォーマンスが向上して関数コンポーネントとの違いはわずかになった [^3] ということでしたが前回と同様に差がついています。

## まとめ

測定環境やユースケースによって変わると思いますが、次の 2 点を確認できました

- Vue 2 から Vue 3.2 に更新しても速くなるとは限らない。むしろ遅くなることもある。
- Vue 3.2 は Vue 3 より少しだけ速くなった。

Vue 3 でパフォーマンスが重要な場合は Composition API でリアクティブをコントロールしたり関数コンポーネント化を考える必要がありそうです。

[^1]: https://github.com/sg0hsmt/160916_performance_js_framework/commit/7df3b4bef28928fe76e302656fddd9af313089ce
[^2]: https://github.com/vuejs/vue-next/issues/4318#issuecomment-899385227
[^3]: https://v3.vuejs.org/guide/migration/functional-components.html