Pull Requestのレビュー負荷を軽減し、開発生産性を向上するためにチームで取り組んだこと

ogp

はじめに

こんにちは。WEARフロントエンド部Webチームの藤井です。私たちのチームでは、WEARのWebサイトのリプレイスと新規機能の開発を並行して進めています。これらの開発を推進する中で、Pull Requestのレビュー負荷を軽減し、開発生産性を向上させるための取り組みを行なってきました。本記事では、その中で効果的だった取り組みについてご紹介します。

目次

背景と課題

WEARフロントエンド部では、開発速度の向上を目指して「Pull Requestのオープンからマージまでの平均時間 24時間以内」という目標を掲げています。また、月次のKPTや週次の1on1の中で、Pull Requestのレビューに対する負荷が高いという課題が浮上しました。レビュー負荷が高いと感じる理由や当時の傾向として、以下のような意見がありました。

レビューの体制の薄さ

社員3名、内定者アルバイト2名のメンバー構成で、基本的には社員2名のapproveでマージをするルールで運用しています。このルールで全てのPull Requestを運用するには社員1人あたりのレビュー数量的に負荷が高いという課題がありました。

スコープの広さ

1つのPull Requestに複数の対応内容やついでのリファクタリング、バグ修正などを含めていることがありました。その結果、Pull Requestのスコープが広がり、何の目的でどの部分のコードを修正しているかを把握するのに負荷がかかっていました。

仕様把握の負担

各メンバーそれぞれ違う画面のリプレイスや新規機能の開発を行なっているため、レビュアーが他の担当の画面仕様を把握するのに時間がかかってしまうことがありました。特に画面のリプレイスの場合には仕様書がないため、各レビュアーが既存画面や既存コードから調査するということが発生していました。

対応内容についての説明不足

Pull Requestの対象範囲がレビュアーに伝わらず、レビュイーが意図していない対応箇所を指摘することがありました。

処理の複雑性

コンポーネントや関数の設計が複雑になってしまい、レビュアーが処理を理解するのに時間がかかってしまうことがありました。また、レビュー時点で処理の複雑性に気づき、設計と実装の手戻りが発生することもありました。

仕様の抜け漏れ

レビュー時に仕様の考慮漏れに気づいたり、仕様やデザイン面での相談が発生したりすることがあり、レビューが中断したり、実装の手戻りが発生してしまうことがありました。

動作確認の手間

ブランチをチェックアウトし、ローカル開発環境を立ち上げてUIのチェックや動作確認に時間がかかっていました。

課題解決に向けた取り組み

前述した課題に対してチーム内で改善策を話し合い、実践し、その効果を振り返りながら改善を続けました。その中で効果があったと考える取り組みを以下に紹介します。

レビュー体制の見直し

レビューするメンバーが少ない中でも品質を担保しつつ効率的に運用していくためにレビュー体制を見直しました。例えば、画像差替えや文言修正など1名によるレビューでも品質が担保できる軽微な修正に関しては1名のapproveでマージするなど例外ルールを設けました。また、内定者アルバイトのメンバーにも少しずつレビューに入ってもらい、後進育成に取り組んでいます。

Pull Requestを小さくする

Pull Requestの変更内容が大きいと、レビューに時間がかかります。例えば、変更内容の把握に時間がかかったり、まとまった時間がとれるまでレビュー着手できず遅れたりするということがありました。Pull Requestを小さくすることによって、隙間時間にもレビューができ、レビューに対する心理的な負担も軽減しました。Pull Requestを小さくするためには以下のような取り組みを行いました。

Issueを小さくする

1つのIssueに1つのPull Requestを紐づけることを基本とし、まずはIssueの単位を小さくするように心がけました。毎日の朝会でIssueを共有し、必要に応じて分割することで、Pull Requestを小さくなるように定着させていきました。

Pull Requestの粒度について明文化する

IssueやPull Requestを小さくするといっても人それぞれ感覚が異なるので、Pull Requestの粒度について明文化するようにしました。例えば、以下のようなことを明示しました。

  • 新規に作成するコンポーネントや関数は基本的に1つで1つのPull Requestとする
  • ファイルの移動やリファクタリングは機能修正のPull Requestと分けて作成する

IssueやPull Requestを小さくすると、仕様の全体像や背景がわかりづらいという問題がありました。その問題を回避するために、タスクリスト用のIssueを作成し、そこから細かいIssueを作成しています。よく使う汎用的なタスクリストについてはIssueテンプレートを設定しておくことで、テンプレートから簡単にタスクリストを作成できます。

機械的なチェックの拡充

機械的にチェックできる項目はLinterや自動テストに任せることで、レビューの効率の向上を図りました。具体的には以下の取り組みを行いました。

ESLintルールの拡充

元々、ESLintのメインのルールセットにeslint-config-airbnb-typescriptを採用していましたが、コードの複雑性もチェックするために以下のルールも追加しました。これにより実装段階で処理が複雑になることを回避でき、その結果、レビューの負担が軽減しました。

また、最近ではアクセシビリティに関するチェックを行うプラグインeslint-plugin-jsx-a11yも追加しました。こちらも実装段階で機械的にチェックできるので、レビューの負担軽減につながりました。

Visual Regression Testの拡充

以前から導入していたPlaywrightやChromaticによるVisual Regression Testにおいて、対象画面や細かいデータパターンなどテスト対象を拡充しました。UI面で意図しない変更が生じていないかのチェックを自分たちで比較する必要がなくなり、レビューコスト削減につながりました。また、機械的にチェックすることで人間の目による見落としがなくなり、品質向上にもつながりました。

Pull Requestテンプレートの拡充

仕様把握やUIチェックで時間がかかっていた課題を解決するためにPull Requestテンプレートを拡充しました。例えば、リプレイス前の画面URL、既存コードのGitHub URL、Figmaやリプレイス前の画面との比較スクリーンショットを提示するようにしました。そうすることで、各レビュアーが既存仕様の調査や画面を比較する手間がなくなり、レビュー負荷を軽減できました。現在は以下のようなPull Requestテンプレートで運用しています。

## 対応内容 <!-- やったことを簡潔に -->

### Issue

closes # <!-- このPRをマージすることで解決するIssue -->
ref. # <!-- その他このPRに関係するIssue/PR -->

### 仕様書 <!-- Confluence、JIRA、リプレイス前のURLやsourceコード -->

### この PR でやらないこと

## 比較スクショ

## 影響範囲 <!-- この変更によって影響するページなど -->

## レビュー観点 <!-- このPRで特に注視して確認して欲しいこと -->

事前の仕様・設計相談

設計や実装の手戻りを減らすために、実装へ取り掛かる前に仕様や設計に関して相談するようにしました。具体的な取り組みは以下の通りです。

仕様・デザインのレビュー

実装に入る前段階で、チーム内で仕様やデザインをレビューするようにしました。特に画面のリプレイスの場合、既存の仕様が古くなっていたり、他の画面とのUIや仕様の一貫性が欠けていたりすることがありました。これらの問題を解消するために、実装前にPMやデザイナーと相談して仕様の見直しや利用率が極端に低い機能を削除しました。また、UIや仕様の統一を図り、共通コンポーネントを利用できるようにしました。これにより、実装段階やレビュー段階での仕様やデザインの見直しが減り、開発の効率化やレビュー負荷の軽減につながりました。

実装前の設計相談

毎朝行なっているタスク・進捗共有や毎夕行なっているレビュー会において、設計方針や実装中の悩みについても相談するようにしました。これにより、レビュー時に設計から見直すような手戻りが減り、実装やレビュー時間の短縮につながりました。

コーディングルールとしての蓄積

設計相談で決まった設計方針やレビュー中にでた指摘事項などで汎用化できるものについては、コーディングルールや命名規則としてGitHub Discussionsに記載し、ドキュメント化しました。方針が明文化されていることによって実装やレビューにおける迷いが軽減されました。

レビューしやすい環境の整備

以前はローカルにブランチをチェックアウトして動作確認を行なっていたのですが、Preview環境やStorybookを活用することによって、簡単に動作を確認できるようになりました。

Preview環境を使った動作確認

有難いことに、定期的に弊SREチームが各チームで困っていることを吸い上げて開発環境の改善を行なってくれており、そのうちの1つがPreview環境でした。Pull Request毎ごとにPreview環境を起動が可能になり、Preview環境内の対象画面のURLを共有するだけで容易に動作を確認できるようになりました。Preview環境の詳細についてはSREチームの山岡による以下の発表資料をご覧ください。

speakerdeck.com

Storybookのレビュー活用

コンポーネント単位でのUI確認はStorybookを活用しています。Storybookを使用することで、ページに組み込む前のコンポーネントや、異なるデータや状態のパターンについてもそれぞれ確認できます。また、StorybookをChromatic上にデプロイしているので、ローカルでStorybookを起動せずともWeb上で閲覧でき、Chromaticにて変更点の差分も容易に確認できます。

定期的な振り返り

週に1回、Findy Team+を見て、オープンからマージまでの時間や平均の変更行数をチェックし、メンバー全員で振り返りをしました。数値が良い時、悪かった時それぞれ要因を考え、次の週へ向けて良かったことの継続や改善をしました。

取り組みの結果

前述した取り組みについては前々から行なっていたものもありますが、課題感をもってチーム全体として積極的に取り組んだのは2023年4月半ばでした。Findy Team+のレビュー分析を見ると2023年4月後半あたりにオープンからマージまでの平均時間が減り、グラフが安定してきている傾向が見られます。お休みや研修期間などもあり、マージまでの時間が少し増えている期間もありますが、2023年4月以前と比較すると時間も短く、安定しています。 2022年4月から2024年2月までの分析グラフ。平均レビュープルリク数が棒グラフ、オープンからマージまでの平均時間が折れ線グラフで表されている。

サイクルタイム比較

以下のBefore、Afterは取り組みの効果が顕著に現れた2023年5月からの半年間とそれ以前の半年間のサイクルタイム分析の数値です。オープンからレビューまでの平均時間は少し伸びていますが、それ以外の時間と全体の合計値は改善し、合計で12時間も短縮できました。

Before

サイクルタイムの分析結果。コミットからオープンまでの平均時間12時間。オープンからレビューまでの平均時間2.6時間。レビューからアプルーブまでの平均時間17.4時間。アプルーブからマージまでの平均時間1.6時間。合計値33.6時間。

After

サイクルタイムの分析結果。コミットからオープンまでの平均時間4.2時間。オープンからレビューまでの平均時間5.3時間。レビューからアプルーブまでの平均時間10.9時間。アプルーブからマージまでの平均時間0.9時間。合計値21.3時間。

主要スタッツ比較

オープンからマージまでの時間もおよそ4時間短縮でき、目標の24時間に近づくことができました。また、平均の変更行数も81行となり、Pull Requestが小さくなっています。

Before

プルリク作成数などが列挙されている。オープンからマージまでの平均時間28.7時間、平均変更行数178.5行がマークされている。

After

プルリク作成数などが列挙されている。オープンからマージまでの平均時間24.4時間、平均変更行数81行がマークされている。

まとめ

チーム全体で課題解決に取り組み、さまざまな小さな改善を積み重ねることで、Pull Requestのレビュー負荷の軽減や開発プロセスの効率化につながったと実感しています。一時的な改善に終わらせないためにも、今後も継続的な取り組みが必要であり、長期的に持続可能な開発体制を築いていくことが大切だと思います。

おわりに

ZOZOでは、一緒にサービスを開発する仲間を募集しています。ご興味のある方は、以下のリンクからぜひご応募ください。

corp.zozo.com

カテゴリー