Backbone.jsでフロントエンド開発

はじめまして、エンジニアの高松です。 今回は先日リリースした、「色・サイズ改修」でのフロントエンド開発についてお話したいと思います。

概要

「色・サイズ改修」は、主に以下を目的としたプロジェクトです。

  • 購入可能な色やサイズが、ひと目で分かるようにする
  • 次期リリースで、色とサイズを選択して購入できるようにすることで、誤注文を減らす
  • 商品の色・サイズのデータを蓄積し、運営に活かす

リリース時のお知らせがこちらです。

BUYMAはC2Cのショッピングサイトなので、改修は大きく出品側と購入側に分かれます。 開発は私と部長の2人体制、さらにデザイナーのチームで制作しました。

私: 出品側開発 部長: 購入側開発 デザイナー: 全般的なデザイン

開発の始まり

部長が先行して開発した部分を引き継ぐことから、開発は始まりました。

引き継いだのは、500行ほどのJavaScriptでした。 検討中の画面の仕様と併せて見ると、動的な制御の多いポップアップ画面のコードの一部です。

$と_の量が多い事と、「ここはAjaxで取ってくるか?」というコメントが気になりましたが、続きを書き始めました。

ajax-mozaic

行き詰まり

少しずつ画面が動き始め、行数にして1300行を超えた頃でしょうか、開発が日に日に辛くなってきました。 ちょっとした修正にも時間がかかり、どこかを直せば、どこかが壊れます。 私(と部長)の書いたコードが読みづらく、子泣きじじいのように重くのしかかってくるのです。

「このまま作りきれるのか...」不安が募ってきたところで、一度書いたコードを捨て、Backbone.jsで書きなおすことを決めました。 一部ですが、既にBUYMAの中にはBackbone.jsで書かれた部分があったのが理由です。

Backbone.jsの導入

結果、Backbone.jsを使って書き直したコードは、以前よりずっと可読性が高いものに生まれ変わりました。

開発で使ったのは、View・Collection・Modelといった、Backbone.jsのベーシックな部分で、ルーターなどの機能は使っていません。 テンプレートエンジンには、Handlebars.jsを使いました。

Backbone.jsを利用して得られた、主なメリットは以下の部分です。

  • Viewとロジックが分離でき、イベントも所定の場所に書くので、処理が追いやすくなった。
  • CollectionがUnderscore.jsをラップしていて、使いやすい。eachやmapなどのコレクション系のメソッドや、findなどのファインダーメソッドがRubyRailsライクで馴染みやすかった。
  • フレームワークとしてコンパクトで、学習コストは低かった。
  • 結果として、ロジックの実装に集中できるようになったのが、一番のメリット。

逆にハマった部分です。

  • Backbone.jsのViewをappendすると、空のタグが入る。jQueryのappendと、Backbone.jsのView::setElementを使い分ける必要がありました。
  • ViewがGCに入らずメモリリークする。いわゆるゾンビビュー問題です。

ここは、ノウハウを貯めていかないといけないですね。

API

だいぶ調子が出てきたタイミングで、部長と立ち話がてら、実装の話をしました。

部長: 「APIってRailsだよね?」

私: 「いえ、出品側は既存もあるので、全部PHPでやってます。」

部長: 「いや、新規APIだからRailsで書けるじゃん。」

私: 「へっ???」

そうです、「ここはAjaxで取ってくるか?」のコメントを動かすために、APIを3本作りました。

以前の部長のポストに記載がありますが、BUYMAのコードは少しずつPHPからRailsに移行しています。 APIは独立して作りやすいので、Railsで書くのが社内では定石になっているのです。

新規でレガシーコードを増やしてしまいました、すみません...

まとめ

Backbone.jsの導入で、フロントエンド開発は随分捗りましたが、まだ課題は残ります。

  • 通化できる部分はexport、requireして読み込みたい
  • サーバ側のModelとBackbone.jsのModelがほぼ一緒になるので、重複をなくしたい
  • View -> Model、Model -> Viewの双方向のやりとりを多く書かなければいけない。
  • フロントエンドもテストが必要じゃないか?

そうです、どれも最近のライブラリやフレームワークが解決しようとしている問題ばかりです。 モダンなツールを導入して、解決していきたいですね。