Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
RailsアプリケーションをSPA化しながら容赦ない削除をした話
Search
Yuki Eda
December 12, 2023
Programming
6
7.8k
RailsアプリケーションをSPA化しながら容赦ない削除をした話
年末の大掃除〜リファクタリング・コード断捨離勉強会〜
#年末にコードの大掃除
https://timeedev.connpass.com/event/303260/
Yuki Eda
December 12, 2023
Tweet
Share
Other Decks in Programming
See All in Programming
PC-6001でPSG曲を鳴らすまでを全部NetBSD上の Makefile に押し込んでみた / osc2025hiroshima
tsutsui
0
190
組み合わせ爆発にのまれない - 責務分割 x テスト
halhorn
1
160
AI時代を生き抜く 新卒エンジニアの生きる道
coconala_engineer
1
450
GISエンジニアから見たLINKSデータ
nokonoko1203
0
190
Jetpack XR SDKから紐解くAndroid XR開発と技術選定のヒント / about-androidxr-and-jetpack-xr-sdk
drumath2237
1
200
【卒業研究】会話ログ分析によるユーザーごとの関心に応じた話題提案手法
momok47
0
130
Tinkerbellから学ぶ、Podで DHCPをリッスンする手法
tomokon
0
150
愛される翻訳の秘訣
kishikawakatsumi
3
350
20251212 AI 時代的 Legacy Code 營救術 2025 WebConf
mouson
0
220
脳の「省エネモード」をデバッグする ~System 1(直感)と System 2(論理)の切り替え~
panda728
PRO
0
120
0→1 フロントエンド開発 Tips🚀 #レバテックMeetup
bengo4com
0
420
モデル駆動設計をやってみようワークショップ開催報告(Modeling Forum2025) / model driven design workshop report
haru860
0
290
Featured
See All Featured
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
34
Design in an AI World
tapps
0
100
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
70
Paper Plane
katiecoart
PRO
0
44k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
94
Amusing Abliteration
ianozsvald
0
72
sira's awesome portfolio website redesign presentation
elsirapls
0
91
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
130
Building the Perfect Custom Keyboard
takai
1
660
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.2k
Transcript
RailsアプリケーションをSPA化しながら 容赦ない削除をした話 2023/12/12 年末の大掃除〜リファクタリング・コード断捨離勉強会〜 株式会社タイミー 江田優樹 @edy2xx
自己紹介 江田優樹(Eda Yuki)/ @edy2xx 2020年にタイミー入社 バックエンドエンジニア 今年のベストバイ: ブリタ浄水ボトル ベスト断捨離: 外付けディスプレイ
& キーボード ・ガジェット煩悩から解き放たれている ・周期的に欲しいアイテムが変わるので復活の可能性あり 好きな水風呂の温度は16℃
3
4
目次 1. UIリニューアル(SPA化) 2. 捨てた機能・コード 3. 学び
目次 1. UIリニューアル(SPA化) 2. 捨てた機能・コード 3. 学び
UIリニューアル(SPA化) - 話すテーマ - Railsでバックエンド開発をするエンジニア視点での発表になります • 管理画面のUIリニューアルの取り組み内容 • 捨てた機能やコードなどを紹介します(本イベントの断捨離ネタ)
UIリニューアル(SPA化) - プロジェクト概要 - • モノリスなRailsシステムのUIリニューアルを実施 ◦ 約30画面を新デザインに • フロントエンドの技術基盤を移行
◦ Rails による SSR(Server Side Rendering) から Next.js による SPA(Single Page Application) に移行 • 結論: 3年かかりました←
UIリニューアル(SPA化) - 当時の状況 - • フロントエンドの内部品質改善に時間を割けていない • Railsのビュー(View)にビジネスロジックやクエリ発行箇所が... • Bootstrap
をベースにしつつ、独自CSSも書く • JS書くときは基本 jQuery jQueryは 昔の彼女 (...社内で聞こえてきた声)
• フロントエンドの内部品質・外部品質を共に高めたい • モダンWebフロント技術の導入 • フロントエンドエンジニアの採用拡大 UIリニューアル(SPA化) - 当時の状況 -
CTOも交えて検討しSPA化プロジェクトスタート • TypeScript / Next.js(React) ベースの別リポジトリを切りました • Rails は Web
API サーバの役割に特化 • アクセス数の少ない画面からじわじわ移行 ◦ 全画面を一気に移行する手法は取りませんでした ◦ 機能追加は最小限(基本はそのまま)
UIリニューアル(SPA化) - タイムライン - 2020年秋 2021年 2022年 2023年
UIリニューアル(SPA化) - タイムライン - 2020年秋 2021年 2022年 2023年 ・プロジェクト発足 ・技術選定
- Product Manager: 1名 - Backend Engineer: 1~2名 - Frontend Engineer: 1~2名
UIリニューアル(SPA化) - タイムライン - 2020年秋 2021年 2022年 2023年 ・リプレイス画面数最多 ・新旧UIを切り替える仕組みを提供し、
リプレイス時のハレーションを抑制
UIリニューアル(SPA化) - タイムライン - 2020年秋 2021年 2022年 2023年 ・差し込みタスク増加 ・優先順位が変化
→ プロジェクト中断
UIリニューアル(SPA化) - タイムライン - 2020年秋 2021年 2022年 2023年 プロジェクトがリスタート
約3年かかり、2023年夏にSPA化が完了🎉
• 3年はかかったが無事UIリニューアル(SPA化)が完遂 🎉 • フロントエンドをテーマに顧客体験向上を狙ったり、技術課題解消に向け た土台づくり 🔧 • フロントエンドが Rails(SSR)から
Next.js(SPA)に生まれ変わった 🆕 ここまでのまとめ
生まれたコードもあれば、捨てたコードもあります
目次 1. UIリニューアル(SPA化) 2. 捨てた機能・コード 3. 学び
捨てたものその1 - Fat Controller - • タイミーで最も長く存在する Controller のうちの1つ(長老) • コアドメインのデータの作成・編集フォームに対応
• その名を聞けばメンバーが「あ〜〜(ツラい)」となる
捨てたものその1 - Fat Controller - 処理の具体例を幾つかピックアップ • 同一エンドポイントで入力フォームと確認画面の2つの責務を持ち、 オブジェクトの状態やパラメータによってaction内で切り替わる • テンプレートファイルで使うインスタンス変数が複数個あり
before_action でセットされる • ActiveRecord を介したDBへの書き込み前後で複数の条件分岐 • 外部API通信、プッシュ通知、メール・Slack送信 • 独自のエラーハンドリング
捨てたものその1 - Fat Controller - 処理の具体例を幾つかピックアップ • 同一エンドポイントで入力フォームと確認画面の2つの責務を持ち、 オブジェクトの状態やパラメータによってaction内で切り替わる • テンプレートファイルで使うインスタンス変数が複数個あり
before_action でセットされる • ActiveRecord を介したDBへの書き込み前後で複数の条件分岐 • 外部API通信、プッシュ通知、メール・Slack送信 • 独自のエラーハンドリング -> Controller 内で定義された privateメソッド に 書かれているため視線移動も多かった わからん
捨てたものその1 - Fat Controller - • 役割に対して暗黙的に抱えている責務が過剰にあった ◦ 役割 = “リクエストの意味を理解して適切な出力を行う”*
と定義 • テストコードでの仕様の網羅性や理解容易性が低い * Railsガイド の Action Controller の概要 を参考
捨てたものその1 - Fat Controller - • 役割に対して暗黙的に抱えている責務が過剰にあった ◦ 役割 = “リクエストの意味を理解して適切な出力を行う”*
と定義 • テストコードでの仕様の網羅性や理解容易性が低い -> FormObject を活用したリファクタリングを行いました * Railsガイド の Action Controller の概要 を参考
捨てたものその1 - Fat Controller - Api::V1::EventsController#create を題材にすると... • ユースケースに対応したロジックを持つクラスを作成 ◦ 例:
Api::V1::CreateEventForm • Controller では FormObject の呼び出しのみ ◦ 例: CreateEventForm.new(event_params).create! • あとはJSONオブジェクトやステータスコードを返却
捨てたものその1 - Fat Controller - Api::V1::EventsController#create を題材にすると... • ユースケースに対応したロジックを持つクラスを作成 ◦ 例:
Api::V1::CreateEventForm • Controller では FormObject の呼び出しのみ ◦ 例: CreateEventForm.new(event_params).create! • あとはJSONオブジェクトやステータスコードを返却 -> Controller のダイエットに成功 🔥
捨てたものその1 - Fat Controller - Api::V1::EventsController#create を題材にすると... • ユースケースに対応したロジックを持つクラスを作成 ◦ 例:
Api::V1::CreateEventForm • Controller では FormObject の呼び出しのみ ◦ 例: CreateEventForm.new(event_params).create! • あとはJSONオブジェクトやステータスコードを返却 -> Controller のダイエットに成功 🔥 -> ただし、単にロジックを移しただけになりたくは無かった
• テストピラミッドを意識 ◦ 結合テスト(RSpec: Controller specs) からユニットテストへと比率を上げる • テストに仕様を残す ◦
残しづらい場合は設計にフィードバックする 捨てたものその1 - Fat Controller - UIテスト 結合テスト ユニットテスト
捨てたものその1 - Fat Controller - ファイル上部に君臨し続けていたTODOコメントも消せました
捨てたものその2 - 確認画面 - 「この確認画面、本当に必要?」というシーンに遭遇したこと無いですか?
捨てたものその2 - 確認画面 - 「この確認画面、本当に必要?」というシーンに遭遇したこと無いですか? • タイミーにはありました • フォームで確認画面をワンクッション挟む • ブラウザ機能の
confirm ではなく独立した “画面”
捨てたものその2 - 確認画面 - • UIリニューアルの機会を利用して消しました • 顧客からのネガティブなフィードバックは観測せず • リニューアル時のE2Eテストのパターンを相当減らせた ◦
ブラウザバックの加味、前画面の入力値の引き回しなど
捨てたものその2 - 確認画面 - • UIリニューアルの機会を利用して消しました • 顧客からのネガティブなフィードバックは観測せず • リニューアル時のE2Eテストのパターンを相当減らせた ◦
ブラウザバックの加味、前画面の入力値の引き回しなど → 画面や機能を消すのは勇気も要るがリターン大 → 機能の存在意義を一度問い正してみましょう(自戒)
• Bootstrap ベースの Material Dashboard を使用していましたが削除 • Webpacker(*) や Yarn
も不要になりリポジトリから消しました ◦ Dockerfile や .circleci/config.yml でも断捨離成功 🎉 捨てたものその3 - CSS, JSライブラリ - * webpack ビルドシステムのRailsラッパー
捨てたものその3 - CSS, JSライブラリ -
• 5万行以上のソースコードが消えました ◦ CSS, JSのvendorファイルが大量にあった • テンプレートファイルやヘルパーメソッドなどViewロジックに関わるコード 消したソースコード行数は5万行にのぼる
• 5万行以上のソースコードが消えました ◦ CSS, JSのvendorファイルが大量にあった • テンプレートファイルやヘルパーメソッドなどViewロジックに関わるコード -> 徹底的に削除しきる(将来の負債になる可能性を潰す。単に残しておくと dependabotの対象になったりバージョン管理タスクが残る)
-> プロジェクトの完了条件に盛り込む 消したソースコード行数は5万行にのぼる
目次 1. UIリニューアル(SPA化) 2. 捨てた機能・コード 3. 学び
リファクタリングや機能・コード削除で得られるメリットがある • 保守性が上がる • コードの理解容易性が増す • 操作対象の画面数が減る(顧客も嬉しい) • 自動テストの実行時間が若干短縮 ◦
HTMLの動的な生成処理が無くなったので 学び
• マネジメントライン(CTO, EM, PdM)がプロジェクト完了条件にリファクタや コード削除を盛り込むことに理解があった • 初登壇 & SPA化しきったぞ!と発表する機会をくれた @r_kawamata
さん • #容赦ないリファクタリング の精神を授けてくれた @sugaishun さん 感謝 - Thanks -
• 3年はかかったがフロントエンドをRailsからNext.jsに移行し、 UIリニューアル(SPA化)が完遂 • その過程で削除やリファクタリングが出来ました • 開発者/顧客にポジティブな影響をもたらしました まとめ
“削除” も1つのテーマになった!💡
We are Hiring!! - 絶賛採用中!! -
RailsアプリケーションをSPA化しながら 容赦ない削除をした話 2023/12/12 年末の大掃除〜リファクタリング・コード断捨離勉強会〜 株式会社タイミー 江田優樹 @edy2xx
Thank you