2015年4月3日
JavaScriptのフレームワークについて検討してみよう
(2015-02-28)by Allen Pike
本記事は、原著者の許諾のもとに翻訳・掲載しております。
(注記:4/10、いただいた翻訳フィードバックを元に記事を修正いたしました。)
ほとんどのプログラミング言語は、評判のよい安定した、ごく少数のアプリケーションフレームワークをサポートしています。Objective-CやSwiftのアプリケーションではAppleの優れたフレームワーク、Cocoaを使用しています。Rubyのアプリケーションは、大抵Railsを使います。Javaには確立されたWebアプリのフレームワークが少数あって、それらは比較的ゆっくりと移り変わっています。
一方でJavaScriptのフレームワークは、およそ16分ごとに、最新で最良のものが誕生しています。
研究によると、(より新しくより優れたフレームワークが発明されない限り)作るのが最も複雑なJavaScriptのアプリはToDoリストだそうです。幸い、ToDoのサンプルプロジェクト経由でJavaScriptのフレームワークを比較する、 TodoMVC という優れたサイトがあります。そこでは、63個のJavaScriptのアプリケーションフレームワークのToDoの例とjQueryあるいはVanilla JavaScript(jQueryなどのライブラリを使わないJavaScript)を比較したものを見ることができます。63個のフレームワークと聞いて、随分たくさんあると思ったでしょうか。しかし、それだけではありません。TodoMVCチームは毎週、新しいJavaScriptのフレームワークを使いこんでいる人から、 複数のプルリクエストを受けとっています 。
例えば、この原稿を書いている時点で 最新のTodoMVCのプルリクエスト は、Riot.js2.0を加えて欲しいというものでした。Riot.js 2.0とは何かと思われるかもしれませんね。どうやら、Riot.jsと呼ばれるアプリケーションフレームワークの2番目のバージョンのようです。Riot.jsとは、React.jsのようなアプリケーションフレームワークですが、非常に重要ないくつかの点で改善されたものです。でも、あなたは不思議に思ったかもしれません。“そのReactのようなアプリケーションは誕生したばかりで、バージョン1.0にもなっていないじゃないか。どうしていきなり2.0なんだ?” 答えは、それがJavaScriptだから、です。
どうしてJavaScriptのフレームワークの環境は、こんなにも安定していないのでしょうか。この異常な状態を引き起こしているものは何なのでしょう? なぜRubyの開発者はRails 4.2を使っているのに、クライアント側の開発者はboron.js 0.2.1を売り込もうとするのでしょうか?
問題は、例によってブラウザにあります。元々は簡単な文書を表示する方法だったことを考えたら、現代のWebブラウザはエンジニアリングによって驚くほど発展しました。Node.jsやio.jsコミュニティでは、確かに相当な量のフレームワークが入れ替わっています。しかし、ブラウザアプリのフレームワークの世界で起きている混乱とは比べものにならないでしょう。クライアント側のJavaScriptが手に負えないほど不安定なのは、ブラウザの歴史的な限界と驚異的な速度で起こる改善によるものです。
ブラウザは、史上最高に普及しているアプリケーション実行環境で、そのためのアプリケーションを構築するにはJavaScriptを書く必要があります。その結果、JavaScriptは最も選ばさるを得ないスクリプト言語になっています。クライアント側でJavaScriptのアプリケーションを書く人の大多数は積極的に選ぶわけではなく、クライアント側のWebの発達のためにはJavaScriptを選択するしかないのです。彼らのバックグラウンドは様々で、目指すゴールも様々です。この新しいアイデアと興味の定期的な流入は、JavaScriptの世界を非常に多様化させています。
ところが、ブラウザ自体の変化は、他のフレームワークの土台となっている内在する言語よりもはるかに速く、予測不能です。1988年にCocoaの登場によってObjective-Cは変わりましたが、2010年にBackbone.jsが登場した時には、さらに大きな変化がブラウザに起きたのです。ブラウザは常に改善されていて、それによって新しい世代のフレームワークが生み出されています。
これらのインプットはかなりの量の試みと興奮、適応を促します。新しいフレームワーク、新しいアプローチ、新しいツールが、 Githubという名の間欠泉 から毎日湧き出ています。JSConfでは 奇抜な新しいアイデア や 印象的な新しいブラウザ 、 ベストプラクティスの再考 に関する素晴らしいトークが年々増えています。この美しきカオスは他の開発者コミュニティでは目にしたことがないという意味で、エキサイティングです。
残念なことに、コミュニティが新しい機能やフレームワークの作成に力を入れるかたわら、ブラウザはそれらを排除するよう動いていました。
C++やSwiftで使用するフレームワークとは違い、あらゆるアプリケーションフレームワークはユーザが使用する前にダウンロードし、解析を行って機械コードに変換しなければなりません。キャッシングやオフラインアクセスは常に向上している一方、帯域幅、待ち時間、メモリ、そしてロード時間などの現実的な制約は巨大なアプリケーションフレームワークにとって大きな課題となるのですが、そのようなフレームワークの利用はネイティブアプリ開発において当然のものとなってしまっています。
これは特に、既にメモリ・CPU・ネットワーク帯域幅の限界に達しようとしているモバイル機器に顕著なものです。現時点でJavaScriptはとても速い言語ではありますが、Web上のいたるところに存在します。そのため、作成したコードやフレームワークを誰かがダウンロードし、まったく適さない環境で実行してしまうかもしれないのです。Mac ProのChrome Canaryの超強力なパワーの恩恵を受けることができたとしても、古いAcer製のEvoAMAZE Plus 3G Eにおける”ブラウザ”では快適に動作しないでしょう。
クライアント側のフレームワークが航海する荒れ狂う海は、ネイティブな方法で豊富な環境やアプリケーション構築のためのUIライブラリを作成しようとするような、大きく、野心的なフレームワークにとっては特に危険です
2007年にSproutCoreとCappuccinoが登場した時、私はその 感動的なデモ に感化されました。ついにムーアの法則に従ってブラウザに美しいデスクトップ向けようなのアプリを構築できる、安定して先進的なJavaScriptフレームワークが登場したと思いました。それから2年間かけてSproutCoreを 導入しました 。数メガバイトにも相当する量の誰かが作成したJavaScriptを扱い、IE7におけるひどいDOMパフォーマンスのせいで必要とされる異様な技術的選択に取り組み、そしてどうにかして256MBのRAMしか持たないiPadに無理やり詰め込みました。しかしその一方、そういった変更点に対してマニュアルの作成がまったく追いつかず、パフォーマンスは常に問題だらけでした。そのため、これ以上向上の余地がないと悟るのに、そう時間はかかりませんでした。
多くの面でまだ私はSproutCoreやCappuccinoが約束していたような事項を実現できるフレームワークの登場を期待すると同時に、今はその構築の難しさをより実感しています。JavaScriptにおいては特にそうです。柔軟性があり、型付けされていない性質はJavaScriptでのマイクロフレームワークの使用を楽しくする一方、大きなフレームワークを学んだり、維持したりするのに嫌気がさすようになります。ネイティブアプリケーションの強い型付けは細かなプロジェクトでは厄介に感じられるかもしれませんが、大きくなりがちなAPIの調査を簡単にし、効果的に使用できるようにします。ただTabキーで自動補完させるだけでよいのですから。
Cocoaフレームワークでは非推奨APIを使用するとプロジェクトを開くときに警告が表示されます。そして時には、右クリックだけで古い方法を新しい方法に変更することができます。一方JavaScriptにおいて、使いたいAPIを探すためにWebkit REPLを覗くことは、フレームワークをアップデートした後にアプリケーションの実行環境を膨大にしてしまうサポートされていない公開APIを偶然にも見つけられる良い手段です。
目まぐるしい変更、様々な必要事項、不適切な環境、そして厳密ではない言語特徴、これら全てが原因で、膨大で機能豊富なJavaScriptフレームワークを遅くするのです。新しく登場した素早い マイクロフレームワーク の大群が生存競争をするがごとくJavaScriptフレームワークを排除していっているようです。モジュール性とコンポーネント化による統治です。
無数のごく小さなフレームワークが席巻する世界は、JavaScriptのエキスパートとコンサルタントにとっては実はそれほど問題ではありません。コンポーネントをいろいろと組み合わせる技術も向上していますし、私たちは時間をかけて最新の選択肢とそれぞれの長所についての知識を取り入れることができます。そうやってカンファレンスに向けて多くのネタを仕入れているわけです。でもJavaScriptを始めたばかりの人やクライアント側の正規の開発者でない人にとっては、JavaScriptの開発者が苦労するような幅広い問題を、このような小さなフレームワークで解決するのは難しいでしょう。大型で息の長いクライアント側のアプリを構築している会社であれば、何かフレームワークを決めておいて、何らかの制約を見つけるまではその決定を受け入れるしかありません。
評判の良い Mithril.jsフレームワークはたったの5KB です。ロードとパースの時間を考慮すれば素晴らしいですが、様々の根深い問題を解決できるとは限りません。一方、Railsはコードの量で100倍以上の大きさがあります。 ActiveRecordだけで1274KBもあるのです。 ブラウザ上で1.2MBのフレームワークをとても使う気にはなれませんよね。それでフレームワークの増殖は続くのです。
首まで大量のフレームワークに埋もれたような状態で、 1つだけで満足できるフレームワークを選ぶ などということは、実際には不可能でしょう。自分がおそらく正しいフレームワークを使っていないと知ることが終わりのない認知的不協和を引き起こすという、「選択のパラドックス」に陥ります。皮肉なことにこの不満のタネによって、より多くの人が独自にフレームワークを作成するようになってしまうのです。
フレームワーク選び に 疲労した 結果、JavaScriptの開発者が実際に試してみるフレームワークの数は絞られてきました。実際のところ、重要なアプリケーションをビルドするのに、Dojo、YUI、ExtJS、jQuery UI、Backbone、Ember、Cappuccino、SproutCore、GWTなどを使うでしょうか。というかGWTって覚えていますか? 他にも、Angular、Sencha、jQuery Mobile、Knockout、Meteor、Ampersand、Flight、Mithril、Polymer、ReactやFluxを使いますか? まさかですよね。
人気のある選択肢を全て試すことができる人はいません。誰もが統合と、より少ないフレームワークで実益を得られることを求めています。それで、多くの開発者が次のようなパターンに陥ってしまっています。新しいフレームワークに見込みがあって、ついには幅広い人気と評判を得て、とても有用で、これでJavaScriptのフレームワークを構築しても”クビにはならない”選択だと分かるまでは、調査に手をつけないのです。Google Trendsは二重盲検法ではありませんが、Angularへの興味は過去の他のWebアプリケーションフレームワークをはるかに超えていることは確かなようです。10年もの混沌の後、ようやく選ばれしものを見つけることができたのでしょうか。
そうです。2009年に私が最初に”理不尽に変”と評したフレームワークであるAngular.jsは、かつて他のJSアプリのフレームワークにはなかったほどの人気を獲得したようです。Googleからの本気のサポート、容易な立ち上げ手順、そして豊かなコミュニティに恵まれ、Angularはついに王座に君臨…。
ちょっと待って、何ですって? Angularチームは Angular2はAngular1.xと互換性を持たない と決定を下し、簡単にアップグレードできるパスもない?
Angular1.xに慣れ親しんできた開発者は、全く異なった見た目のフレームワークと向き合い、新しいアーキテクチャを学習しなくてはなりません。
うーん。
これは永遠に続く?
おそらく私たちはこんな風にしていつも諦めてしまうのではないでしょうか。私はかねてから、マイクロフレームワークとDOMライブラリから独自のJavaScriptフレームワークを作成するのは正気の沙汰ではないと主張してきましたが、もしかしたらこれが最もマシな手段なのかもしれません。言語の特殊性とブラウザの制限のせいで、洗練されていてかつ安定しているCocoaやRailsのようなフレームワークを作成することは不可能なのかもしれません。
この辺りで止めにしておきましょう。それにしても、React.jsは随分と評判がいいようです。少なくとも見た感じでは優秀な開発者が関わり、わくわくするようなアイデアが詰まっているようです。
そうですね、これで何かビルドしてみてどうなるか見てみたらいいかもしれません。もしかしたら、これが運命のフレームワークかもしれませんから。
Hennik Joreteg、Angelina FabbroとNigel Brooke、この記事を書くにあたってのフィードバックを下さって感謝します。
株式会社リクルート プロダクト統括本部 プロダクト開発統括室 グループマネジャー 株式会社ニジボックス デベロップメント室 室長 Node.js 日本ユーザーグループ代表
- Twitter: @yosuke_furukawa
- Github: yosuke-furukawa