hacomono TECH BLOG

フィットネスクラブ・スクールなど施設・店舗のための会員管理・予約・決済システム「hacomono」 開発チームの技術ブログ

(小ネタ) Vitest でパフォーマンス劣化を検知する

どうもみゅーとんです.
最近パフォーマンス周りで問題をおこしかけてしまったので, パフォーマンスの劣化を抑制する方法を調べてみました.

概要

3 行でまとめ

  • public repository であれば, CodSpeed を無料で利用できる
  • main ブランチでのパフォーマンスを計測しておき, Pull Request で劣化したら警告してくれる
  • CodSpeed から, 内部処理を詳細に追うことができる

前提知識

vitest でパフォーマンステストを行う構成ができていることが条件になります.
導入方法についてはこの記事を確認してください. techblog.hacomono.jp

CodSpeed とは

docs.codspeed.io

なんて読むんでしょうか・・?私はコードスピードと呼んでいますが, コッドスピードのほうが正しそう・・?

GitHub Actions で実行した Python, Rust, JavaScript のベンチマークテスト結果を使って, パフォーマンスリグレッションテストを行ってくれる

GitHub Repository と連携するとすぐに利用可能になり, JS の場合だと tinybench の実行結果を Actions から CodSpeed に送り, 詳細を表示してくれるようになります.

PullRequest 作成時に main ブランチとの比較でパフォーマンス劣化 (デフォルトで 10% の劣化) があれば, 教えてくれる機能があり, 大幅なパフォーマンス劣化を検知できます.

なんと, Public Repository では無料で利用できます.

導入してみた

今パフォーマンス周りで最も気になっているのは, hacomono-lib で OSS として公開している json-origami なので, これに導入してみました.

通常は tinybench での実行に対して手を入れるようですが, vitest の benchmark test から tinybench を使っている場合は vitest 用のプラグインを導入すれば良いようです.

vitest を利用している場合の専用のマニュアルが存在しました. docs.codspeed.io

導入方法

vitest の設定を追加

@codspeed/vitest-plugin を導入し, vitest.config.ts にプラグインとして追加します.

yarn add -D @codspeed/vitest-plugin
+import codspeed from '@codspeed/vitest-plugin'
 import { defineConfig } from 'vitest/config'

 export default defineConfig({
+  plugins: [codspeed()],
   test: {
     benchmark: {
       include: ['test/**/*.bench.(js|ts)'],
     },
   },
 })
GitHub Actions を設定

main ブランチと, current Pull Request で実行したいので, 以下のように設定しました.

name: Codspeed Benchmarks

permissions:
  contents: read
  packages: read
  pull-requests: write

on:
  push:
    branches:
      - "main"
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    paths:
      - ".github/workflows/benchmarks.yml"
      - "src"
      - "package.json"
      - "vitest.config.ts"
      - "yarn.lock"

jobs:
  init__node:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ./.github/actions/init-node

  benchmarks:
    runs-on: ubuntu-latest
    needs:
      - init__node
    steps:
      - uses: actions/checkout@v4
      - uses: ./.github/actions/init-node

      - name: Run benchmarks
        uses: CodSpeedHQ/action@v2
        with:
          run: yarn bench
          token: ${{ secrets.CODSPEED_TOKEN }}
GitHub 側で Repository の設定

Pull Request 毎に必ず実行してほしいので, Branch Protection Rule で, main ブランチに以下の設定をします.

Require status checks to pass before merging にチェックを入れ, 下の Status checks that are required.CodSpeed Performance Analysis を追加します.

これで, パフォーマンスの劣化を検知したときにマージをブロックできるはずです.

CodSpeed 側でも, Thresholdを設定しておきます. デフォルトは 10%.


結果を見てみる

main ブランチの計測結果を CodSpeed 上で見てみる

こんな感じになりました.

これは main ブランチにあるベンチマークテストのテストケース毎の実行結果の一覧です.

時間がかかったケースが画面上部にわかりやすく表示されてます. 面積が広ければ時間がかかってる意味かな?

パフォーマンスが劣化する PR を作ってみる

わざとパフォーマンスが落ちるようにコードを書いて, エラーを起こさせてみます.

こんな感じのレポートが Pull Request にコメントされ, テストが通過しなくなりました.
CodSpeed による通過が main ブランチへのマージ条件になっているので, これでマージを防ぐことができます.

良きですね.

CodSpeed 側の画面で見てみると, 劣化具合がしっかりレポートされています.

詳細を開いてみると, 変更前と後で関数ごとにかかった時間割合まで見れます. これ無料ってヤバいですね.


まとめ

これでパフォーマンスの劣化の軽減と, 原因の検出がこれだけでだいぶスムーズにできるのではないでしょうか.

とても良いものを見つけた!と思いました. 今後も活用していきたいです.おわり.


株式会社hacomonoでは一緒に働く仲間を募集しています。
採用情報や採用ウィッシュリストもぜひご覧ください!