Vue Fes Japan 2018 に行ってきた #vuefes

Vue Fes Japan に行ってきました。簡単に所感をまとめます。

vuefes.jp

今回参加したセッションは以下の通り。メモから抜粋。スライドが公開されたらリンクを貼っておきます。尚、英語セッションはリスニング力がショボすぎて理解が誤ってるかもしれません...。

キーノート

docs.google.com

  • Vue 3.0 Updates
    • 速度向上が重要
    • サイズを小さくする
    • メンテナンスしやすく
    • ネイティブ向けに

より速く:

  • 仮想 DOM の実装をフルスクラッチで作り直す
    • 最大100%の速度改善!
  • 後方互換あり、内部実装を作り変える
    • ライブラリ作者は少し調整が必要になるかも
  • JavaScript の新しい言語仕様を使うようにする
    • 3.x ではプロキシを使うように書き換えている
    • 2.x では ES5 の getter/setter を使っている
    • プロパティの追加/削除を検知できるようになる
    • ネイティブプロキシによるプロパティプロキシの高速化
      • Object.defineProperty は使わない
  • 実行中のオーバーヘッド削減のため、コンパイル時にヒントを追加
    • Render Function
    • コンパイル時にテンプレートの情報を取得する
    • これまでは実行時に解析していた
    • 必要な情報をコンパイル時に取得することで実行時の速度が向上する
  • Render 関数にあるスロット機能を最適化 (スロットの生成を最適化)
    • 2.x ではスロットは親のスコープで生成されるため、子要素は親要素を参照する必要があり、描画時に依存の階層が深くなる
    • 子要素が変更されたときは子要素のみ再描画すればよい
    • React にはこの仕組みはない
  • static tree hoisting (静的ツリーの巻き上げ)
  • static props hoisting (静的プロパティの巻き上げ)
    • ツリー全体を再描画するのではなく、中身だけ再描画する
  • inline handler hoisting (インラインハンドラの巻き上げ)
  • コンポーネントインスタンスの初期化を高速化
  • 省メモリ、パフォーマンス向上
  • Vue をアップデートするだけでパフォーマンス向上が可能

より小さく:

  • Tree-shaking への対応
  • Webpack や Rollup では Tree-shaking に対応している
  • オプション機能のコードをバンドルに含めないようにする (10KB以下も可能)

よりメンテしやすく:

  • アーキテクチャをよりクリーンなものに
  • パッケージの分離
    • リポジトリはモノリポジトリ
    • 独立した機能ごとにパッケージとして分ける
    • 実行環境に依存しない、js が動く環境であればどこでも動かせる

よりネイティブに:

  • iOS, Android
  • カスタムレンダラAPI
    • ブラウザ以外の環境向けに出力できる
    • NativeScript, Weex
    • ネイティブ向けに出力するために作った

コードの品質向上:

  • どのオプジェクトのプロパティでも監視できるようになる
  • Vuex を使わなくもよくなるかも

リアクティビティAPI:

TSX による TypeScript サポート:

  • Vue 2.x では完璧なものではなかった
  • props の型を表示できる (違う型を指定すると警告を表示してくれる)
  • コンポーネントと親コンポーネントの警告をコンソールに表示してくれる

(Experimental) Hooks API:

(Experimental) Time Slicing:

  • 描画に時間がかかるコンポーネントが複数あるとき、ブラウザが固まってしまう
  • Time Slicing を使うだけでレスポンシブになる
  • 60fps で収まるように js 関数をスロットリングする
  • イベントが連続したときに、古いイベントはスキップする

Vue.js と Web Components のこれから

  • Web Components
  • Web Components Specifications ★
    • HTML Template はもう使われなくなる?
  • Vue CLI 3 の Build Targets
    • --target wc オプションをつけてビルド
    • Vue.js コンポーネントを Web Components に変換してくれる
    • web-component-wrapper
      • Vue.js をラップしている
    • Vue.js コンポーネントを Web Components にスムーズに移行できる
  • Vue, React, Angular で共通のUIフレームワークとして使い回せる
  • Fully Scoped
    • Vue.js は Scoped っぽくなっている
    • Shadow DOM なので完全に Scoped
    • グローバルの css や js に影響しない
  • デメリット ★
  • 現時点では Vue.js でコンポーネントを作った方が機能的にいいかも
  • Micro Frontends ★
    • Web アプリを機能の集合と見なす
    • 一般的なフロントエンドはモノリシックになっている
    • 独立した機能で分割する
    • Shadow DOM は Scoped なので、変更が他のコンポーネントに影響しない
    • Web Components は Micro Frontends を実現するのに適している
  • 柔軟な Web サイトに
  • Vue.js の方が機能的に強力ではあるが、Web 標準であることの強みは将来の負債を減らす
  • Web Components は Vue.js を置き換えるものではない
    • Web Components は HTML 要素をカプセル化するもので、Web アプリを作るものではない
    • UI を相互干渉なく作るためのもの
    • Vue.js は Web アプリを作るためのもの
  • UI を Web Components に任せることで負債を減らす

Unit testing a Vuex store

slides.com

  • なぜテストをするのか
  • Three approaches ★
  • Don't
    • UT を書くのにも時間はかかる
    • E2E tests test store implicitly
  • store のパーツごとにテストする
    • Mutations
      • state と payload を渡して mutate して update されていることを assert
    • Getters
      • state を渡して getter を解決、戻り値を verify
    • Actions
      • HTTP リクエストはしない (テストがスローダウンするため)
      • jest.mock で API の戻り値をモック化する
      • mock の store を渡して、action が data を commit していることを assert
    • 粒度が細かいが、メンテが大変
  • store インスタンスをテストする
    • ブラックボックス
    • Vue.use(Vuex) はだめ
      • グローバルな Vue インスタンスに影響を与えないため
      • localVue.use(Vuex)
    • store.dispatch で action を呼び出して、state を assert
    • 必要に応じて API 呼び出しをモック化
    • 粒度は荒いが、メンテはラク
  • 複雑なテストを何度も回せるようにファクトリ関数を用意している
  • vue-test-utils はベータ
  • Vue 3 ではブラウザの DOM を使わずにレンダリングできる
    • これを使ってテストすることで高速化できるかも?
  • テストのときに本物の store を使うか、モックの store を使うか
  • コンポーネントのテスト
  • カバレッジを上げることより、何をテストするのかを見極めることが大事
    • 無駄にテストするより、新機能を開発することに注力する方がいい
  • TDD

Nuxt.js 2.0

  • レンダリングモード
  • モダンブラウザ対応のビルド
  • ブラウザと REST サーバーの間に Nuxt サーバーを置いてもいい (BFF)
  • https://hn.nuxtjs.org/
  • ブラウザ => APIサーバーだとユーザーごとにリクエストが来る?
    • SSR なら Nuxt サーバーで中継できる?
  • 静的ファイルはECサイトみたいな動的サイトに向かない
  • SPA
  • 2.3 でクライアントとサーバーのバンドルを分離できる
    • クライアントフォルダ / サーバーフォルダ
  • ES Modules 対応
  • 新規追加したコンポーネントは自動でルーティングなどに設定してくれる
  • asyncData のコンテキストはドキュメント参照
  • Vue 2.x のサポートが続くので、Nuxt 2.x のサポートも続く
  • Vue 3.x に合わせて Nuxt 3.x もリリースされる予定

note のフロントエンドを Nuxt.js で再構築した話

  • Angular.js 1.x
    • 初期表示が遅い (特に低スペックな端末)
    • SSR 未サポート
  • Nuxt.js によって規約が手に入る ★
  • パスベースで移行、Dog Fooding
    • 移行完了するまで二重メンテになるのがデメリット
    • チームを分ける
  • Lighthouse によるパフォーマンス比較
    • 指摘されているのはほとんど画像関連
  • Vuex + Atomic Design
  • mutations/actions/getters のタイプには定数を使う
    • grepability
    • エディタ補完
  • Vuex モジュール肥大化問題 (特に Actions に処理が集中しがち)
    • パーツごとにファイルを分離
    • 機能単位でモジュール分割できないか
  • Atomic Design
    • レイヤごとの責任分離が明確に
    • 名称があることでコミュニケーションが円滑に
  • コンポーネント視認性問題
    • Storybook
  • ユニバーサル JavaScript
    • クライアント/サーバーのどちらでも動作する
    • window, document は undefined
  • Polyfill.io
  • Nuxt on Lambda
    • Node.js のバージョンが固定されるため、Nuxt.js の最新に追従できない
    • ファイルサイズ上限が50MB
    • コールドスタート問題

1年間単体テストを書き続けた現場から送る Vue Component のテスト

  • 半数以上のサービスで Vue を使っている
  • 外部から見た振る舞いをテストする ★
  • Public Interface
  • Output
    • HTML/CSS, Event(Emit), Vuex/Action
  • ↑これらがテストターゲット ★
  • mount or shallow mount
    • 外部から見た振る舞い、設計の可動域の確保の観点から mount
  • router から読み込む Page Component をテストする
    • Page Component でカバーできないものは別途テスト
  • テストツールの役割を整理する ★
    • ブラウザが必要 or ブラウザが不要
  • Lifecycle Hooks ★
  • Props / Vuex State ★
    • 見た目にかかわるところ
    • Snapshot Testing ★
      • コンポーネントの DOM を比較する
      • 修正前後の DOM を比較する (差分があればチェック)
    • Visual Testing
      • Snapshot Testing の画像版 (CSS もテスト可能)
    • Storybook + reg-suit (画像の差分抽出) ★
      • Visual Testing を開発フローに乗せる
      • 以前は手元に checkout して起動したり、修正前後の画像をキャプチャしたり
      • レビューの負荷を下げることができる
  • User Interaction
    • スクロールなどの複雑な操作は難易度高い (できないことはないが諦める)
    • karma-nightmare でテスト中にスクリーンショットを取る
    • 画像は reg-suit で開発フローに乗せる
    • 重要なフォームだけでもテストする
    • 難しいところは割り切って諦める
  • テストをしっかり準備することでレビュー負荷を下げられる

所感など

登壇者が豪華で、改めて Vue.js の盛り上がりと勢いを感じます。全体的に学びと刺激が多いカンファレンスでした。キャンセル分のチケットが購入できてよかった...!

最初の KEYNOTE で 3.x の話がありましたが、特にパフォーマンスを改善する仕組みが多く取り込まれているようです。後方互換もちゃんと考慮されていて、Vue.js をアップデートするだけでパフォーマンス向上が期待できる模様。ぜひ使ってみたい。あと、個人的にはテスト関連のセッションがとても参考になりました。過去に自分が書いたテストは方向性としては決して間違ってなかったけど、足りてないところや改善できるところがまだまだたくさんあります。

Nuxt.js はまだちゃんと使ってないので、勉強中。

あと、Web Components や Micro Frontends あたりもなかなか興味深かったです。要復習。他のセッションも資料が公開されてるものがあるので、あとで読む。

というか、本当にもっと英語力を鍛えなくては...。