Buddy開発よもやま話 1

「Buddy」の無料体験版をリリースしてから約2ヶ月が経ちました。
実装予定の機能や皆様の声から生まれたアイデアなど、今後も新しい展開を数多く検討しています。
今後も「Buddy」の展開にご期待ください。

さて、今回からはじまりましたこのコラムでは、「Buddy」開発に関わるウラ話や、知っておくと便利なアプリ作成のコツなどを不定期にお話していこうと思います。

ちょっとした読み物と思ってお付き合いいただければ幸いです。

 


第1回 『Buddy開発よもやま話 1』

Webアプリ開発システムBuddyの開発に携わった立場から、感じたことを思いつくまま書き綴ったよもやま話です。

BuddyはReactを使用していますが開発の初期にはAngularJSの使用を検討したこともありました。その中で感じたそれぞれの特長などについて書いてみたいと
思います。

振り返ると昔のWebアプリはサーバー側のプログラムで画面を構成するHTMLをすべて組み立てて、ブラウザはそれを表示するだけでした。ユーザーの入力はそのままサーバーに送られ、それに応じて画面全体が作り直されてブラウザに返される、という繰り返しです。
画面が複雑になってくると、いかにネットワークが速くなったと言ってもこれでは機敏な動作は望めません。
実際に変更のある部分だけをサーバーから取得し、それに応じて画面の対応する部分だけを書き換えるようにしたい。それを可能にしたのがAjaxによるサーバーとの通信とDOMによる画面の書き換えです。その利用には結構面倒なコードを書かねばなりませんでしたが、jQueryの登場によって簡潔なコードで書けるようになりました。

これによって、アプリのうちの一定の部分(少なくとも画面表示に関する部分)のプログラムはブラウザ側で実行されることになってきます。最初にサーバーからアプリの初期画面とプログラムを取得したあとは、そのプログラムが必要に応じてデータをサーバーとやりとりしながら画面を書き換えていくことで動作します。
異なるURLが必要となるのでない限り、ページ全体を読み直すことはしません。これをシングルページアプリケーションと呼んだりします。最近のWebアプリは概ねこの作り方になってきていると思います。Buddyもその流れに沿っています。

しかしアプリの画面がきちんと動作するようにするには、何らかの設計方針が必要です。画面が複雑になって、あちらを触るとこちらに影響し…という連動が絡み合ってくると、プログラムはすぐスパゲッティ化してバグも生まれやすくメンテナンス性も悪くなります。jQueryは便利ですがそこまでは助けてくれません。そこで登場してきたのがReactやAngularJSといったライブラリです。

ReactはUIライブラリ、つまり画面を構成する表示・入力要素を組み立てるためのものです。
HTMLは<div>や<input>などのタグによって配置した要素によって組み立てられていますが、Reactは例えば<Calendar>といった仮想的な要素を定義して、それを組み合わせて画面を作っていきます。これを「コンポーネント」と呼んでいます。コンポーネントの表示内容を決める値は要素のプロパティで与えます。
例えば<Calendar year=”2017″ month=”1″ locale=”jp”/>といった具合です。
コンポーネントの中で別のコンポーネントを使うこともでき、これによって複雑な画面も階層的なコンポーネントによって構成できます。下位のコンポーネントに適切なプロパティを与えるのは上位のコンポーネントの責任とすると、画面全体の表示に必要なデータはすべて最上位のコンポーネントに渡し、それが順に下位に伝わってゆく、という一方向の情報の流れになり、画面の状態管理が非常にスッキリします。これがReactの基本的な設計思想だと思います。

しかしこれだとどこか一部分の変更でも画面全体を書き直すようなことになり、いかにも非効率ではないか。またDOMを操作するプログラムを書いた経験のある方なら、DOM操作は遅いのでそれでは処理が重くなるのではないか、と思われるかと思います。
Reactは「仮想DOM」という仕掛けでこの問題に備えています。仮想DOMはいわば前回の内容を覚えておいて実際に変更のあった部分だけDOMの更新を行ってくれるものです。これによって実行効率は気にせずにシンプルなロジックで画面更新が行える、というわけです。

もちろんアプリの動作のうえでは、入力要素へのユーザーの入力をどう扱うか、いわゆるビジネスロジックと画面表示や入力をどう結びつけるか、という問題も解決しなければなりません。Reactにはコンポーネントの内部状態を管理するstateというプロパティと、ビジネスロジックに関連するFluxという設計方針があって、考えなければならないことは色々あるのですが、その話はまた別の機会にします。React自体の守備範囲はあくまでUI構築で、それ以外はユーザーに任されています。

 

 一方AngularJSは単なるUIライブラリではなく、MVC(Model-View-Controller)フレームワークです。
HTML要素にng-controllerやng-modelといった独自プロパティを付与しておくと、ページをロードしたときにAngularJSがそれを読み取って必要なイベントハンドラなどを設定してくれる、というのが基本的な仕掛けです。
Reactのような仮想DOMの仕組みはなく、DOMを直接操作します。状態変数とそれを表示・入力する要素を関係づけておけば、状態変数が変わったときに表示を更新し入力があったときに状態変数を更新することはAngularJSが面倒を見てくれるので、そういうよくある処理のコードが圧倒的に少なくなります。またController部分のコードがひとまとまりになって見通しが良くなります。Reactのコンポーネントのような独自の要素を作れる「ディレクティブ」という仕組みもあります。フレームワークですのでその枠組みの中で書かなければなりませんが、AngularJSをうまく使うとWebアプリの生産性は非常に高くなると思います。

 

Buddyも当初はその生産性の高さを考えてAngularJSを使うことを検討していました。しかしBuddyの開発画面には非常に多くの要素が並び、複雑に絡み合うことになります。AngularJSはDOMを直接扱うため操作が重くならないよう工夫する必要が出てくる懸念がありました。Reactであればそこは仮想DOMに任せることができて開発の負担が減ることからReactを使うことにしました。もちろんこれはあくまでBuddy開発における我々の判断です。その得失は対象システムの内容に沿って具体的に検討すべきで、一般的にどちらが良いかを言うのは難しいと思います。

もう一つ、Buddyは開発システムですので、Buddy自体の設計だけでなく、Buddyで作成するアプリの設計をどうするかも考えなくてはなりません。
AngularJSはフレームワークですので、採用すればその枠組みの中でアプリを作ることになり、Buddyはそれを支援するシステムということになります。そういうシステムがあれば便利ではないかと思っていますが、Buddyユーザーにその枠組みを強制するのが良いかは判断が難しいところでした。

 

現時点でのBuddyでは、作成するアプリの画面に配置するモジュールは内部でReactを使っていますが、ユーザーの作るアプリの設計に上記のようなReactの設計思想を強制することはしていません。用意されている仕組みは、画面に配置したモジュールに対してイベントハンドラが書け、モジュールに用意されたアクションが実行できる、というベーシックなもので、それを使ってアプリをどう設計し組み立てるかはユーザーに任されています。
もちろんそれだけでイチからアプリを作るのは大変なので、登録・編集や検索と言ったよくある画面はテンプレートから作成できる機能などを用意していますが、将来は優れたライブラリやフレームワークのアイデアを取り入れて、より積極的にアプリの設計を支援する機能を盛り込めたらと思っています。

 

2017/01/10 N(Buddy開発担当者)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です