📱

モバイル対応でコードが複雑化?ロジックとビューの分離で解決した話

に公開

こんにちは、株式会社スタイルポートの孫です。

現在、プロダクトグループでUXエンジニア/3Dエンジニアとして、「ROOV.space」の開発に携わっています。UI/UXのデザインからフロントエンドの実装、そして3D空間との統合まで、一貫して担当しています。

フロントエンド開発において「モバイル対応」は避けて通れないテーマです。私たちが開発しているROOV.spaceのようなUIリッチなWebアプリでは、PCとモバイルでのUI要件が大きく異なるケースも多く、それによりコードの複雑化やメンテナンス性の低下が課題となっていました。

本記事では、その課題をどう捉え、どのようにアプローチし、チームで改善を進めたかを共有します。

ROOV.spaceサービス紹介

課題:モバイル対応でコードが肥大化・分断化

  • 分岐ロジックの増加
    if (isMobile) { ... } else { ... } のような条件分岐が各所に散在。
  • ロジックコードの重複
    モバイルとPCで同じ処理をそれぞれの分岐内に持つことで、処理の重複やズレが発生しやすくなっていました。変更やバグ修正のたびに、両方を意識する必要あり。

アプローチ:ロジックとビューの分離

こうした状況を踏まえ、以下のような構造への見直しを進めました:

GalleryPanel/
├── GalleryPanel.tsx         ← ロジック&状態管理
├── GalleryPanelViewPC.tsx   ← PC向けView
├── GalleryPanelViewMobile.tsx ← モバイル向けView
└── index.ts

この構成では、状態管理やビジネスロジックをGalleryPanel.tsxに集約し、View部分だけを端末ごとに切り分けます。つまり、 1つの「ロジック」と2つの「ビュー」 という構造です。

Devinとの相談とフィードバック

スタイルポートでは、複数のAIツールを導入し、メンバーが日常的に活用できる環境を整えています。今回の実装でも、開発エージェント「Devin」 を利用して、設計方針の整理やタスク分割を相談しながら進めました。

このアプローチは、React開発の一般的なベストプラクティスに沿っており、将来的な拡張性も高いです。
他の選択肢としては:

  1. CSS Media Queriesのみ: 単一コンポーネントでCSSメディアクエリを使用する方法もありますが、PCとモバイルで大きく異なる場合は管理が難しくなります
  2. HOCパターン: withMobileView()のようなHOCを作成する方法もありますが、提案されたアプローチの方がシンプルです

ご提案の方法は適切だと思います。他のコンポーネントでも同様のパターンを適用することで、一貫性のあるモバイル対応が実現できるでしょう。

「設計相談にも付き合ってくれるAI同僚」って感じでした。

実装フロー

この方針のもと、以下のように作業を進めました。

  1. GalleryPanelのView分離を依頼
    まずはViewの分離作業をDevinに依頼しました。
from sunxuan:
それでは、まだモバイルViewを考える必要がありません、GalleryPanel から、GalleryPanel & GalleryPanelViewPC ファイルを作る作業をお願いしたいです。
feature/mobile-ui-1 からブランチを作ってください、マージ先も feature/mobile-ui-1 にしてください。
  1. GalleryPanelViewMobile の追加
    その後、自分で GalleryPanelViewMobile.tsx を追加し、モバイルUIを設計・実装。

  2. 他コンポーネントへの展開
    このパターンをテンプレートとして他のコンポーネントにも展開していきました。構造が統一されることで、レビュアーにとってもコードの見通しがよくなり、チーム全体の開発効率も向上しました。

まとめ:モバイル対応は構造から見直す

モバイル対応において「CSSでなんとかしよう」とすると、後から大きな負債になる可能性があります。特に表示構造が大きく異なるUIでは、「ロジックとビューの分離」は強力なパターンです。

今回のアプローチを通して得た教訓:

  • モバイル対応のしやすさは、UIだけでなく設計レベルの構造が鍵
  • ロジック・状態とViewの明確な分離は、再利用性・保守性・テスト性すべてに効果がある
  • チームでパターンを共有することで、一貫性のある開発体験を作れる

今後もこのパターンをベースに、UIの拡張や改善を継続していきます。

Discussion