Slide 1

Slide 1 text

RailsアプリケーションをSPA化しながら 容赦ない削除をした話 2023/12/12 年末の大掃除〜リファクタリング・コード断捨離勉強会〜 株式会社タイミー 江田優樹 @edy2xx

Slide 2

Slide 2 text

自己紹介 江田優樹(Eda Yuki)/ @edy2xx 2020年にタイミー入社 バックエンドエンジニア 今年のベストバイ: ブリタ浄水ボトル ベスト断捨離: 外付けディスプレイ & キーボード ・ガジェット煩悩から解き放たれている ・周期的に欲しいアイテムが変わるので復活の可能性あり 好きな水風呂の温度は16℃

Slide 3

Slide 3 text

3

Slide 4

Slide 4 text

4

Slide 5

Slide 5 text

目次 1. UIリニューアル(SPA化) 2. 捨てた機能・コード 3. 学び

Slide 6

Slide 6 text

目次 1. UIリニューアル(SPA化) 2. 捨てた機能・コード 3. 学び

Slide 7

Slide 7 text

UIリニューアル(SPA化) - 話すテーマ - Railsでバックエンド開発をするエンジニア視点での発表になります ● 管理画面のUIリニューアルの取り組み内容 ● 捨てた機能やコードなどを紹介します(本イベントの断捨離ネタ)

Slide 8

Slide 8 text

UIリニューアル(SPA化) - プロジェクト概要 - ● モノリスなRailsシステムのUIリニューアルを実施 ○ 約30画面を新デザインに ● フロントエンドの技術基盤を移行 ○ Rails による SSR(Server Side Rendering) から Next.js による SPA(Single Page Application) に移行 ● 結論: 3年かかりました←

Slide 9

Slide 9 text

UIリニューアル(SPA化) - 当時の状況 - ● フロントエンドの内部品質改善に時間を割けていない ● Railsのビュー(View)にビジネスロジックやクエリ発行箇所が... ● Bootstrap をベースにしつつ、独自CSSも書く ● JS書くときは基本 jQuery jQueryは 昔の彼女 (...社内で聞こえてきた声)

Slide 10

Slide 10 text

● フロントエンドの内部品質・外部品質を共に高めたい ● モダンWebフロント技術の導入 ● フロントエンドエンジニアの採用拡大 UIリニューアル(SPA化) - 当時の状況 -

Slide 11

Slide 11 text

CTOも交えて検討しSPA化プロジェクトスタート ● TypeScript / Next.js(React) ベースの別リポジトリを切りました ● Rails は Web API サーバの役割に特化 ● アクセス数の少ない画面からじわじわ移行 ○ 全画面を一気に移行する手法は取りませんでした ○ 機能追加は最小限(基本はそのまま)

Slide 12

Slide 12 text

UIリニューアル(SPA化) - タイムライン - 2020年秋 2021年 2022年 2023年

Slide 13

Slide 13 text

UIリニューアル(SPA化) - タイムライン - 2020年秋 2021年 2022年 2023年 ・プロジェクト発足 ・技術選定 - Product Manager: 1名 - Backend Engineer: 1~2名 - Frontend Engineer: 1~2名

Slide 14

Slide 14 text

UIリニューアル(SPA化) - タイムライン - 2020年秋 2021年 2022年 2023年 ・リプレイス画面数最多 ・新旧UIを切り替える仕組みを提供し、 リプレイス時のハレーションを抑制

Slide 15

Slide 15 text

UIリニューアル(SPA化) - タイムライン - 2020年秋 2021年 2022年 2023年 ・差し込みタスク増加 ・優先順位が変化 → プロジェクト中断

Slide 16

Slide 16 text

UIリニューアル(SPA化) - タイムライン - 2020年秋 2021年 2022年 2023年 プロジェクトがリスタート

Slide 17

Slide 17 text

約3年かかり、2023年夏にSPA化が完了🎉

Slide 18

Slide 18 text

● 3年はかかったが無事UIリニューアル(SPA化)が完遂 🎉 ● フロントエンドをテーマに顧客体験向上を狙ったり、技術課題解消に向け た土台づくり 🔧 ● フロントエンドが Rails(SSR)から Next.js(SPA)に生まれ変わった 🆕 ここまでのまとめ

Slide 19

Slide 19 text

生まれたコードもあれば、捨てたコードもあります

Slide 20

Slide 20 text

目次 1. UIリニューアル(SPA化) 2. 捨てた機能・コード 3. 学び

Slide 21

Slide 21 text

捨てたものその1 - Fat Controller - ● タイミーで最も長く存在する Controller のうちの1つ(長老) ● コアドメインのデータの作成・編集フォームに対応 ● その名を聞けばメンバーが「あ〜〜(ツラい)」となる

Slide 22

Slide 22 text

捨てたものその1 - Fat Controller - 処理の具体例を幾つかピックアップ ● 同一エンドポイントで入力フォームと確認画面の2つの責務を持ち、 オブジェクトの状態やパラメータによってaction内で切り替わる ● テンプレートファイルで使うインスタンス変数が複数個あり before_action でセットされる ● ActiveRecord を介したDBへの書き込み前後で複数の条件分岐 ● 外部API通信、プッシュ通知、メール・Slack送信 ● 独自のエラーハンドリング

Slide 23

Slide 23 text

捨てたものその1 - Fat Controller - 処理の具体例を幾つかピックアップ ● 同一エンドポイントで入力フォームと確認画面の2つの責務を持ち、 オブジェクトの状態やパラメータによってaction内で切り替わる ● テンプレートファイルで使うインスタンス変数が複数個あり before_action でセットされる ● ActiveRecord を介したDBへの書き込み前後で複数の条件分岐 ● 外部API通信、プッシュ通知、メール・Slack送信 ● 独自のエラーハンドリング -> Controller 内で定義された privateメソッド に  書かれているため視線移動も多かった わからん

Slide 24

Slide 24 text

捨てたものその1 - Fat Controller - ● 役割に対して暗黙的に抱えている責務が過剰にあった ○ 役割 = “リクエストの意味を理解して適切な出力を行う”* と定義 ● テストコードでの仕様の網羅性や理解容易性が低い * Railsガイド の Action Controller の概要 を参考

Slide 25

Slide 25 text

捨てたものその1 - Fat Controller - ● 役割に対して暗黙的に抱えている責務が過剰にあった ○ 役割 = “リクエストの意味を理解して適切な出力を行う”* と定義 ● テストコードでの仕様の網羅性や理解容易性が低い -> FormObject を活用したリファクタリングを行いました * Railsガイド の Action Controller の概要 を参考

Slide 26

Slide 26 text

捨てたものその1 - Fat Controller - Api::V1::EventsController#create を題材にすると... ● ユースケースに対応したロジックを持つクラスを作成 ○ 例: Api::V1::CreateEventForm ● Controller では FormObject の呼び出しのみ ○ 例: CreateEventForm.new(event_params).create! ● あとはJSONオブジェクトやステータスコードを返却

Slide 27

Slide 27 text

捨てたものその1 - Fat Controller - Api::V1::EventsController#create を題材にすると... ● ユースケースに対応したロジックを持つクラスを作成 ○ 例: Api::V1::CreateEventForm ● Controller では FormObject の呼び出しのみ ○ 例: CreateEventForm.new(event_params).create! ● あとはJSONオブジェクトやステータスコードを返却 -> Controller のダイエットに成功 🔥

Slide 28

Slide 28 text

捨てたものその1 - Fat Controller - Api::V1::EventsController#create を題材にすると... ● ユースケースに対応したロジックを持つクラスを作成 ○ 例: Api::V1::CreateEventForm ● Controller では FormObject の呼び出しのみ ○ 例: CreateEventForm.new(event_params).create! ● あとはJSONオブジェクトやステータスコードを返却 -> Controller のダイエットに成功 🔥 -> ただし、単にロジックを移しただけになりたくは無かった

Slide 29

Slide 29 text

● テストピラミッドを意識 ○ 結合テスト(RSpec: Controller specs) からユニットテストへと比率を上げる ● テストに仕様を残す ○ 残しづらい場合は設計にフィードバックする 捨てたものその1 - Fat Controller - UIテスト 結合テスト ユニットテスト

Slide 30

Slide 30 text

捨てたものその1 - Fat Controller - ファイル上部に君臨し続けていたTODOコメントも消せました

Slide 31

Slide 31 text

捨てたものその2 - 確認画面 - 「この確認画面、本当に必要?」というシーンに遭遇したこと無いですか?

Slide 32

Slide 32 text

捨てたものその2 - 確認画面 - 「この確認画面、本当に必要?」というシーンに遭遇したこと無いですか? ● タイミーにはありました ● フォームで確認画面をワンクッション挟む ● ブラウザ機能の confirm ではなく独立した “画面”

Slide 33

Slide 33 text

捨てたものその2 - 確認画面 - ● UIリニューアルの機会を利用して消しました ● 顧客からのネガティブなフィードバックは観測せず ● リニューアル時のE2Eテストのパターンを相当減らせた ○ ブラウザバックの加味、前画面の入力値の引き回しなど

Slide 34

Slide 34 text

捨てたものその2 - 確認画面 - ● UIリニューアルの機会を利用して消しました ● 顧客からのネガティブなフィードバックは観測せず ● リニューアル時のE2Eテストのパターンを相当減らせた ○ ブラウザバックの加味、前画面の入力値の引き回しなど → 画面や機能を消すのは勇気も要るがリターン大 → 機能の存在意義を一度問い正してみましょう(自戒)

Slide 35

Slide 35 text

● Bootstrap ベースの Material Dashboard を使用していましたが削除 ● Webpacker(*) や Yarn も不要になりリポジトリから消しました ○ Dockerfile や .circleci/config.yml でも断捨離成功 🎉 捨てたものその3 - CSS, JSライブラリ - * webpack ビルドシステムのRailsラッパー

Slide 36

Slide 36 text

捨てたものその3 - CSS, JSライブラリ -

Slide 37

Slide 37 text

● 5万行以上のソースコードが消えました ○ CSS, JSのvendorファイルが大量にあった ● テンプレートファイルやヘルパーメソッドなどViewロジックに関わるコード 消したソースコード行数は5万行にのぼる

Slide 38

Slide 38 text

● 5万行以上のソースコードが消えました ○ CSS, JSのvendorファイルが大量にあった ● テンプレートファイルやヘルパーメソッドなどViewロジックに関わるコード -> 徹底的に削除しきる(将来の負債になる可能性を潰す。単に残しておくと dependabotの対象になったりバージョン管理タスクが残る) -> プロジェクトの完了条件に盛り込む 消したソースコード行数は5万行にのぼる

Slide 39

Slide 39 text

目次 1. UIリニューアル(SPA化) 2. 捨てた機能・コード 3. 学び

Slide 40

Slide 40 text

リファクタリングや機能・コード削除で得られるメリットがある ● 保守性が上がる ● コードの理解容易性が増す ● 操作対象の画面数が減る(顧客も嬉しい) ● 自動テストの実行時間が若干短縮 ○ HTMLの動的な生成処理が無くなったので 学び

Slide 41

Slide 41 text

● マネジメントライン(CTO, EM, PdM)がプロジェクト完了条件にリファクタや コード削除を盛り込むことに理解があった ● 初登壇 & SPA化しきったぞ!と発表する機会をくれた @r_kawamata さん ● #容赦ないリファクタリング の精神を授けてくれた @sugaishun さん 感謝 - Thanks -

Slide 42

Slide 42 text

● 3年はかかったがフロントエンドをRailsからNext.jsに移行し、 UIリニューアル(SPA化)が完遂 ● その過程で削除やリファクタリングが出来ました ● 開発者/顧客にポジティブな影響をもたらしました まとめ

Slide 43

Slide 43 text

“削除” も1つのテーマになった!💡

Slide 44

Slide 44 text

We are Hiring!! - 絶賛採用中!! -

Slide 45

Slide 45 text

RailsアプリケーションをSPA化しながら 容赦ない削除をした話 2023/12/12 年末の大掃除〜リファクタリング・コード断捨離勉強会〜 株式会社タイミー 江田優樹 @edy2xx

Slide 46

Slide 46 text

Thank you