Slide 1

Slide 1 text

Vaporモードを⼤規模サービスに 最速導⼊して学びを共有する Vue Fes Japan 2024

Slide 2

Slide 2 text

2 島本 和樹 ● 株式会社スタディスト ○ Teachme Biz の開発 ● 最近フロントエンド領域に注⼒ ⾃⼰紹介

Slide 3

Slide 3 text

はじめに 3

Slide 4

Slide 4 text

4 はじめに Vaporモードをプロダクトに導⼊し パフォーマンス検証をした 取り組みや学びについて共有する 今⽇話すこと

Slide 5

Slide 5 text

5 はじめに 専⾨領域じゃなくても チャレンジしてみよう!! と思ってもらう 伝えたいことは

Slide 6

Slide 6 text

● Vaporモードの詳細な中⾝ ● 実装内容を踏まえた考察 6 はじめに 話さないこと

Slide 7

Slide 7 text

7 はじめに 詳しい話はこちらで!

Slide 8

Slide 8 text

Vaporモードとは 01 Teachme BizをVaporモードで動かす 02 VaporモードON/OFFでの⽐較 03 取り組み前の⾃分に向けて 04 はじめに 8 ⽬次

Slide 9

Slide 9 text

Vaporモードとは 01 9

Slide 10

Slide 10 text

10 Vaporモードとは About Vue Vapor is a variant of Vue that offers rendering without the Virtual DOM. vue-vaporのリポジトリにはこう書かれている https://github.com/vuejs/vue-vapor

Slide 11

Slide 11 text

11 Vaporモードとは 仮想DOMを使わない 新しいコンパイル戦略 ⾔い換えると

Slide 12

Slide 12 text

12 Vaporモードとは Vueはコンパイルされて動いている import { ref } from 'vue' const msg = ref('Hello World!')

{{ msg }}

function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createElementBlock(_Fragment, null, [ _createElementVNode("h1", null, _toDisplayString($setup.msg), 1 /* TEXT */), _withDirectives(_createElementVNode("input", { "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($setup.msg) = $event)) }, null, 512 /* NEED_PATCH */), [ [_vModelText, $setup.msg] ]) ], 64 /* STABLE_FRAGMENT */)) }

Slide 13

Slide 13 text

13 Vaporモードとは 仮想DOMが使われている function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createElementBlock(_Fragment, null, [ _createElementVNode("h1", null, _toDisplayString($setup.msg), 1 /* TEXT */), _withDirectives(_createElement VNode("input", { "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($setup.msg) = $event)) }, null, 512 /* NEED_PATCH */), [ [_vModelText, $setup.msg] ]) ], 64 /* STABLE_FRAGMENT */)) }

Slide 14

Slide 14 text

14 Vaporモードとは 仮想DOM:DOMツリーの構造を模したオブジェクト div p Hello, World! { type: "div", props: { id: "my-app" }, children: [ { type: "p", props: {}, children: [`Hello World!`] } ] } DOMツリー 仮想DOM

Slide 15

Slide 15 text

15 Vaporモードとは 従来の実装: 更新コストを抑える⼯夫 div p Hello, World! div p Hi, Vue! 差分だけ更新 変更前 変更後

Slide 16

Slide 16 text

16 Vaporモードとは 仮想DOMを扱う従来の実装は 更新のコストが抑えられている

Slide 17

Slide 17 text

17 Vaporモードとは もしも 仮想DOMの差分の計算すらなくせたら…

Slide 18

Slide 18 text

18 Vaporモードとは Vaporモード そんな夢のような機能を実現しているのが

Slide 19

Slide 19 text

19 Vaporモードとは ● より速い実⾏速度 ● より少ないメモリ使⽤量 ● より少ないランタイムのコード Vaporモードによってどうよくなるか

Slide 20

Slide 20 text

20 Vaporモードとは ● より速い実⾏速度 ● より少ないメモリ使⽤量 ● より少ないランタイムのコード Vaporモードによってどうよくなるか

Slide 21

Slide 21 text

21 Vaporモードとは ● より速い実⾏速度 ● より少ないメモリ使⽤量 ● より少ないランタイムのコード Vaporモードによってどうよくなるか

Slide 22

Slide 22 text

22 Vaporモードとは ● より速い実⾏速度 ● より少ないメモリ使⽤量 ● より少ないランタイムのコード Vaporモードによってどうよくなるか

Slide 23

Slide 23 text

23 Vaporモードとは Vaporモードすごい! 良さそう!!

Slide 24

Slide 24 text

Teachme BizをVaporモードで動かす 02 24

Slide 25

Slide 25 text

25 Teachme BizをVaporモードで動かす Vaporモードの恩恵は 実際のプロダクトレベルでどれくらい?

Slide 26

Slide 26 text

26 Teachme BizをVaporモードで動かす 導⼊社数 国内 2,000 社 海外 100社 マニュアル作成‧共有システム ビジュアルベースの⼿順書で 「伝えることを、もっと簡単に。」

Slide 27

Slide 27 text

27 Teachme BizをVaporモードで動かす ● コンポーネント数: 573 ● ページ数: 142 Teachme Bizの規模

Slide 28

Slide 28 text

28 Teachme BizをVaporモードで動かす VaporモードはR&D段階 しかし‧‧‧

Slide 29

Slide 29 text

29 Teachme BizをVaporモードで動かす Teachme Bizに導⼊するのは難しい 簡単には試せないか…

Slide 30

Slide 30 text

30 vue-vaporリポジトリを眺めてみる

Slide 31

Slide 31 text

31 Teachme BizをVaporモードで動かす Playgroundを発⾒!!

Slide 32

Slide 32 text

32 Teachme BizをVaporモードで動かす ここで Teachme Biz を動かすことならできる

Slide 33

Slide 33 text

33 Teachme BizをVaporモードで動かす DOM操作が多い編集画⾯をPlaygroundに!

Slide 34

Slide 34 text

34 Teachme BizをVaporモードで動かす マニュアル編集画⾯ Options APIのコンポーネント約130個

Slide 35

Slide 35 text

35 Teachme BizをVaporモードで動かす Vaporモード 現在Options APIはサポートしていない

Slide 36

Slide 36 text

36 Teachme BizをVaporモードで動かす 約130個のコンポーネントをすべて Composition API形式に 書き換えて実装する必要がある

Slide 37

Slide 37 text

37 Teachme BizをVaporモードで動かす 約130個のコンポーネントをすべて Composition API形式に 書き換えて実装する必要がある

Slide 38

Slide 38 text

38 Teachme BizをVaporモードで動かす 130個…

Slide 39

Slide 39 text

39 Teachme BizをVaporモードで動かす AI と ⼿作業 どのように約130個を書き換えたか

Slide 40

Slide 40 text

40 Teachme BizをVaporモードで動かす プロンプトは結構シンプル メインの指⽰ 不⾜があれば 指⽰を追加

Slide 41

Slide 41 text

41 Teachme BizをVaporモードで動かす 作業の流れ AIで変換して追加 参照ファイル‧静的アセット追加 表⽰を確認 エラーがあれば修正

Slide 42

Slide 42 text

42 Teachme BizをVaporモードで動かす 作業の流れ AIで変換して追加 参照ファイル‧静的アセット追加 表⽰を確認 エラーがあれば修正 130回 繰り返す

Slide 43

Slide 43 text

43 Teachme BizをVaporモードで動かす 作業の流れ AIで変換して追加 参照ファイル‧静的アセット追加 表⽰を確認 エラーがあれば修正 130回 繰り返す

Slide 44

Slide 44 text

44 Teachme BizをVaporモードで動かす 作業の流れ 130回 繰り返す AIで変換して追加 参照ファイルやiconを追加 ルートページ(App.vue)に表⽰ エラーがあれば修正 結構動かないです

Slide 45

Slide 45 text

45 Teachme BizをVaporモードで動かす VaporモードはR&Dなので当然

Slide 46

Slide 46 text

46 Teachme BizをVaporモードで動かす 発⽣したエラーや動かなかったこと と その対応を紹介 事象は9⽉4⽇時点のコードで発⽣ 現在は修正されているものもあります

Slide 47

Slide 47 text

47 Teachme BizをVaporモードで動かす slotにカスタムコンポーネントを差し込む際 名前指定が必要 動かない 動く!

Slide 48

Slide 48 text

48 Teachme BizをVaporモードで動かす slotにカスタムコンポーネントを差し込む際 名前指定が必要 動かない 動く! 名前指定なし

Slide 49

Slide 49 text

49 Teachme BizをVaporモードで動かす slotにカスタムコンポーネントを差し込む際 名前指定が必要 動かない 動く! defaultと指定する

Slide 50

Slide 50 text

50 Teachme BizをVaporモードで動かす フォールスルー属性が付与されない // 実際のHTML要素

My Comp

Slide 51

Slide 51 text

51 Teachme BizをVaporモードで動かす フォールスルー属性が付与されない // 実際のHTML要素

My Comp

Slide 52

Slide 52 text

52 Teachme BizをVaporモードで動かす フォールスルー属性が付与されない // 実際のHTML要素

My Comp

Slide 53

Slide 53 text

53 Teachme BizをVaporモードで動かす フォールスルー属性がつかない(対策) const styleObj = ref({ color: 'red' }) const props = defineProps<{ styleObj?: obj | null }>()

My Comp

Parent.vue MyComp.vue

Slide 54

Slide 54 text

54 Teachme BizをVaporモードで動かす フォールスルー属性がつかない(対策) const styleObj = ref({ color: 'red' }) const props = defineProps<{ styleObj?: obj | null }>()

My Comp

Parent.vue MyComp.vue

Slide 55

Slide 55 text

55 Teachme BizをVaporモードで動かす フォールスルー属性がつかない(対策) const styleObj = ref({ color: 'red' }) const props = defineProps<{ styleObj?: obj | null }>()

My Comp

Parent.vue MyComp.vue

Slide 56

Slide 56 text

56 Teachme BizをVaporモードで動かす フォールスルー属性がつかない(対策) const styleObj = ref({ color: 'red' }) const props = defineProps<{ styleObj?: obj | null }>()

My Comp

Parent.vue MyComp.vue

Slide 57

Slide 57 text

57 Teachme BizをVaporモードで動かす v-for × v-on でオブジェクトの省略記法
動かない 動く!

Slide 58

Slide 58 text

58 Teachme BizをVaporモードで動かす v-for × v-on でオブジェクトの省略記法
動かない 動く!

Slide 59

Slide 59 text

59 Teachme BizをVaporモードで動かす v-for × v-on でオブジェクトの省略記法
動かない 動く!

Slide 60

Slide 60 text

60 Teachme BizをVaporモードで動かす ● pinia, vuex ○ provide / inject で対応 ● vue-router ○ インターフェースを揃えたオブジェクトで代替 ● vue-3-slider ○ Composition API形式に書き換え ● サードパーティ製のコンポーネント ○ 使わずに置き換え 各種ライブラリが動かない

Slide 61

Slide 61 text

61 Teachme BizをVaporモードで動かす ● slot名にケバブケースが使えない (現在修正済み) ○ slotを使わない形に変更 ● ネイティブイベントが emit されていない ○ 明⽰的に emit するように ● 名前付き slot 内の v-for がリアクティブではない ○ slot を使わない その他の事象

Slide 62

Slide 62 text

62 Teachme BizをVaporモードで動かす 130個… 頑張ってComposition APIに書き換えていき

Slide 63

Slide 63 text

63 Teachme BizをVaporモードで動かす

Slide 64

Slide 64 text

VaporモードON/OFFでの⽐較 03 64

Slide 65

Slide 65 text

65 VaporモードON/OFFでの⽐較 PlaygroundではVaporモードのON/OFFができる plugins: [ Vue({ vapor: true, compiler: CompilerSFC, }), vite.config.ts

Slide 66

Slide 66 text

66 VaporモードON/OFFでの⽐較 仮想DOM(VNode)の処理有無が切り替わる Vapor: ON Vapor: OFF

Slide 67

Slide 67 text

67 VaporモードON/OFFでの⽐較 以下がよくなっていることを確認したい Vaporでよくなること より速い実⾏速度 より少ないメモリ使⽤量 より少ないランタイムのコード

Slide 68

Slide 68 text

68 VaporモードON/OFFでの⽐較 3つの項⽬で⽐較 Vaporでよくなること より速い実⾏速度 より少ないメモリ使⽤量 より少ないランタイムのコード 1. バンドルサイズ 2. 初期描画のパフォーマンス 3. 更新描画のパフォーマンス 検証項⽬

Slide 69

Slide 69 text

69 VaporモードON/OFFでの⽐較 ● PC ○ チップ: Apple M1 Pro ○ メモリ: 32 GB ● パフォーマンス検証は5回ずつ計測し平均値を算出 全項⽬で共通の条件

Slide 70

Slide 70 text

70 VaporモードON/OFFでの⽐較 1. バンドルサイズ 2. 初期描画のパフォーマンス 3. 更新描画のパフォーマンス ⽐較する項⽬

Slide 71

Slide 71 text

71 VaporモードON/OFFでの⽐較 App.vueに130個のコンポーネントを⼀覧

Slide 72

Slide 72 text

72 VaporモードON/OFFでの⽐較 バンドルサイズの出⼒⽅法 rollup-plugin-visualizer を使⽤

Slide 73

Slide 73 text

73 VaporモードON/OFFでの⽐較 バンドルサイズの⽐較⽅法

Slide 74

Slide 74 text

74 VaporモードON/OFFでの⽐較 バンドルサイズの⽐較⽅法 若⼲Vapor ONの⽅が サイズが⼩さい

Slide 75

Slide 75 text

75 VaporモードON/OFFでの⽐較 1. バンドルサイズ 2. 初期描画のパフォーマンス 3. 更新描画のパフォーマンス ⽐較する項⽬

Slide 76

Slide 76 text

76 VaporモードON/OFFでの⽐較 以下の画⾯を表⽰したときのパフォーマンスを計測 1ステップ x 50

Slide 77

Slide 77 text

77 VaporモードON/OFFでの⽐較 計測にはChromeのパフォーマンスタブを使⽤

Slide 78

Slide 78 text

78 VaporモードON/OFFでの⽐較 ● First Contentful Paint (FCP) ● Largest Contentful Paint (LCP) ● Total Blocking Time (TBT) 初期描画でよく⾒られる項⽬は以下

Slide 79

Slide 79 text

79 VaporモードON/OFFでの⽐較 ● First Contentful Paint (FCP) ○ 最初のコンテンツが表⽰されるまでの時間 ● Largest Contentful Paint (LCP) ● Total Blocking Time (TBT) 初期描画でよく⾒られる項⽬は以下

Slide 80

Slide 80 text

80 VaporモードON/OFFでの⽐較 ● First Contentful Paint (FCP) ● Largest Contentful Paint (LCP) ○ 最⼤のコンテンツが表⽰されるまでの時間 ● Total Blocking Time (TBT) 初期描画でよく⾒られる項⽬は以下

Slide 81

Slide 81 text

81 VaporモードON/OFFでの⽐較 ● First Contentful Paint (FCP) ● Largest Contentful Paint (LCP) ● Total Blocking Time (TBT) ○ FCPからユーザー操作が可能になるまでの時間 初期描画でよく⾒られる項⽬は以下

Slide 82

Slide 82 text

82 VaporモードON/OFFでの⽐較 ● First Contentful Paint (FCP) ● Largest Contentful Paint (LCP) ● Total Blocking Time (TBT) どの値を⽐較するか

Slide 83

Slide 83 text

83 VaporモードON/OFFでの⽐較 ● First Contentful Paint (FCP) ● Largest Contentful Paint (LCP) ● Total Blocking Time (TBT) どの値を⽐較するか

Slide 84

Slide 84 text

84 VaporモードON/OFFでの⽐較 ● First Contentful Paint (FCP) ● Largest Contentful Paint (LCP) ● Total Blocking Time (TBT) どの値を⽐較するか

Slide 85

Slide 85 text

85 VaporモードON/OFFでの⽐較 ● First Contentful Paint (FCP) ● Largest Contentful Paint (LCP) ● Total Blocking Time (TBT) FCP (=LCP) を⽐較

Slide 86

Slide 86 text

86 VaporモードON/OFFでの⽐較

Slide 87

Slide 87 text

87 VaporモードON/OFFでの⽐較 Vaporモード ONの⽅が 88 ms 早く コンテンツが描画

Slide 88

Slide 88 text

88 VaporモードON/OFFでの⽐較 1. バンドルサイズ 2. 初期描画のパフォーマンス 3. 更新描画のパフォーマンス ⽐較する項⽬

Slide 89

Slide 89 text

89 VaporモードON/OFFでの⽐較 タイトル⼊⼒時のパフォーマンスを確認 ステップ1を 更新すると 残り49ステップ も更新される = 50箇所同時更新

Slide 90

Slide 90 text

90 VaporモードON/OFFでの⽐較 0.2秒間隔で20回⼊⼒

Slide 91

Slide 91 text

91 VaporモードON/OFFでの⽐較 計測にはChromeのパフォーマンスタブを使⽤

Slide 92

Slide 92 text

92 VaporモードON/OFFでの⽐較 ● 速度 ○ スクリプト ○ レンダリング ○ ペイント ● ヒープメモリ 更新パフォーマンスを速度とメモリで⽐較

Slide 93

Slide 93 text

93 VaporモードON/OFFでの⽐較 ● 速度 ○ スクリプト ○ レンダリング ○ ペイント ● ヒープメモリ 速度については3つの結果を確認

Slide 94

Slide 94 text

94 VaporモードON/OFFでの⽐較

Slide 95

Slide 95 text

95 VaporモードON/OFFでの⽐較 スクリプティングの時間が Vapor ONの方がすごく短い

Slide 96

Slide 96 text

96 VaporモードON/OFFでの⽐較 レンダリング・ペイント ほとんど差がない

Slide 97

Slide 97 text

97 VaporモードON/OFFでの⽐較 レンダリング・ペイント ほとんど差がない 仮想DOMの有無には関係がない

Slide 98

Slide 98 text

98 VaporモードON/OFFでの⽐較 ● 速度 ○ スクリプト ○ レンダリング ○ ペイント ● ヒープメモリ ヒープメモリは最⼩値と最⼤値を確認

Slide 99

Slide 99 text

99 VaporモードON/OFFでの⽐較

Slide 100

Slide 100 text

100 VaporモードON/OFFでの⽐較 Vapor ONの⽅がわずかに⼩さい

Slide 101

Slide 101 text

101 VaporモードON/OFFでの⽐較 各項⽬でVapor ONの⽅が 良い結果が⾒られた

Slide 102

Slide 102 text

102 VaporモードON/OFFでの⽐較 要素数を増やしたらもっと差がでるのだろうか 🤔

Slide 103

Slide 103 text

103 VaporモードON/OFFでの⽐較 追加でパフォーマンス検証を実施

Slide 104

Slide 104 text

104 VaporモードON/OFFでの⽐較 要素数を⼀気に増やす!! 1ステップ x 1000

Slide 105

Slide 105 text

105 VaporモードON/OFFでの⽐較 1. バンドルサイズ 2. 初期描画のパフォーマンス 3. 更新描画のパフォーマンス 検証項⽬ 1000ステップ版!

Slide 106

Slide 106 text

106 VaporモードON/OFFでの⽐較

Slide 107

Slide 107 text

107 VaporモードON/OFFでの⽐較 Vapor ON の⽅が 描画がめっちゃ速い 4秒くらい差がある

Slide 108

Slide 108 text

108 VaporモードON/OFFでの⽐較 1. バンドルサイズ 2. 初期描画のパフォーマンス 3. 更新描画のパフォーマンス 検証項⽬ 1000ステップ版!

Slide 109

Slide 109 text

109 VaporモードON/OFFでの⽐較

Slide 110

Slide 110 text

110 VaporモードON/OFFでの⽐較 スクリプティングは Vapor ON の⽅が すごく短い

Slide 111

Slide 111 text

111 VaporモードON/OFFでの⽐較 レンダリングとペイントの時間が Vapor ONのほうが⻑い!?

Slide 112

Slide 112 text

112 VaporモードON/OFFでの⽐較 VaporモードONによって レンダリング‧ペイントの時間伸びたのか? レンダリングとペイントは同じになるはずなのに

Slide 113

Slide 113 text

113 VaporモードON/OFFでの⽐較 動作を⾒ると原因がわかった Vapor ON: 更新 18回 Vapor OFF: 更新 5回

Slide 114

Slide 114 text

114 VaporモードON/OFFでの⽐較 描画更新の回数が Vapor ON の⽅が多かった

Slide 115

Slide 115 text

115 VaporモードON/OFFでの⽐較 ヒープメモリの⽐較

Slide 116

Slide 116 text

116

Slide 117

Slide 117 text

117 Vapor OFF(仮想DOM有り)は 最⼩と最⼤の差が⼤きい

Slide 118

Slide 118 text

118 VaporモードON/OFFでの⽐較 ● バンドルサイズ ● 初期描画のパフォーマンス ● 更新描画のパフォーマンス ● 初期描画のパフォーマンス ● 更新描画のパフォーマンス 各項⽬においてVaporが優れていることが確認できた ⽐較検証のまとめ 1000ステップ版! 1000ステップ版!

Slide 119

Slide 119 text

119 VaporモードON/OFFでの⽐較 Vaporすごい!

Slide 120

Slide 120 text

120 VaporモードON/OFFでの⽐較 これが脱仮想DOMの⼒か!! と思いきや

Slide 121

Slide 121 text

121 VaporモードON/OFFでの⽐較 ubugeeeiさん 脱仮想DOMがメインですが 処理の最適化も⼊ってますよ!

Slide 122

Slide 122 text

122 VaporモードON/OFFでの⽐較 Vaporについての理解はまだまだこれからだ 完

Slide 123

Slide 123 text

取り組み前の⾃分に向けて 04 123

Slide 124

Slide 124 text

124 取り組み前の⾃分に向けて Vue の公式ドキュメントを隅から隅まで読め!

Slide 125

Slide 125 text

125 取り組み前の⾃分に向けて 「フォールスルー属性」も知らなかった

Slide 126

Slide 126 text

126 取り組み前の⾃分に向けて 公式ドキュメントに載っている

Slide 127

Slide 127 text

127 知っているとすぐ対応できる ● 動かない原因に気づける ● 調べることができる ● 対応策を考えられる

Slide 128

Slide 128 text

128 取り組み前の⾃分に向けて 必要なことはVueの公式ドキュメントに書いてある Vue の公式ドキュメントを 隅から隅まで読め!

Slide 129

Slide 129 text

129 取り組み前の⾃分に向けて 深い部分はubugeeeiさんのコンテンツを読もう! 上質なコンテンツを⽇本語で出してくれている

Slide 130

Slide 130 text

130 取り組み前の⾃分に向けて パフォーマンス検証はChromeで結構できるぞ https://developer.chrome.com/docs/devtools/performance?hl=ja

Slide 131

Slide 131 text

131 取り組み前の⾃分に向けて CfPを出してみよう!!! とにかく

Slide 132

Slide 132 text

132 取り組み前の⾃分に向けて ● フロントエンドの専⾨じゃない⾃分には出せないだろう ● 最新の技術を試すなんて本当にできるのか? CfP出す前の⾃分の気持ち

Slide 133

Slide 133 text

133 取り組み前の⾃分に向けて わからない‧難しいことはもちろんあった Vaporモードの導⼊が簡単にできなかった図

Slide 134

Slide 134 text

134 取り組み前の⾃分に向けて わからない‧難しいことはもちろんあった 130個のコンポーネント書き換えにビビる図

Slide 135

Slide 135 text

135 取り組み前の⾃分に向けて なんだかんだ乗り越えられた!!

Slide 136

Slide 136 text

136 取り組み前の⾃分に向けて 専⾨領域 じゃなくても チャレンジできるぞ!!

Slide 137

Slide 137 text

137 取り組み前の⾃分に向けて ● 登壇駆動でたくさん勉強することができた ● フロントエンドの専⾨性を深めたい! という気持ちが強まった やってみたらどうなった?

Slide 138

Slide 138 text

さいごに 138

Slide 139

Slide 139 text

139 さいごに ● Composition API へ書き換え実施予定 ○ Vapor モードをすぐに使えるように ● フロントエンドの改善活動をやっていくぞ!! ○ 継続的なパッケージ最新化 ○ 新しいツールの調査や導⼊ 今後の活動

Slide 140

Slide 140 text

140 さいごに 30⽇にアフターイベントやるのできてね

Slide 141

Slide 141 text

141 さいごに special thanks ubugeeeiさん

Slide 142

Slide 142 text

https://studist.jp/