Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

Vaporモードを大規模サービスに最速導入して学びを共有する

 Vaporモードを大規模サービスに最速導入して学びを共有する

Kazuki Shimamoto

October 19, 2024
Tweet

More Decks by Kazuki Shimamoto

Other Decks in Programming

Transcript

  1. 2 島本 和樹 • 株式会社スタディスト ◦ Teachme Biz の開発 •

    最近フロントエンド領域に注⼒ ⾃⼰紹介
  2. 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
  3. 12 Vaporモードとは Vueはコンパイルされて動いている <script setup> import { ref } from

    'vue' const msg = ref('Hello World!') </script> <template> <h1>{{ msg }}</h1> <input v-model="msg" /> </template> 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 */)) }
  4. 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 */)) }
  5. 14 Vaporモードとは 仮想DOM:DOMツリーの構造を模したオブジェクト div p Hello, World! { type: "div",

    props: { id: "my-app" }, children: [ { type: "p", props: {}, children: [`Hello World!`] } ] } DOMツリー 仮想DOM
  6. 48 Teachme BizをVaporモードで動かす slotにカスタムコンポーネントを差し込む際 名前指定が必要 <template> <ParentComp> <ChildComp> </ParentComp> </template>

    <template> <ParentComp> <template #default> <ChildComp> </template> </ParentComp> </template> 動かない 動く! 名前指定なし
  7. 49 Teachme BizをVaporモードで動かす slotにカスタムコンポーネントを差し込む際 名前指定が必要 <template> <ParentComp> <ChildComp> </ParentComp> </template>

    <template> <ParentComp> <template #default> <ChildComp> </template> </ParentComp> </template> 動かない 動く! defaultと指定する
  8. 50 Teachme BizをVaporモードで動かす フォールスルー属性が付与されない <template> <MyComp class="hoge" style="color: red;" />

    </template> // 実際のHTML要素 <template> <!-- ↓ここにclass, styleが付与されない --> <div class="my-comp"> <p>My Comp</p> </div> </template>
  9. 51 Teachme BizをVaporモードで動かす フォールスルー属性が付与されない <template> <MyComp class="hoge" style="color: red;" />

    </template> // 実際のHTML要素 <template> <!-- ↓ここにclass, styleが付与されない --> <div class="my-comp"> <p>My Comp</p> </div> </template>
  10. 52 Teachme BizをVaporモードで動かす フォールスルー属性が付与されない <template> <MyComp class="hoge" style="color: red;" />

    </template> // 実際のHTML要素 <template> <!-- ↓ここにclass, styleが付与されない --> <div class="my-comp"> <p>My Comp</p> </div> </template>
  11. 53 Teachme BizをVaporモードで動かす フォールスルー属性がつかない(対策) <script setup lang="ts"> const styleObj =

    ref({ color: 'red' }) </script> <template> <MyComp :styleObj="styleObj" /> </template> <script setup lang="ts"> const props = defineProps<{ styleObj?: obj | null }>() </script> <template> <div class="my-comp" :style="props.styleObj"> <p>My Comp</p> </div> </template> Parent.vue MyComp.vue
  12. 54 Teachme BizをVaporモードで動かす フォールスルー属性がつかない(対策) <script setup lang="ts"> const styleObj =

    ref({ color: 'red' }) </script> <template> <MyComp :styleObj="styleObj" /> </template> <script setup lang="ts"> const props = defineProps<{ styleObj?: obj | null }>() </script> <template> <div class="my-comp" :style="props.styleObj"> <p>My Comp</p> </div> </template> Parent.vue MyComp.vue
  13. 55 Teachme BizをVaporモードで動かす フォールスルー属性がつかない(対策) <script setup lang="ts"> const styleObj =

    ref({ color: 'red' }) </script> <template> <MyComp :styleObj="styleObj" /> </template> <script setup lang="ts"> const props = defineProps<{ styleObj?: obj | null }>() </script> <template> <div class="my-comp" :style="props.styleObj"> <p>My Comp</p> </div> </template> Parent.vue MyComp.vue
  14. 56 Teachme BizをVaporモードで動かす フォールスルー属性がつかない(対策) <script setup lang="ts"> const styleObj =

    ref({ color: 'red' }) </script> <template> <MyComp :styleObj="styleObj" /> </template> <script setup lang="ts"> const props = defineProps<{ styleObj?: obj | null }>() </script> <template> <div class="my-comp" :style="props.styleObj"> <p>My Comp</p> </div> </template> Parent.vue MyComp.vue
  15. 57 Teachme BizをVaporモードで動かす v-for × v-on でオブジェクトの省略記法 <template> <ul> <li

    v-for="item in items" :key="item.id" @click="handler({ item })" > </li> </ul> </template> <template> <ul> <li v-for="item in items" :key="item.id" @click="handler({ item: item })" > </li> </ul> </template> 動かない 動く!
  16. 58 Teachme BizをVaporモードで動かす v-for × v-on でオブジェクトの省略記法 <template> <ul> <li

    v-for="item in items" :key="item.id" @click="handler({ item })" > </li> </ul> </template> <template> <ul> <li v-for="item in items" :key="item.id" @click="handler({ item: item })" > </li> </ul> </template> 動かない 動く!
  17. 59 Teachme BizをVaporモードで動かす v-for × v-on でオブジェクトの省略記法 <template> <ul> <li

    v-for="item in items" :key="item.id" @click="handler({ item })" > </li> </ul> </template> <template> <ul> <li v-for="item in items" :key="item.id" @click="handler({ item: item })" > </li> </ul> </template> 動かない 動く!
  18. 60 Teachme BizをVaporモードで動かす • pinia, vuex ◦ provide / inject

    で対応 • vue-router ◦ インターフェースを揃えたオブジェクトで代替 • vue-3-slider ◦ Composition API形式に書き換え • サードパーティ製のコンポーネント ◦ 使わずに置き換え 各種ライブラリが動かない
  19. 61 Teachme BizをVaporモードで動かす • slot名にケバブケースが使えない (現在修正済み) ◦ slotを使わない形に変更 • ネイティブイベントが

    emit されていない ◦ 明⽰的に emit するように • 名前付き slot 内の v-for がリアクティブではない ◦ slot を使わない その他の事象
  20. 69 VaporモードON/OFFでの⽐較 • PC ◦ チップ: Apple M1 Pro ◦

    メモリ: 32 GB • パフォーマンス検証は5回ずつ計測し平均値を算出 全項⽬で共通の条件
  21. 78 VaporモードON/OFFでの⽐較 • First Contentful Paint (FCP) • Largest Contentful

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

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

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

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

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

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

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

    Paint (LCP) • Total Blocking Time (TBT) FCP (=LCP) を⽐較
  29. 92 VaporモードON/OFFでの⽐較 • 速度 ◦ スクリプト ◦ レンダリング ◦ ペイント

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

    • ヒープメモリ ヒープメモリは最⼩値と最⼤値を確認
  31. 116

  32. 118 VaporモードON/OFFでの⽐較 • バンドルサイズ • 初期描画のパフォーマンス • 更新描画のパフォーマンス • 初期描画のパフォーマンス

    • 更新描画のパフォーマンス 各項⽬においてVaporが優れていることが確認できた ⽐較検証のまとめ 1000ステップ版! 1000ステップ版!
  33. 139 さいごに • Composition API へ書き換え実施予定 ◦ Vapor モードをすぐに使えるように •

    フロントエンドの改善活動をやっていくぞ!! ◦ 継続的なパッケージ最新化 ◦ 新しいツールの調査や導⼊ 今後の活動