Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

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

Avatar for Kazuki Shimamoto

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 モードをすぐに使えるように •

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