- 講演資料(柴田氏):大規模開発におけるこれからのフロントエンド開発
- 講演資料(伊藤氏):Yahoo! JAPANが実践するOpenStackと大規模環境でのコンテナ利用
めまぐるしく進歩するフロントエンド技術
本セッションは2部構成で、前半はフロントエンド、後半はインフラについての話だった。
前半は柴田氏が登壇し「大規模開発におけるこれからのフロントエンド開発」と題して語った。柴田氏はデザイナーとして勤務しているが、最近の主な担当は、広告入稿管理のフロントエンド周りの開発だ。
柴田氏が最近のフロントエンドに関するトピックで目立っていると感じているのは「シングルページアプリケーション」。この言葉自体は新しいものではないが、最近トレンドになってきている。
従来は、サーバサイドでPHPやRubyによってHTMLを構築し、それをブラウザに返して表示させる手法が主流だった。それがシングルページアプリケーションになると、サーバから返すのは最初の一回だけで、以後はJavaScriptで必要なデータを、その都度APIで取ってくる。つまり、従来サーバサイドで行っていた処理をクライアントサイドで行っているというわけだ。すると、JavaScriptで行う必要がある処理が多岐にわたり、実装が煩雑になりやすい。「機能ごとにファイルを分割し、きちんと整理しないと、訳が分からない状況になる」と柴田氏は言う。
ここで重要になるのが、モジュールの管理だ。もともとJavaScriptはその構造上、丁寧にファイル分割したとしても、ひたすらJavaScriptの外部ファイルを定義したHTMLを読み込むことしかできない。そのため大規模なアプリケーションになると、その読み込み数が30を超えることもある。
またファイル同士の依存関係があり、「ファイルAをファイルBのあとに読み込まないとエラーになる」ということがある。
少し進化したやり方だと、機能のまとまりごとに連結するという方法もある。こうすることで読み込みリソースが減り、モジュールの依存関係も解決される。
さらに、CommonJSスタイルによって依存解決する方法もある。もともとJavaScriptはブラウザで動くことを前提に作られているので、ファイル読み込み機能などは用意されていなかった。それが最近ではサーバ対応など、ブラウザ以外でも動くようになってきている。そこで、どのようなプラットフォームでも動くように、標準仕様を定めようとして考えられたのがCommonJSだ。その中でModule APIを受け、require()を用いてファイルの読み込みができるようになる。しかし、この関数はブラウザ上では動作しない。最近では、それを可能にするツールwebpackやBrowserifyが出ているので、事前にコンパイルしてから読ませるようにする。
2015年6月、JavaScriptの最新仕様ECMAScript 2015(ES6)が正式公開された。これにより、それまでプロトタイプなどを使って擬似的にクラスを表現していたところを、標準的にクラスを作れるようになったり、コールバック地獄で苦しんでいたところをプロミスで解決できたりするなど、色々と便利な機能が増えた。
ただ現状では、動く環境が限られているため、ヤフーではBabelといったツールを使ってES6からES5にコンパイルしてからブラウザに読ませる流れが主流になっている。「本当にコンパイル祭りという感じ」と柴田氏。
続くテーマは、フレームワークだ。JavaScriptのフレームワーク戦争などと言われているが、柴田氏は「若干落ち着いてきたものの、その中でも未だ勢いがあるのがAngularとReact」という。このように、フロントエンド技術のトレンドはめまぐるしく変わり、技術の進化スピードは半端ではない。
大規模開発における技術選択のポイントは「息の長い技術であるか」
昨今のフロントエンド周りの新技術に対し、ヤフーの対応状況はどうか。柴田氏は「少々残念だが、シングルページアプリケーションは△、CommonJSとES6は×、フレームワークは△」と評価している。
シングルページアプリケーションの対応状況が△というのも、ヤフーではサーバサイドでHTMLを構築しているアプリケーションが多く、長く続いている大規模なサービスが多いため、なかなかシステムをリニューアルする工数が取れない。また、HTMLメインで進めてきたので、JavaScriptを書けるエンジニア・デザイナーが少なく、全体の2~3割程度だ、という背景がある。
2つ目のCommonJSスタイル、ES6に関しては、まだごく少数のケースにしか対応できていないという印象だ。ただ最近、新規サービスでは導入しているケースもある。しかし既存サービスをリニューアルするのは厳しい。
フレームワークに関しては、シングルページアプリケーションの割合と比例している。その中でAngularとBackbone、React、Vueなどを用いたアプリケーションが増えている。中でもReactが増えつつある。
大規模プロダクトをリニューアルするには、専用の工数を確保する必要がある。既存の機能改修とバグ改修を同時に進めていかなければならないので、単純計算で人数が2倍必要になる。かつ既存の回収とリニューアルのスピードが遅いと、追いつかない。サグラダ・ファミリア状態になってしまう、という。
以上の課題を解決するため、ヤフーでは2014年頃、フレームワークを統一しようという流れが現れた。当時、ヤフーのプロモーション広告は、スポンサードサーチ/YDN(Yahoo!ディスプレイアドネットワーク)についてはjQuery、Twitter広告はBackboneで作っていた。これらをAngularに統一しようと考えたのである。
1年ほど経った時点で、アプリケーションが大規模すぎたため全体の3割程度しか進んでいない状態だった。またReactが伸びてきて、当時最強だったAngularの影がだんだん薄れてきた。そうこうしているうちにAngular2のベータ版が出てきて、これから新規のプロダクトをAngular1で作るのは、モチベーションが上がらない状態になってしまった。
フレームワーク統一のメリット、デメリットについてまとめたのが下記のスライドだ。
以上の点を考慮して、柴田氏のチーム周辺では統一を止めようという結論になった。では、現状を打破するためにどうしていったのだろうか。
技術が進歩するのは素晴らしい。ただその分、既存の技術が古くなっていくのも事実だ。そのため、サービスはいつかリニューアルせざるを得ない。そこで重要となってくるのは、どれだけ息の長い技術を選択できるかになる。柴田氏が「進歩の種類」として挙げるポイントは以下の3点だ。
- 言語仕様:変わるのは必然。polyfillを使って未来を先取りすることで、プロダクトの寿命を延ばせる。
- 概念:ここではAjax、JSX、Fluxなどのことで、イノベーションにより今までのバランスが崩壊することがあるので注意。
- フレームワーク:発展がとても早いが、機能的には近しいものが多い。今後の言語仕様に沿っているかどうかが長生きの鍵になる。
技術選定のポイントとして柴田氏が挙げるのは次の3つ。基本として新しい言語仕様は取り入れていくこと。未来の言語仕様にうまく載ることができそうな技術を選ぶこと。最後に、話題に上がってくる新しい概念は、とりあえず触っておくこと。
では新しい技術をいつ取り入れればいいのか。何事もすぐに取り入れるのは危険だ。新規リリース直後の場合、バージョンアップが多い。特に大規模なアプリケーションにおいて、ライブラリのメジャーアップデートはリスクとなってしまう。話題に上がってから半年〜1年が経ち、それでも筋が良さそうだったら取り入れるという戦略を取っているとのことだ。
ここで柴田氏は、ヤフーならではの大規模開発、特にプロダクトの数が莫大に多いプロジェクトにおいて適した方法について語った。ポイントは「仕組みの共通化」「モジュールの共通化」「属人化の回避」の3点だ。
まず仕組みの共通化では、ソースコードを共通化するのではなく、仕組み自体を共通化する。命令規制・コーディング規制をESLintに揃える。テストの構成をKarma、mocha、chaiに。タスクランナーの処理はgulp、Yeomanに。プルリクエストのフォーマットをCONTRIBUTING.mdに揃えるなどになる。
2番目のモジュールの共通化については、使っているフレームワークが異なると難しい。ディレクトリ構成をできる限り揃えるだけでも十分効果はある。ユーティリティ関数だけを切り出して、使い回す等は可能だ。
最後の属人化の回避は、プロダクト数が多くなると、担当プロダクトの専任になりがちだ。そこで、定期的に担当者をシャッフルする、別プロダクトをレビューする、別プロダクトのテストを担当するなどの策が有効だ。
まとめとして、言語仕様の未来を見据えて技術を選ぶこと、大規模開発においてはソースコードよりも仕組みや構成を共通化することが大事であること、属人化を回避できるような運用を考えること、の3点を挙げ、柴田氏のパートは終了した。