はじめに
こんにちは!普段はiOS開発をメインに行っている、モバイルエンジニア志望の学生です。
先日、株式会社ジーニー様の2days春季インターンシップ(ハッカソン型)に参加してきました。
なぜ、iOSメインの自分が参加したのか?
自分自身、普段はネイティブアプリケーションの開発をしているのですが、実務に限りなく近い設計・実装プロセスを経験でき、より視座の高いエンジニアリングを体感できるインターンシップであると感じたため応募しました。
今回は「CS(カスタマーサポート)向けWebシステムの改善と新規機能開発」というテーマに対し、5名チームのフロントエンド(React)担当として参画しました。普段の領域とは少し異なりますが、そこで得た技術的な学びと、プロからいただいたフィードバックについてまとめます。
また、下記の写真は社内で撮影した写真です!綺麗なオフィスでとても作業が捗りました!

Day1:既存のサンプルサービスのリファクタリング
初日は既存コードのリファクタリングとパフォーマンス改善がメインのタスクでした。
以下が自分が着手した実装内容です。
1. DRY原則に基づいたCSV処理の共通化
まずはCSV出力機能の改修に着手しました。元々UTF-8での出力機能があり、そこに別メンバーがShift-JISでの出力機能を追加したという状況でした。
私のタスクは「出力ファイル名に現在の日時を含める」という要件でしたが、それぞれの関数にDateオブジェクトから年・月・時・分を抽出する処理をベタ書きすると、同じロジックが重複してしまいます。
そこで、最初からファイル名生成処理を共通のユーティリティ関数として切り出し、両方の出力処理から呼び出す設計にしました。チーム開発において無駄なコードの重複を未然に防ぎ、今後の仕様変更にも一箇所で対応できる保守性を意識した実装ができました。
2. 描画パフォーマンスの改善(計算量のO(N)→O(1)化)
続いて、レポート一覧画面におけるアカウント情報の参照処理を改善しました。
既存の実装では、描画のたびに配列の find メソッドを用いた線形探索が実行されており、データ量に比例してパフォーマンスが劣化する状態でした。
これを、以下の2点のアプローチでリファクタリングしました。
-
Map(辞書型)への変換による計算量削減: アカウントデータを事前にMapオブジェクトに変換することで、検索時の計算量をO(N)からO(1)へと劇的に減らしました。 -
useMemoによる無駄な再読み込みの防止: さらにuseMemoフックを活用し、依存するデータが更新された時のみ再計算させる設計とし、コンポーネントの再レンダリング時における無駄な処理を防ぎました。
【なぜこのベストプラクティスを採用したのか?】
Reactのように状態が更新されるたびに再レンダリングが走る環境において、描画のたびに find でO(N)の探索を行うと、データ量が増えた際に計算負荷が跳ね上がり、ユーザー体験を著しく損ないます。Mapによる検索の高速化と、useMemoによる不要な再計算コストの削減を組み合わせてスケーラビリティを担保することは、プラットフォームがWebであれモバイルであれ、不可欠なエンジニアリングの基本だと改めて実感しました。
3. AIに頼らず「対話」で乗り越えたリファクタリングと責任感
今回のインターンではDay1のリファクタリングタスクにおいてAIを用いたコード生成が禁止されており、AIの用途は既存コードの理解(リーディングの補助)のみに制限されていました。
普段の個人開発とは異なる縛りでしたが、結果としてこれが大きな学びにつながりました。AIにリファクタリングの答えを丸投げするのではなく、メンターの方々やチームメンバーに積極的に質問し、アドバイスをいただきながら実装を進めました。
AIの出力結果をただコピペするのとは違い、現場のプロの思考プロセスを直接吸収しながら自らの頭でロジックを組み立てたことで、一行一行のコードに対する「解像度」と「責任感」が格段に上がったと感じています。
4. Day1でのチーム開発での反省
技術的な改善が進む一方で、該当箇所を修正していることを全体へ共有しきれておらず、コンフリクトを起こしてしまいました。初対面のメンバー同士での開発において、「相手に正しく伝えるコミュニケーション」の重要性を痛感しました。
Day2:Day1でリファクタリングしたものに機能を追加する
Day1の反省を踏まえ、Day2では「誰がどこを触るか」の作業領域の明確化と、こまめな声掛けを徹底しました。ミッションは、新規機能である「時間別レポート」の実装です。
Day2ではAIエージェントの使用が許可されたため、自分はエディタに「Cursor」を活用し、スピード感を持って実装を進めました!
顧客視点に立った要件の深掘り
チームとしてこだわったのは、「ただ言われた通りに作る」のではなく「顧客は本当にどの時間を参照したいのか?」というユーザー視点での要件定義です。
ホワイトボードを活用し、「『過去1時間』とは、アクセスした瞬間からの1時間なのか、直近の正時(00分)からの1時間なのか」といったユースケースを徹底的に議論しました。
苦労・工夫した点:アーキテクチャ選定と「関心の分離」
要件が固まった後、集計処理をどこで行うかについて、フロントエンドとバックエンドの責任分界点を以下の3案で比較検討しました。
- 案1: フロントでデータ処理を直接行って表示する
- 案2: バックエンドで新規テーブルを作成し、フロントはDB参照のみ行う
- 案3: フロントがパラメータを指定してリクエストし、バックエンドがデータを加工して提供する
議論の結果、私たちは「案3」を採用しました。
既存のテーブルに必要なデータが揃っている中、半日という限られた時間で新たに別テーブル(サイドテーブル)を構築する「案2」は、実装コストに見合わないと判断して見送りました。
【なぜこの設計(ベストプラクティス)を採用したのか?】
最大の採用理由は、「関心の分離(Separation of Concerns)」による開発効率の向上と、「データの二重管理防止」です。
UIの描画と重いデータ集計処理を密結合させないことは実践的なベストプラクティスです。フロントエンドは「最適なUI提供」に、バックエンドは「SQLを用いたデータの抽出・集計」にと関心事を明確に分離することで、システム負荷を下げつつ並行開発をスムーズに進めることができました。
また、安易に新規テーブルを作成せず、既存のテーブルから動的にデータを生成(案3)したことで、将来的に元データが更新された際の不整合リスクを未然に防ぐ、保守性の高いアーキテクチャに落とし込めたと考えています。
現場のプロからのフィードバック:「toC思考」から「B2B思考」への転換
今回のインターンを通して、メンターの方からいただいた言葉で最もハッとさせられたのが、「機能要件をそのまま鵜呑みにするのではなく、顧客が本当に欲しいものは何なのかを考え抜き、コミュニケーションをとることの重要性」です。
これまでiOSアプリの個人開発をしてきた私は、どうしても自分がユーザーとなるtoC(一般消費者向け)の視点でアプリケーションを考えていました。しかし、今回のCS向けシステム改善を通じて、「顧客のビジネス課題を解決するためのtoB(SaaS)的観点」が自分に決定的に不足していることに気付かされました。
単に技術を追うだけでなく、ビジネスの視点を持ってシステムを設計していくことの重要性を、現場のプロフェッショナルから直に学べたことは大きな財産です。
おわりに・Next Action
普段のiOS開発とは異なるWebフロントエンドの環境でしたが、「計算量の最適化」や「関心の分離」といった根本的なエンジニアリングのベストプラクティスは共通であり、それを本質的に理解できた2日間でした。
そして何より、今回の経験を通してWebアプリケーション開発の奥深さと面白さに気づくことができました。 今後はiOS開発はもちろんのこと、Web開発も継続して学び、フロントエンドからモバイルまで幅広い視点で価値提供できるエンジニアを目指していきます。
最後に、手厚く指導してくださった株式会社ジーニーの社員の皆様、そして共に駆け抜けたチームメンバーに心から感謝申し上げます!