LIFULL Creators Blog

LIFULL Creators Blogとは、株式会社LIFULLの社員が記事を共有するブログです。自分の役立つ経験や知識を広めることで世界をもっとFULLにしていきます。

WinSession で成果を自慢したらビルド時間が 8 倍速くなった話

こんにちは。テクノロジー本部の福留です。4 月に新卒入社しました。好きなものは合唱篩型です。

目標管理に関するフレームワークとして、OKR(Objectives and Key Results)が Google や Facebook などの企業で取り入れられ、注目を集めています。

OKR フレームワークにおいては、挑戦しがいのある高い目標(Objective)を設定し、主要な結果(Key Results)も 60〜70%の達成度で成功とみなされるような、高い成果に設定します。 チームのモチベーションが高くなるような高い目標を掲げる一方で、日々の業務ではできなかったことのほうが多くなり、徐々にメンバーのモチベーションが低下する原因になりえます。

この問題を解決する取り組みが WinSession です。この場では、逆に「できたこと」に注目し、メンバーどうしが承認・称賛しながら情報共有を行います。

resily.com

今回は、私が所属するアーキテクトグループで実際に行った WinSession の中で、成果を共有をすることでよりよい成果を出せた事例を、新卒の目線から紹介します。

目次

アーキテクトグループの主な仕事

本題へ入る前に、私が所属しているアーキテクトグループの主な仕事を紹介します。

アーキテクトグループは過去に、BFF 層アプリケーションを刷新するためのプロジェクトとして、TypeScript 製の新しい Backend For Frontend アプリケーションを作成していました。

www.lifull.blog

このアプリケーションを、以下では「新 BFF」と呼びます。

現在はこのアプリケーションの GitHub リポジトリをTemplate Repositoryに指定しています。さらに新しく BFF アプリケーションを作る際には、Template Repository から Generate することで作成することを推奨しています。 この方法で作られたアプリケーションを、以下では「派生アプリケーション」と呼びます。

これを踏まえて、現在のアーキテクトグループは次の取り組みを行っています。

  • 新 BFF から Generate された派生アプリケーション作成時のアーキテクチャの相談受け付け
  • 新 BFF の保守や生産性向上のためのリファクタリング・ビルド設定等の最適化
  • そのほか、レガシーなアプリケーションに対する生産性向上や刷新の取り組み

各派生アプリケーションは新 BFF から Generate されているため、新 BFF に行われた改善を受け入れやすい状態です。 新 BFF への改善を行うと全体最適な状態に近付けることができるため、個人的に力を入れている仕事でもあります。

WinSession

さて、アーキテクトグループでは WinSession を 2 週間に一度、金曜日に行っています。

新卒として感じる WinSession の効果は以下の 3 つです。

  1. 冒頭で述べたモチベーション維持の効果
  2. 共有された成果がよりよくなるような提案をいただける
  3. 他の人の成果からアイデアをふくらませることができる

以下では、WinSession の効果のうち、特に2 つ目が効力を発揮して、よりよい成果を出せた事例を紹介します。

Win: テストを高速化した!

Vitest でテストを高速化

ある日私は、新 BFF のユニットテストフレームワークを Jest からVitestに乗り換えることで、ユニットテスト全体に 1 分かかっていたものを約半分の 30 秒に短縮する成果を上げました。

vitest.dev

新 BFF は、TypeScript 製フレームワークであるLoopBackを採用しています。LoopBack は decorator に型情報を持たせるため、トランスパイル時に型情報を保存する、 tsc でいうところの emitDecoratorMetadata オプションに相当する機能が必要です。

一方、Vitest はトランスパイルに esbuild を使用しています。

esbuild.github.io

esbuild は速度を重視する思想から、emitDecoratorMetadataのような TypeScript の型システムに関する機能をサポートしません。 有志がプラグインを作成しているものの、対応する esbuild のバージョンが古く、Vitest をそのまま使うことはできませんでした。

そこで、esbuild と同じく、速さが売りの SWC に目をつけました。

swc.rs

SWC は tsc を書き換えることも目的としているので、emitDecoratorMetadata に相当する機能をもっています。 Vitest に対しては rollup-plugin-swc3 を使うことで導入できました。

ここまでたどり着くのに少し時間がかかったので、WinSession で自慢したい!と息巻いていました。

ビルドも速くしたい!

テストが速くなったので、ビルドも tsc から SWC に乗り換えれば、もっと生産性を上げることができないかと考えました。 しかし、SWC を使って TypeScript をトランスパイルする場合には、次の課題がありました。

  • SWC は通常 ESModule のコードを出力するため、CommonJS を用いる LoopBack がビルド後のコードを読み込めない
  • 開発時に使う tsc-watch を廃止したいが、SWC には tsc-watch の onSuccess 相当の機能がなく、「差分ビルドが終わってからサーバを再起動する」ことができない

課題はさておき、Vitest を使えるようになったのはうれしい!ということで、WinSession にネタを持っていきました。

Session: Node.js の専門家に相談

WinSession 当日

さて WinSession 当日、Vitest の成果を共有しました。そして、ビルドにも SWC を使えないか目論んでいることも話しました。

すると、同じアーキテクトグループの相馬さんから、esbuild や SWC の速さの秘訣について教えていただくことができました。

相馬さんは自他共に認める Node.js の専門家で、過去にこんな記事も書いていらっしゃる方です。

www.lifull.blog

www.lifull.blog

相馬さんなら SWC の設定にも詳しそうだと思ったので、ビルド高速化について抱えている課題を話してみました。 すると、なんとその日のうちに、SWC によるビルドを行えるようにする Pull Request を作っていただくことができました。

この Pull Request には、SWC によるトランスパイルで CommonJS を出力する設定のほか、トランスパイルと型チェックを並列に行うスクリプトも含まれていました。

あと一歩!

ところが、これで解決、めでたしめでたし…とはなりませんでした。開発用サーバを起動する場合に、トランスパイルとサーバ起動を並列に行っている状態でした。 これだと最初に起動する際は

  1. 以前のビルド結果を削除
  2. SWC の全体トランスパイルとサーバの再起動を同時に行う

となるのはよいのですが、この後

  1. SWC がファイルの変更を検知
  2. SWC が変更されたファイルだけを再トランスパイル
  3. サーバはファイルの変更を検知しないため、再起動しない

となる場合がありました。3 を解決するには、「トランスパイルが行われた後にサーバを再起動する」という、順序関係を担保するしくみが必要です。

After: 協力してビルドの高速化にも成功

実行順序の担保

私は、この問題に対して、SWC の watch モードを使う代わりにnodemonで解決を図りました。ファイルの変更を検知し、指定されたスクリプトを動作させるツールです。

nodemon.io

このツールを使うことで、

  1. nodemon が任意の ts ファイルを監視
  2. 変更を検知したら、トランスパイルとサーバの起動を順に行う

とし、トランスパイルとサーバ起動の順序関係は担保しました。 しかし、これでは SWC の差分トランスパイル機能が使えないため、毎回すべてのファイルをトランスパイルし直す必要があります。 パフォーマンス的には片手落ちになってしまいました。

再び専門家に仰ぐ

もう一度相馬さんに相談し、nodemon の監視対象の制限方法と、delay 機能を教えていただくことができ、次の構成になりました。

  • SWC のトランスパイル結果が出力される
  • js ファイルが出力されたら、500ms 後にサーバを起動する

結果、実行順としては

  1. SWC のトランスパイル開始と同時に、nodemon が出力先ディレクトリを監視
  2. js ファイルが出力されたら、500ms 後にサーバを再起動する

となり、すべての問題が解決しました。

最終的に、全体のビルド速度は、tsc を使っていたころに約 24 秒かかっていたのが約 8 倍の 3 秒となりました。 開発サーバのファイル変更検知による再起動も、SWC のトランスパイルによって、tsc 時代より大幅に短縮された速度で行われるようになりました。

結果、テストだけではなく、ビルドも高速になり、生産性向上に大きく貢献できました。

終わりに

今回は、WinSession で成果を共有することで、よりよい成果につながった事例を紹介しました。

WinSession で成果を称え合う文化があることで、モチベーションを高く保ちながら働くことができています。さらに、WinSession で成果を共有できたことで、新卒でも専門家の教えを受けながら働ける、貴重な機会に恵まれました。

LIFULL 社員の行動規範であるガイドラインには、「真のチームワークを築く」という節があります。個人的に WinSession は、これをよく表す、LIFULL らしい取り組みだと感じています。

一緒に働きませんか?

LIFULL には、Node.js 以外にも数多の専門家がいます。新卒、中途問わず、一緒に働いてみたい!という方、ぜひこちらも合わせてご覧ください。

hrmos.co

hrmos.co