この記事は、「de:code2016」のセッションレポート、日本マイクロソフトエバンジェリスト物江修氏による「モダンWeb:たった今と、ほんの少し未来のはなし」です。講演内容を再現していますが、ニュアンス等伝えきれない場合があるかもしれません。ご了承ください。
モダンWebとは
昨今、様々なところで「モダンWeb」という言葉を聞くが、その定義は曖昧で意味するところの範囲が広範囲に及んでいるためではないかと考える。多くの場合、「モダンWeb」という文脈で語られている内容は次の4つの事柄で語られている。
- モダンなWebシステム
- モダンな開発手法
- モダンな標準機能
- モダンなアプリケーション
単にモダンWebアプリケーションと言った場合にはこれらいろいろな意味に捉えることが多いが、このように四つに分けることができる。このセッションでは、アプリケーションを開発するのに必要な「モダンなWeb標準の機能」、「モダンなWebアプリケーション」に関して触れる。
なぜ「モダンWeb」が話題になっているのか
第一に挙げられることは「時代の要求」。具体的には以下の3つが挙げられる。
- Web技術の進化
- コンテンツのリッチ化
- クライアントの多様化
Web技術で作るリッチなUIは昔から存在していたが、以前はFlashなどのプラグインを利用したいわゆるRIA(Rich Internet Applications)のほうが優勢だった。その後、Ajaxでデータを取得し、そのデータを使って部分的なUIの更新が可能になり、jQuery UIなどのUIライブラリによる開発生産性の向上、そしてHTML5の登場によって、プラグインで行っていたことがWebの標準技術だけで作ることが可能になった。これがWeb技術の進化である。
そしてスマートフォンから始まったFlashの衰退が進み、今までFlashで行っていたような要求をWebコンテンツ側にやってくるようになり、コンテンツのリッチ化が始まった。
スマートフォンを始め、PCブラウザー以外の様々なものがインターネットに繋がり、クライアントが多様化した。
この「クライアントの多様化」はサーバーサイドの形態にも影響を与え、その影響が、Webブラウザー上で動くアプリケーションにも影響を与えたという状況になっている。具体的にどういうことなのか。
黎明期のWebアプリケーションは、リクエストされたページを単純にレスポンスするというもの。ちなみに一番最初のWebサーバーはティム・バーナーズ・リーが作った「CERN Httpd」で、1991年にニュースグループで公開されたが、翌年に作られた「NCSA Httpd」ではCGIがサポートされ、動的ページが作れるようになった。ご存知の通り、このサーバーサイドで処理をして、処理結果をページで返すWebアプリケーションは広く使われている。
さらに、新しいクライアントとして携帯電話が現れる。NTT Docomoから始まった携帯電話は、それまでWebのクライアントというと、PCブラウザかゲーム機くらいで、いずれも机に座って使うようなものだった。
しかし、携帯電話は持ち歩き、行動に必要な情報を得るためのツールとして機能するモビリティという考え方が生まれた。
今までとは利用用途が異なる、サーバーではデバイスに応じた専用のコンテンツを作る必要があるなどコンテンツを作っていくには困難な状況だった。
やがて、スマートフォンに代表されるスマートデバイスが現れます。これらは、PCブラウザー用のコンテンツを同じ様に処理することができたので、わざわざ専用のコンテンツを用意しなくても済む。問題は、画面サイズに応じて表示を切り替える必要があり、同時期に出てきたHTML5関連技術であるCSS3を使ったレスポンシブWebデザインで、こうした技術を吸収することができた。
さらにスマートフォンは、サーバーサイドの処理にさらに大きな変化をもたらした。
Webアプリケーションの登場です。サーバにリクエストを投げるが、必要とするのはページではなくデータでした。この影響を受け、Webサーバーに必要な技術は、データを返す「API」が重要になった。
現在では、クライアントデバイスの性能とWebブラウザーの機能も数段上がり、処理性能ではネイティブで作られたアプリケーションと同等なことができるようになった。
SPA(Single-page Application)
単一ページによるWebアプリケーションであるSPAの特徴は、以下が挙げられる。
- 画面遷移はDOM操作
- ページのリフレッシュは不要
- リッチなエクスペリエンス
SPAにするメリットもいくつかある。例えば、サーバーサイドを「サービス化」することによって、多様化していくクライアントにも対応できるようになる。つまり、サービスをどこにでも提供できポータビリティを上げることができる。
現在のようにクライアント技術の進化が劇的に早い(言い換えると、陳腐化する速度も早い)状況下でもSPAは有効だ。クライアントとサーバーのロジックを物理的に別けることで保守性を上げることができるから。さらに分業においては、サーバーサイドを開発する人間、クライアントサイドを開発する人間で、やるべきことに集中できるということが挙げられる。
プログラミングスタイルの変化
SPAの登場によつてプログラミングのスタイルも少なからず変化している。Ajaxなどの非同期処理を行う場合、処理の単位はサーバーサイドの動作と必ずしも一致せず、処理の順番やタイミングもまちまちになる。それらを適切にハンドリングして画面に描画する必要がある。
さらに、ユーザーアクションの開始が、いわゆるPull型(サーバにリクエストするという意味で)だったが、WebRTCやWebSocketsの登場にによって、突発的に開始されるPush型(サーバからクライアントに通知する)可能性もある。
非同期処理の完了であるが JavaScriptではイベント通知で行われる。また、今まではサーバーロジックで行われていた処理をクライアントで行うケースも出てくるので、1つの完結する処理を行う場合、複数回サーバーとやり取りする必要がある。よく「コールバック地獄」ということに陥る。
不規則に発生するイベントを適切にルーティングしつつ、状態を把握し、かつ処理全体を制御する仕組みが必要で、こういった制御を行うために、JavaScriptのライブラリやフレームワークが様々な機能を実装し提供している。
そして、最新のモダンブラウザーがサポートしつつあるECMA Script2015や2016にも、こうした機能が標準で用意されようとしている。つまりイベントのフロー制御方法は
- Promise(ES2015)
- async/await(ES2016)
- Generator/yield(ES2015)
Promiseは非同期処理を抽象化したオブジェクトでPromiseパターンで非同期処理を行う。async/awaitは、Promise とGeneratorの糖衣構文で、そのGenerator/yieldは、反復子 (イテレータ )の生成元で、実行環境を維持したま中断・再開が可能となる。
SPAでは画面のレンダリングも従来のサーバーサイドの処理をメインしたものとは異なる。
SPA以前のサーバーサイドでページが生成されるタイプのWebアプリケーションでは、画面データの成形もサーバーサイドで行われていましたが、SPAではその部分をクライアントサイドで行うことになる。
素直に書くなら、エレメント一つひとつのインスタンスを取得して、各々データをセットする所謂「Glue code」を書く(”グルー”とは糊のこと)ことになる。だが、これだとエレメント変更に関わるUI仕様があるたびにコードまで修正する必要がありメンテナンスが大変だし、いちいちデータを入れるためだけのコードを書くということ自体が非効率。
データバインディング
そこで出てきたのがUIへのデータバインドです。 マークアップにUIとデータの関係を記述しておくと、JavaScriptフレームワークがよしなにデータをセットしてくれるという仕組みです。 こうすることで、データと画面、いわゆる ModelとViewの関係を1:1に紐づけ、構造的には明確に分け部品化することが可能になった。
“バインド”とあるように、ModelとViewの関係を保持します。つまり、モデルもしくはビューに変更が発生した場合、その変更が一方向、あるいは双方向に反映されます。Modelの変更のみかViewに反映されるのが1Wayバインドで、双方向に変更が伝わるのが2Wayバインドです。
まとめるとモダンなWebアプリケーションとは
- SPA
- リアクティブな動作
- M-V-Whatever
少し先のWebアプリケーションの技術的コンセプト
ここからは、ここ数年提唱されているWebアプリケーションの技術的コンセプトについて紹介します。
- Web Components
- Progressive Web Apps
- WebAssembly
Web Components
まずは「Web Components」です。これはWebをコンポーネント化する仕組みで、2013年のGoogle I/Oで紹介された。実は、Webをコンポーネント化するという仕組みは、これが最初ではなく、マイクロソフトも1998年にHTMLコンポーネントというものを提案したし、Mozillaも2001年にXBLと2007年にXBL2というのを提案した。
このコンポーネント化のメリット、目的について
Webのアプリケーションは、他のソフトウェア・アプリケーションと同様に複雑になり、今ではリリース製品の開発に大勢が協力して取り組むことは珍しくなくなった。少しでも効率化を図るには、関係者やシステム間の重複が最小限になるように開発作業を分割する正しい方法を見つけることが重要になる。そのための方法としてコンポーネント化がある。複雑なシステムでも、機能を分割していけば、単純化することができる。全体をある程度の機能単位に分割する、つまりはコンポーネント化だ。
Web Componentsの目標は、HTML、CSS、JavaScriptの関連グループを分離し、単一ページのコンテキスト “内” で共通関数を実行することで、複雑さを軽減することだ。
この Web Components は、複数の API を組み合わせるか、それ単独を使用して実現する。 しかし、すべての Web ブラウザーがその API をサポートしているわけではないので、Polyfill 用のライブラリーが用意されています。
そしてこちらがWeb Componentsを構成する要素です。
- HTML Templates
- Shadow DOM
- Custom Elements
- HTML Imports
現在のサポートの状況はこのようになっています。
Web Components | Edge 13 | Chrome 50 | Firefox 45 | Safari 9.1 |
---|---|---|---|---|
HTML Templates | ○ | ○ | ○ | × |
Shadow DOM | × Medium | ○ | △※ | × |
Custom Elements | × High | ○ | △※ | × |
HTML Imports | × Low | ○ | △※ | × |
※ 既定では動作しない
Progressive Web Apps
これはモバイル Web アプリ向けのコンセプトで、具体的には、高性能のモバイルWebブラウザー向けにネイティブアプリケーションのようなUXを提供しようというも。去年の「Chrome Dev Summit」のキーノートで発表され話題になったものだ。今年の4月に行われた「Google Developers Summit Tokyo 2016」でも2日のテーマになっていたくらい力を入れている。
Progressive Web Appsに求められる体験をまとめると次の様なもの
- ネイティブアプリケーションのようなUX
- オフラインサポート: Service Worker
- プッシュ通知: Web Notifications/Push API
- ホームスクリーンにアイコンの追加: Web App Manifest
- バックグラウンド: Service Worker
- 高速でなめらかなインターフェース: CSS3 Animation
Service Workerは、JavaScriptで実装されているローカルのプロキシ、あるいはApplication Cacheの改良版として利用できる。 いままで Web ブラウザーからサーバーにコンテンツをリクエストする場合、サーバーになげてそれを返していたのが、その間にカスタマイズ可能な Service Worker というのが入って バックグラウンドで動いているので、タブを閉じてもブラウザを終了しても動作しているので、プッシュ通知もうけとれるとこと。httpsでしか動作しない。
Progressive Web Appsを実現する技術のサポート状況は
Edge | Chrome | Firefox | Safari |
---|---|---|---|
Internal build | Canary 51.0.2677.0 | Nightly | – |
WebAssenbly
WebAssenblyは、コンパイル済みのバイナリをWebブラウザ上で直接動作させる仕組で、Microsoft、Google、Mozilla、Webkitプロジェクトのメンバーで共同開発されていて足並みが揃っている。
JavaScriptよりもポータブルでロード時間や実行に対するパフォーマンスに優れたアプリケーションを作ることが可能だ。asm.jsの次のステップとしている。
2016/3/14〜16の間にMicrosoft、Google、Mozillaの3社が3DゲームAngry botでの検証結果を各ブログで公開している。
WebAssemblyの実装状況は
WebAssembly | Edge 13 | Chrome 50 | Firefox 45 | Safari 9.1 |
---|---|---|---|---|
Service Workers | × High | ○ | ○ | × |
Fatch API | △ Preview | ○ | ○ | × |
Web Notifications | △ Preview | ○ | ○ | × |
Push API | × High | ○ | ○ | × |
Web Application Manifest | 検討中 | ○ | ○ | × |
ハイブリッドアプリケーションとしての利用
Webアプリケーションが苦手とするところは
- ストアのエコシステムを利用しない
- Webブラウザからはどうしてもアクセスできないハードウェアリソース
そしてこれらの Web アプリケーションのは、ハイブリットアプリとしてパッケージすることにより、ターゲットとなるプラットフォームのリソースや、ブラウザーからはアクセスできないハードウェアの機能を使用できるようになる。 また、アプリストアのエコシステムを利用することができる。
Webフロントエンドの開発リソース
インタラクティブなコンテンツを作ることができるようになったので、開発は非常に大変なものになった。
- JavaScript
- ライブラリ
- フレームワーク
- エンジンテンプレート
- altJS
- CSS
- フレームワーク
- プリプロセッサー
- HTML
- 軽量マークアップ
- パッケージマネージャ
- タスクランナー
- モジュール管理
Richになったことで多くのライブラリが提供された結果「Chaos」になったのか?と思いがち。そして、ライブラリ/フレームワークの選定として考える必要がある。
- ブラウザサポート
- ベンダーサポート
- 情報
- ドキュメント
- 書籍類
- 学習コスト
- 開発生産性
- 機能範囲
- ロックイン
- 運用コスト
特にこの中のロックインですが、ロックインは決して悪いものではなく、優秀なベンダーと一緒になってやっていくこと、コミュニティの力を借りることでむしろ良い状況も作れる。運用コストに関しては、便利なんだけどお金がかかるというものについては考えもの。
標準技術は不変
結局、Webブラウザで動作するのは、HTML、CSS、JavaScriptであり、ブラウザがサポートしていない機能は動かない。技術はあくまでも「手段」でり、そうした技術に対する勉強は大事だが、手段であって目的ではない。目的は、ユーザに対して良いプロダクトを提供すること。たとえば、YouTubeはFlashで作られていたが、HTML5に変わったことに気づいた人はいない、そういうものが良い。
そして、WebはApplicationのプラットフォームになる。どんどん低レベルなAPIを実装することになる。結果、デスクトップと同じ様なアプリケーションを作っていける。こうした変貌は「変化」ではなく「拡張」である。