de:code2016セッション「モダン Web: たった今と、ほんの少し未来の話」フォローアップ


de:code 2016、2 日めのセッション ARC-003「モダン Web: たった今と、ほんの少し未来の話」 にお越しくださいました皆さま、ありがとうございました。

そうとう気合いを入れて資料を作ったものの、セッションのビデオを見たら私の喋りがイマイチ(ほんとはイマサンくらい) だったので、猛省して内容を記事にまとめました。

なお、このセッションについては、HTML5 Experts.jp に、以下の驚くほど詳細な記事が載っており、概要であれば同記事で充分と思いますが、

モダンWeb:たった今と、ほんの少し未来のはなし~「de:code 2016」セッションレポート~

このブログの記事では、セッションでは語れなかった内容もふくめて書いていきたいと思います。

なお、デモでお見せした promise, async/await, generator/yield を使用した非同期制御については、後日別記事で紹介させていただきます。

 

モダン Web: たった今と、ほんの少し未来の話

この記事は、今現在、巷で言われている「モダン Web」、なかでも「モダンな Web アプリケーション」というものがどういうものであるか、また、今後一般的になるであろう「Web アプリケーションの技術的コンセプト」のいくつかを紹介するものです。

「モダン Web」 とは?

「モダン Web」 とはなんでしょう?

数年ほど前からいろいろなところで、この「モダン Web」というキーワードを耳にするようになりましたが、話されている内容というのは人によりまちまちであることが多いようです。

これはなにも話している人がそれぞれに勝手なことを言っているわけではなく、「モダン Web」で括れる範囲がそれだけ広いからに他なりません。

たとえば、一口に「モダン Web」と言っても、Web のフロントエンドからサーバーサイドのバックエンドまでを含めた「モダンな Web システム」のことの場合もあれば、最新の JavaScript のフレームワークや altJS、 プリプロセッサやタスクランナーといった様々なツールを組み合わせて作業を行う「モダンな Web フロントエンドの開発手法」の場合もあり、かと思えば、次々とやむことなく追加されていく「モダンWeb ブラウザーの新機能」を使用していることをさす場合もあります。

この記事では、「モダンな Web アプリケーション」というものがどういうものであるか、また、そういったアプリケーションを開発するのに必要な「モダンな Web 標準の機能」、 今後一般的になるであろう 「Web アプリケーションの技術的コンセプト」のいくつかを紹介していきます。

なぜ「モダン Web」なのか

昨今なぜこんなにも「モダン Web」、あるいは機能的な「Web のリッチ化」が注目されるようになったか、これはひとえに「時代の要求」と言わざるをえないでしょう。

具体的には以下の 3 つが大きいと思います。

  • Web 技術の進化
    Web のコンテンツおよび UI のインタラクティブ性を伴うリッチ化は、DOM の登場くらいからはじまりましたが、その時代は機能的にも開発のしやすさからも Flash などのプラグインを利用した RIA のほうが優勢だったので現在ほど盛り上がりませんでした。
    その後、Ajax による部分更新、jQuery UI のような UI ライブラリの登場による開発生産性の向上と HTML5 の登場によって、それまでプラグインで行っていたようなことが Web の標準技術だけで可能になりました。
  • Web コンテンツへのリッチ化の要求
    スマートフォンから始まった Flash に代表されるプラグインの衰退が進み、それまでプラグインで行っていた要求が、Web コンテンツ側にやってくるようになりました。
    そしてそのころには、プラグインを使用しなくても HTML5 に代表される Web の標準技術だけでそれなりのことができるようになっており、さらに、不足している機能を埋めるかのようにさまざまな機能が提案され追加されるようになってきました。
  • クライアントの多様化
    PC ブラウザー以外の様々なものがインターネットにつながりクライアントが多様化し、Web コンテンツはそれらのさまざまなクライアント上で最適に動作するよう、また Web サーバーはクライアントが必要とする様々なデータをレスポンスする必要が出てきました。

この「クライアントの多様化」はサーバーサイドの形態にも影響をあたえ、また、このサーバーサイドの変化が Web ブラウザー上で動くアプリケーションにも少なからず影響を与えるという状況になっています。

具体的にどういうことなのか、サーバーサイドの形態の変化を時系列順に見ながら紹介していきましょう。

 

クライアントの多様化とサービスの変化

Web システムのもっとも基本的な構成は、クライアントからリクエストされたページを Web サーバーがレスポンスするものです。

これはティム・バーナーズ・リーが作った世界初の Web サーバー CERN Httpd の時代から変わっていません。

image

それからほどなく、URLの中にパラメーターを混ぜて送り、Web サーバーはそれについての処理結果を返すようになりました。Web アプリケーションの登場です。

この、サーバーサイドで処理をして処理結果をページで返す、というスタイルの Web アプリケーションというのは現在でも広く使われています。

余談ですが、前出の世界初の Web サーバー CERN Httpd がニュースグループで公開されたその翌年に作られた世界 2 番目の Web サーバー NCSA Httpd では CGI がサポートされ、動的ページが作れるようになっていました。

image

やがて新しいクライアントが現れます。携帯電話です。

この新しいクライアントに搭載されている Web ブラウザーが解釈できるマークアップは cHTML、HDML、WML といった PC ブラウザーとは異なるモバイル専用のものでした。

これらのデバイスはハード的にもソフト的にも貧弱だったので、ブラウザー内で動作する Web アプリではそれほど高度な機能は実装できませんでした。

そういった状況もあり、アプリケーションの処理はサーバーサイドで行い、処理結果をブラウザーで受けるという状況は変わりませんでした。

 

Web クライアントとしての携帯電話の登場は、ハードこそ貧弱でしたが、Web に文化的にも商業的にも大きなインパクトを与えます。

それまでの Web のクライアントは PC ブラウザかゲーム機くらいだったので、Web コンテンツは机に座って使うようなものでしたが、携帯電話は持ち歩き、外出先で行動に必要な情報を得るためのツールとして機能しました。Web にもモビリティの考え方が入ってきました。

また、PC を扱えない新しい属性のユーザーも Web 上のサービスを利用するようになり、ユーザーの多様化に合わせ着メロやソーシャルゲームなど、それまでにない新しいサービスを提供する会社が生まれ収益を伸ばしていきました。

 

image

 

やがてスマートフォンに代表されるスマートデバイスが現れます。

これらは、PC ブラウザー用のコンテンツをほぼ同等に処理することができので、わざわざ専用のマークアップで別のコンテンツを用意する必要はなくなりました。

しかしながら画面サイズは大きく違ったので、同時期に出てきた HTML5 関連技術である CSS3 のレスポンシブ Web デザイン向けの機能で画面サイズを吸収するようになりました。

スマートフォンの出荷台数は伸び続け、スクリーン数では完全に PC ブラウザーを凌駕し、今や一般コンシューマー向けにコンテンツを作るのであれば無視できない状況になっています。

さらにスマートフォンは、サーバーサイドの処理にさらに大きな変化をもたらします。

image

 

スマートフォン アプリの登場です。(※1)

アプリは、インターネットにリクエストを出しますが、アプリが必要とするのはページではなくデータでした。こうして Web サーバーは、ページでだけでなくデータを返す API もホストするようになりました。(※2)

 

(※1)スマートフォン登場以前にも、携帯電話時代に i アプリなどがあり、ゲームなどでそれなりに利用されていました。しかしながら、ハードのスペックによる制限(画面サイズやプログラム自体の容量、通信が自由にできない等)が大きく、複雑なアプリの実装はなかなか難しいものがありました。また、アプリからインターネットに接続する際にはユーザーの承認を得る必要があったため、Web API をコールするというよりはデータをダウンロードするというイメージでした

(※2 )Web アプリケーションの API 化(サービス化) は、2000年代前半に SOAP を使用した XML Web サービスが登場して注目を浴びましたが、クライアントが普及しなかったせいか、それほど流行りませんでした。その後、Ajax が登場し、Yahoo さんや Google さんが JSON でサービスの API を公開することで Web API が認知されましたが、それを使用してアプリケーションを構築するというよりかは、マッシュアップのソースとして Web ページの部分更新に利用されるほうが多かったようです。

image

そして、さらに高性能になったクライアントデバイスと高機能になったブラウザーを使用して、ネイティブアプリのように画面の生成と、データの成形を処理をブラウザー上の Web アプリで実装しようというものが出てきました。

Single-page Application(SPA) です。

image

SPA

SPA (Single-page Application) は、名前のとおり単一ページによる Web アプリケーションであり、サーバーから受け取ったデータを使用して、Web ブラウザー上のアプリケーションが画面を生成します。

画面の遷移は DOM 操作で行われ、基本的には(※)ページ遷移は行いません。(※ページ遷移するものもあります)

ユーザーのアクションに対する逐次的でかつ、細かい粒度でのページの部分更新が可能なので、リッチなエクスペリエンスを実装することが可能です。

image


 

SPA を開発運用するためには、Web アプリケーションのロジックを Web API として公開する必要があります。Web システムのサーバーサイドを「サービス化」することによって、多様化していくクライアントにも対応でき、サービスのポータビリティを上げることができます。

image

 

また、サービスの対象が PC ブラウザーだけという場合でもメリットがあります。

従来型の Web アプリケーションに使用される PHP や ASP(Active Server Pages) のように、サーバーサイドとクライアントのロジックが一つの物理的なファイルにまとまっている場合、片方の修正が両方に影響を及ばしてしまう可能性があります。

とくに昨今、クライアント側の技術の進化は早く、また同様に陳腐化も速いことから UI やコンテンツの書き換えなどが頻繁に発生する可能性があります。そういった場合でもクライアント側とサーバー側のロジックを物理的に別けることで保守性を上げることができます。

さらには、分業においてサーバーサイドを保守開発する人間、クライアントサイドを保守開発する人間で、各々やるべきことに集中できるというのもあるでしょう。

image

 

上記のように、サーバーサイドをサービス化する/しないにかかわらず、クライアントの多様化により Web サイトがクライアントに返す内容はまちまちとなり、ページのような外形的なものは Web サイトの提供する本質的な価値の中心からは外れつつあります。

よってこれから Web サイトを構築する際には、自分たちが作っているものが単に「ページを吐き出す仕組み」はなく、「デジタルサービス」であることを意識強くする必要が出てくるでしょう。(そうしないと UI から離れたエクスペリエンスを考えることは難しいでしょう。

Web サイトの本質が「サービス」であると意識すれば、サーバーサイドの機能分割もドラスティックに行えます。例えば、サーバーサイドの役割は [API]、[認証]、[ストレージ]、[キャッシュ] のみとし、その中でクラウドが提供するサービスで賄える分部はそちらを使用して開発工数と運用コストを下げつつ、信頼性を上げるといったことも考えられます。こういった、現在の最新の技術の利点どうしを合理的に組み合わせて作られる Web システムが「モダンな Web システム」と呼ばれいます。

image

 

プログラミングスタイルの変化

SPA の登場によってプログラミングのスタイルも少なからず変化しています。
SPA 以前、クライアントからのリクエストに対し処理結果をページで返す、従来の Web アプリケーションでは、リクエストとレスポンス、いわゆるページの遷移と処理の単位がだいたい同じでした。
しかし、SPA は基本的にページ遷移をしないので、処理の単位はサーバーサイドの動作と必ずしも一致せず、処理の順番やタイミングもまちまちです。
それらを適切にハンドリングして画面を描画していく必要があります。

image


 

SPA の大きな利点としてあるのが、情報更新の粒度が小さいというのがあります。たとえば、Facebook の「いいね!」ボタンや、Excel オンラインのセルに対する操作のように、局所的なユーザーの操作でも瞬時にサーバー側に反映されるといったリアクティブな動作を実装することが可能です。そして当然のことながらそう言った動作のサポートは、アプリケーションを作成する上での要件として挙がってきます。

さらに、いままで処理の開始はユーザーのアクションによって引き起こされる、いわゆる Pull 型だったものが、WebRTC や Web Sockets などによって、突発的に開始される可能性もあります。


 

image


 

そもそも SPA では、クライアントサイドの処理は、サーバーサイドの処理とは疎結合となるので、やり取りは非同期を前提で考える必要があります。

そして、その非同期処理の完了は JavaScript ではイベントによって通知されます。

また、従来、ページ遷移中にサーバーサイドのロジックで行われていた処理をクライアントサイドで行うケースも出てくるので、1 つの処理の完了までに複数回のサーバーとのやり取りや、マルチメディアのロードや、ユーザーのアクションと非同期処理がイベントが発生する可能性があり、それらを適切にハンドリングする必要が出てきます。

image


 

たとえば XMLHttp で、処理に必要な順番で、サーバーから情報を受け取るコードを書いた場合、イベントハンドラをひたすらネストすることになり、その間に画像のロードやユーザーのアクションについてのイベントのハンドラが入ると、コードはひたすら右側に伸びていくことになります。これでは記述も煩雑になるだけでなく、デバッグも大変です。

これがいわゆる「コールバック地獄」とよばれるものです。

image

不規則に発生するイベントを適切にルーティングしつつ、状態を把握し、かつ処理全体を制御する仕組みが必要です。

image

こういった制御を行うために、JavaScript のライブラリやフレームワークが様々な機能を提供してきました。
しかし、今最新のモダンブラウザーがサポートしつつある ECMA Script の 2015 や、2016 にはそういった機能が標準で用意されています。

JavaScript によるイベントフロー制御

非同期を制御するための機能として、Ecma Script 2015 (旧 ES6) では以下の機能が標準で提供されています。

  • Promise

    非同期処理を抽象化したオブジェクト
    Promise パターンで非同期処理を行う

  • async/await
    Promise と Generator の糖衣構文 (Syntax sugar)
  • generator/yield

    反復子(イテレータ)の生成元
    実行環境を維持したまま中断・再開が可能

(※このトピックについては、次回の記事でサンプルコードつきで紹介します。)

 

クライアントサイドでの画面の生成

変化の波を受けているのは非同期による処理だけではありません。

SPA では画面のレンダリングも従来のサーバーサイドの処理をメインしたものとは異なります。

SPA 以前のサーバーサイドでページが生成されるタイプの Web アプリでは、画面データの成形もサーバーサイドで行われていましたが、SPA ではその部分をクライアントサイドで行うことになります。

すなおに書くなら、エレメントひとつひとつのインスタンスを取得して、各々データをセットする所謂 Glue code (グルー コード) を書くことでしょう。ちなみに”グルー”とは糊のことです。

しかし、これだと UI が変更された際にコードまで修正する必要がありメンテナンスが大変です。それに以前に、いちいちデータを入れるためだけのコード自体が非効率です。

image


 

そこで出てきたのが  UI へのデータバインドです。
マークアップに UI とデータの関係を記述しておくと、JavaScript フレームワークがよしなにデータをセットしてくれるというしくみです。
こうすることで、データと画面、いわゆる Model と View の関係を 1 :  1 にきちんと紐づけ、構造的には明確に分けることで部品化することが可能になります。グローバル空間にむき出しの状態である DOM を直接操作せず、フレームワークに任せることは意図しない変更を避けることにもつながります。
しかも、このデータバインドは、グルーコードのように単にデータを UI にセットするだけではありません。

image


 

“バインド”とあるように Model と View の関係を保持します。つまり、モデルもしくはビューに変更が発生した場合、その変更が一方向、あるいは双方向に反映されます。
Model の変更のみか View に反映されるのが 1 Way バインド、双方向に変更が伝わるのが 2 Way のデータバインドです。
そしてこの仕組みを実現すめためには変更を検知する仕組みが必要です。その変更を検知する考え方として、Publisher/Subscriber パターンObserver パターンがあります。


 

image


 

そして、SPA の内部は Model と View という関係で動作します。

image

(※どこかで仮想 DOM を紹介したかったのですが、煩雑になってしまうので、まだ別の機会ということで)

モダンな Web アプリケーションとは

ここまで紹介してきたように、今現在、ちまたで言われてる「モダンな Web アプリケーション」の特徴としては、以下の 3 つの要素が含まれています。

そして 1 の構造をしたアプリケーションに 2 の機能をいかに効率良く実装するかで、MV や MVVM といったアプローチで、3 の関係を(※)扱うさまざまなフレームワークが出現してきている状況があります。

  1. SPA
  2. リアクティブな動作
  3. M-V-whatever
    (※もしくは Flux とか)

これからアプリを開発する際には、これらを意識した構造にすることで、ある程度の期間の技術的新陳代謝に耐えられるものを作成することができます。

アプリケーションとコンテンツの違い

ここまで「モダンな Web アプリケーション」とはどういったものであるかについて紹介してきましたが、ここまでの内容は(そしてこれ以降の内容も)あくまで「Web アプリケーション」についての内容であり、「Web コンテンツ」についてではありません。

「アプリケーション」と「コンテンツ」がどう違うのか、分かりやすく例えるならば、これは「カメラ」と「写真」の違いといえるでしょう。

アプリケーションとはプログラムであり、プログラムとは関数です。つまりは与えられた引数(課題)について処理結果を返す(解決)するものです。「Web アプリケーション」はユーザーからの入力やアクションよって与えられた情報に対し処理を行い結果を「Web コンテンツ」として返します。

これは「カメラ」がユーザーのアクションにより被写体を撮影し「写真」を生成するのと同じです。

それでは、ビジネスロジックを持たない「Web コンテンツ」についてはこれまで紹介してきたような複雑な仕組みが必要でしょうか?

ビジネスロジックを持たない「Web コンテンツ」を作るにおいては、さまざまなクライアントデバイスを意識したレスポンシブ対応を行い、未知の Web ブラウザーの含めた相互運用性を意識した作りとすることで充分なのかもしれません。

<参考>

 

少し先の Web アプリケーションの技術的コンセプト

Web ブラウザーの進化と、それに比例してリッチ化/複雑化していく Web アプリケーション向けに、それまでアプリケーションを開発するうえで不足していた機能を追加し、より開発効率が向上するような、アプリケーションの新しい技術的コンセプトが提案されています。

ここからは、以下のものについて概要とメリット紹介していきます。

  • Web Components
  • Progressive Web Apps
  • Web Assembly

Web Components

Web Components は Web をコンポーネント化する仕組みで 2012 年の Google I/O で紹介されました。

この Web をコンポーネント化するという仕組みは、これが最初ではなく、マイクロソフトも 1998 年に HTML コンポーネントというのを提案しており、実際 Internet Explorer 5.5 ~ 10 までサポートされていましたし、Mozilla さんも 2001 年に XBL と 2007年に XBL2 というのを提案していました。

Web をコンポーネント化することの目的とメリット

Web のアプリケーションは、他のソフトウェア アプリケーションと同様に複雑になり、今ではリリース製品の開発に大勢が協力して取り組むことは珍しくなくなりました。

たとえば、Facebook を思い浮かべてみてください。Facebook はページとしては 1 枚ですが、その中にはたくさんの機能が実装されています。当然のことながら Web のフロントエンドの部分だけを考えても大勢の人間が共同で開発していることは想像に難くありません。

そういった、ひとつアプリケーションを複数の人間で開発する場合、機能ごとに担当を別け、それぞれの作業が他の部分に不必要な影響が出ないようにする必要があります。そのための方法としてコンポーネント化があります。複雑なシステムでも、機能を分割していけば、単純化することができます。全体をある程度の機能単位に分割する、つまりはコンポーネント化です。

Web Components の目標は、HTML、CSS、JavaScript の関連グループを分離し、単一ページのコンテキスト “内” で共通関数を実行することで、複雑さを軽減することです。

この Web Components は、複数の API を組み合わせるか、それ単独を使用して実現します。
しかし、すべての Web ブラウザーがその API をサポートしているわけではないので、Polyfill 用のライブラリーとして Polymerx-tags といったものが用意されています。

Web Components を構成する API

Web Components を構成する API は現在以下のものがあります。

上記 4 つの API について簡単に紹介します。


 

HTML Templates

HTML のひな型を定義しておくためのタグです。

JavaScript を使用してテンプレート機能を実装する場合、ひな型となる HTML を非表示属性のタグ内に記述しておくという方法が採られますが、非表示タグのなかであっても実行はされます。

例えば、テンプレート内に画像を含んでいた場合は、画像がロードされたり、スクリプトがあった場合は実行が可能な状態となります。

これを防ぐために、最近の JavaScript フレームワークでは、 type 属性を “text/template” としてScript タグの中に記述されますが、これだと、記述した内容は innterHTML を使って文字列として取り出して処理することになるので、セキュリティ的に不安が残ります。

しかし、この template タグを使用すると、その内部に記述された内容は使用されるまで実体を持たないのでパフォーマンス的なオーバーヘッドを発生させず、かつセキュリティ的にも安全にテンプレートを定義することができます。

Shadow DOM

動的なページを作るうえで JavaScript による DOM の操作は不可欠です。DOM は getElementById メソッドなどを使用してページにロードされたスクリプトのどこからでもアクセスすることができます。また同様にロードされた CSS から自由にスタイルを適用させることができます。

これはある意味、操作に対して非常に無防備な状態であるとも言えます。

ページ内の DOM の状態は、グローバルな空間にインスタンスをむき出しに晒しているということでもあり、サードパーティー製のフレームワークを使用した際や、複数人での作業を行った場合、ID のバッティングや、意図しないアクセスやスタイルの適用など、関数における名前空間の汚染のような状況に陥る場合があります。これはコンポーネント化を実現するにおいては大きな不安要素となります。

Shadow DOM はホスト要素に Shadow Root というものを追加し、そのツリー配下に DOM 要素を追加することで DOM をカプセル化します。

Shadow Root に追加された DOM 要素は、Shadow Root を介してのみアクセス可能となり、その外側から JavaScript や CSS で直接アクセスすることはできません。

Shadow DOM を使用すると DOM のカプセル化問題を解決することができます。

Custom Elements

HTML のマークアップは、標準化されているためそのボキャブラリーは最大公約数的かつ抽象的であり、アプリケーションにおける”その要素”の意味するところを十分には説明しきれない場合があります。

Custom Elements を使用すると、独自の HTML/DOM 要素を定義してカスタマイズされた機能をバンドルできることはもちろん、既存の DOM 要素の機能を拡張したりもできます。

例えば、部品化した Web のパーツをページ内にスクリプトを使用することなく、可読性の良い独自のマークアップを使用して配置していくことができます。

HTML Imports

外部の HTML ファイルをインポートするためのものです。ファイルの中に格納するのは完全な HTML である必要はなく、インポートした際に機能が成立するものであれば問題ありません。

Web Components のサポート状況

Web Components の仕様は今日現在 (2016年6月)標準化されたものではありませんが、現在のメジャーな Web ブラウザーにおける Web Components を構成する 4 つの API のサポート状況は以下の通りです。

image

(※)Firefox は FirefoxOS にて Web Components を既定でサポートしていましたが、デスクトップ向けの Firefox ブラウザーではアドレスバーにて about:config での設定が必要です。

前出の 4 つの API のほかに、以前は Decorator というものがあり、それが仕様から外れたあと、Custom Properties が入ってきたとか来ないとか言われています。

さらに、上記の API 群による Web Components はすでに一部では “first generation” (第一世代) と呼ばれ、次世代の Web Components については各ベンダーから様々なプロポーサルが提出され、現在のところ仕様が揺れている段階です。

<参考>

 

Progressive Web Apps

Progressive Web Apps は モバイル Web アプリ向けのコンセプトであり、高性能のモバイル Web ブラウザー向けにアプリのような UX を提供しようというものです。

もともとは Alex Russell 氏(Google) のブログ記事に書かれたものでしたが、 2015 年の Chrome Dev Summit のキーノートで発表され話題になりました。

Web アプリによるネイティブアプリのような UX

HTML5 の登場により、Web ブラウザー上で動作するアプリケーションも、ネイティブアプリとほぼ同じような機能を実装できるようになりましたが  Web アプリケーションという性質上、インストールまでを含めたオフラインでの使用のサポート、プッシュ通知などは行えませんでした。

Progressive Web Apps では、新しい API のサポートによりこれを実現します。

Progressive Web Apps を実現するために使用される新しい API (と、既存の API) は以下のとおりです。

機能

API

オフラインサポート Service Worker
プッシュ通知 Web Notifications/Push API
ホームスクリーンにアイコンの追加 Web App Manifest
バックグラウンド Service Worker
高速でなめらかなインターフェイス CSS3 Animations


上記のような、これまでネイティブアプリにしかできなかった機能をサポートすることにより、Progressive Web Apps は ネイティブアプリの UX に加え、Web アプリケーションの以下の特徴も兼ね備えます。

  • クロスプラットフォー
  • アプリストアのエコシステムに縛られない
  • 事前のインストール不要

Progressive Web Apps の動作

Progressive Web Apps は必要な API をサポートする Web ブラウザーではネイティブアプリのように動作し、それ以外の Web ブラウザーでは通常の Web ページとして動作します。

この動作は、アプリにおける Progressive Enhancement といえます。

image

Progressive Web Apps を実装しているサイトとして、インドの Flipkart というサイトの動画が公開されています。

www.flipkart.com に Android スマートフォン上の Chrome/Firefox か、PC 版 Chrome の開発者ツールのデバイスエミュレーションでアクセスすると実際に操作することができるので、ぜひお試しください。

iPhone でも、完全ではありませんが、かなり近い動作を体験することができます。(※ちなみに先月くらいまでは iPhone からアクセスするとアプリのインストールを促されていましたが変更されたようです)

Service Worker について

Progressive Web Apps を実現するにおいて、中心的な役割を担うのが Service Worker です。

Service Worker は、端的にいうと JavaScript で実装されているローカルのプロキシ、あるいは改良版の App Cache といえるでしょう。

Service Worker としてインストールされたスクリプトは Web ページとは別にバックグラウンドで動作しつづけ、ネットワークリクエストへの介入や、プッシュメッセージ、レスポンスをプログラムから操作できるキャッシュ機能を提供します。

例えば、オフラインの場合には Service Worker がブラウザーのリクエストをハンドリングしてキャッシュの内容を返し、オフライン中に行われた作業の内容をキューイングして、オンラインになったらサーバーに情報をポストするといったことも実装可能です。

またアプリケーション自体をキャッシュに保存すれば、オフライン状態での起動も可能です。

なお、Service Worker は https での通信でのみ動作します。

image

Progressive Web Apps のサポート状況

Progressive Web Apps の仕様は今日現在 (2016年6月)標準化されたものではありませんが、仕様自体はずいぶんと固まっているようで、現在のメジャーな Web ブラウザーにおける Progressive Web Apps を構成する 6 つの API のサポート状況は以下の通りです。

image


Chrome や Firefox に続き、Edge も積極的にサポートする方向にある Progressive Web Apps は、スマートフォンであればすぐにでも使えそうな印象がありますが、残念ながらそうではありません。

「モバイル Web」という点では Progressive Web Apps の普及には 1 つ大きな課題があります。

それは iOS です。

Chorme も Firefox も iOS 用のものが App Store から提供されていますが、これらのレンダリングエンジンや JavaScript エンジンは Apple のサードパーティー・デベロッパー規約の関係から独自のものではなく iSO が提供するものを使用しています。

よって、iOS の提供するレンダリングエンジン (UIWebView, WKWebView) がこれらの機能をサポートしないかぎり、Progressive Web Apps で作られたページにアクセスしても Service Worker 等を利用した機能は使用することができません。

Apple さんが Progressive Web Apps  に対し、どのようなプランを持っているかは不明ですが、他の Web ブラウザーが足並みを揃えて Progressive Web Apps をサポートすることで、この状況が変化することを期待したいところです。

<参考>

Progressive Web Apps については Google の北村さんが非常に分かりやすくて、かつ詳しい資料を公開しておりますので、ぜひご覧くださいませ。

 

WebAssembly

WebAssembly は、コンパイル済のバイナリーを Web ブラウザーで直接動作させるものです。

このような試みは、Internet Explorer における ActiveX や Chrome における NaCl(Google Native Client)/PNaCl(Portable Native Client) 等がありましたが、いずれも特定の Web ブラウザーでしか動作しない相互運用性に欠けるものでした。

WebAssembly はどの Web ブラウザでも実行できることを目標に開発が進められている Web 向けのバイナリーフォーマットです。

2015 年 6 月 17 日に、Microsoft、Mozilla、Google および WebKit プロジェクトのエンジニアによって共同開発が表明され。ほどなく W3Cに 「WebAssembly Community Group」が設立されました。

WebAssembly のプロジェクトは GitHub の WebAssembly リポジトリで開発が進められています。

asm.js の次のステップ

Mozilla の開発した asm.js は、 固有の記述を行った JavaScript を型付言語として事前コンパイルし、実行時チェックやガベージコレクションといったパフォーマンスを低下させる処理を停止することで、高速な実行を可能にしました。

しかしながら、コードのサイズやロード時間、パース時間の長さなど、新たな課題が見つかってきました。WebAssembly はこれらの問題を解決しつつ、JavaScript では実現できない様々な機能をサポートします。

プログラムの記述に使用できる言語は、現在はまだ C/C++ だけですが、将来的に様々な言語で開発ができるようになる可能性があれます。

WebAssembly のサポート状況

WebAssembly は、まだまだ開発途中の技術であり正式にサポートしている Web ブラウザーはありませんが、2016 年 3 月 14 日 から 16 日の間に MicrosoftMozillaGoogle の 3 社が 3D ゲーム AngryBots での検証結果を相次いで各ブログで公開するなど、足並みを揃えつつ着実にプロジェクトが進んでいることが見て取れます。

image

<参考>

WebAssemblyの開発を担当し、ディスカッションのホストを務めたMozillaのルーク・ワグナー氏のインタービュー記事です。WebAssembly が生まれてきた経緯など、興味深い内容がたくさん書いてあります。

 

ハイブリッドアプリでの利用

Progressive Web Apps が普及すれば、今あるネイティブアプリの多くのものを Web アプリケーションが取って代わるかもしれません。

しかしながら依然としてネイティブアプリにしかできないことがあります。

それはアプリ ストアのエコシステムの利用と、ハードウェアやプラットフォームの機能などの Web ブラウザーには許可されていないリソースへのアクセスです。

しかし、Apache Cordova に代表されるハイブリッドアプリを開発するためのフレームワークで Web アプリをラップすることで、その制限を取り払い、ネイティブアプリと同等の機能を実装することができます。

とくに SPA は、アプリケーションとしての構成がネイティブアプリと同じなので、アプリ化もにも向いています。

また、Web サイトでホストされているコンテンツを使用する Hosted アプリにすれば、Web サイトとアプリでソースを物理的に共有することができます。

これにより 1 つの Web アプリケーションで、Web アプリケーションとしてのメリットはもちろんのこと、スマートフォンなどのアプリとしてのメリットを享受することができます。

image

ハイブリットアプリを開発するためのメジャーなフレームワークとしては、iOS, Android, Windows 10 の UWP (Universal Windows Platform) アプリまで幅広く開発可能な Adobe PhoneGapApache Cordova, React Native や、Windows、MacOS, Linux 用のデスクトップアプリケーションが開発可能な Electron、そして、これはツールになってしまうのですが、より深いレベルでの UWP アプリの開発が可能な Visial Studio があります。

これらハイブリッドアプリ開発用のフレームワークを使用することで、Web アプリケーションの可能性を Web ブラウザーの枠を超え押し広げることができます。

image



Web フロントエンドの開発リソースについて

Web 技術の進歩やクライアントデバイスの多様化に伴い Web アプリに求められる要件は増え、同時に作業工数と複雑さも日々増していきます。

こうした状況を解決するためにかつては存在しなかったさまざまなような開発リソースが次々と生み出され、現在も生み出され続けています。

これは開発リソースの選択肢が非常に豊富であることに他なりませんが、別の見方をすれば混沌とした状態であるともいえます。

それら開発リソースは機能が豊富であるが故に学習コストが高く、進歩のスピードが早い故に陳腐化も速いといったジレンマ抱えています。また、それらはいくつかを組み合わせて使用されることが多く、さらに状況を複雑にしています。

image

フレームワークの選定について

おびただしい開発リソースの中から最適なものを選択し、かつベストの組み合わせを見つけるのは大変です。

以前の記事に書いた内容の再掲ですが、JavaScript のライブラリ/フレームワークの選定を例に、最大公約数的なものではありますが、検討すべきポイントをあげますので参考にしていただければと思います。

ここでは JavaScript のフレームワークの採用を 2 段階にわけて判断しています。

【第 1 段階の判断】

  1. ターゲットの Web ブラウザーで動作すること

    Web コンテンツやアプリケーションが、サービスのサポート対象となっている Web ブラウザーで動作する必要があります。ライブラリ/フレームワークがサポートしている Web ブラウザーのバージョンを確認するとともに、実際に支障なく動作するのか、実装する予定の機能を前もって検証することをお勧めします。

  2. 技術サポートが受けられるか否か

    製造元、もしくはサードベンダーで技術サポートが受けられるか、もしくは、そういったサポートが必要なのか確認します。不具合の修正はもちろん、セキュリティホールのような重大な問題が見つかった際の対応、連絡はどのように行われるのか確認しましょう。

  3. 充分な情報があるか    
    ライブラリを使用するにあたって、使い方をはじめ充分に情報があるかを確認しましょう。インターネット上はもちろんですが、いくつか書籍が出ていたほうが安心です。

 

第 1 段階の判断で対象を絞ったら、第 2 段階の判断さらに絞り込んでいきます。

 

【第 2 段階の判断】

  1. 使用するまでの学習コスト    
    使用を開始するまでの学習コストが高すぎると、開発メンバーの追加や交代の際のスキルトランスファーや引き継ぎに時間がかかります。また、バージョンアップによる仕様の変更があまりに変更が大きいと、将来的なメンテナンスにも不安を抱えることになります。

  2. 開発生産性

    そのライブラリを使用して、どれくらいの範囲の作業が賄えるのか?、また、そのライブラリを使用してスムーズに開発が行える環境用意されているのか確認しましょう。メンバーに精通して人間がいる、開発ツールがそのライブラリの入力支援機能をサポートしている等です。

  3. ロックイン度合い

    広い範囲をライブラリで賄ってしまうと、ロックイン度合いも広くなります。どれくらいそのライブラリにロックインして構わないのか検討しましょう。ライブラリの開発が終了してしまった場合にロックインされた部分をどうするか、少なくとも、プログラムのどの部分を依存させるかを明確にしましょう。
    とくにフレームワークを使用した場合、ロックインはほぼ避けられないのでより慎重に選定する必要があります。

  4. 運用コスト

    運用コストを測りましょう。必要なアップデートが頻繁に行われたりすると、検証の回数が増えコストがかさみます。

image

ベンダー・ロックインについて

特定の技術要素や提供者であるベンダーに縛り付けられるいわゆる”ベンダー・ロックイン”は、マイナスな印象が強いですが、もちろん悪いことだけではありません。

ベンダー・ロックインが問題となるのは、依存していた技術要素がなんらかの事情により使用できなくなった場合です。

むしろロックインが強い = 依存度が高ければ高いほど、それは採用した側にとって有用なものであるといえます。

ベンダー・ロックインのマイナス面を顕在化させないためには、たとえば、有償のフレームワークやライブラリであれば、しっかりとしたサポート契約やパートナーシップ契約を結び、使用者側の意向が伝わりやすくするということができるでしょうし、コミュニティが提供する OSS であれば、コミッターやコントリビューターとして開発に参加するという方法もあります。

広範囲において依存性の高い技術要素を採用する際には、こうしたリスクやメリットをきちんと理解しておくことをお勧めします。

投資としての学習をどこにすべきか

Web 技術の進化のスピードは早く、それを取り巻く開発リソースの進歩もスピード同様であり、陳腐化していくスピードもまた同様に早くなっています。

ある程度の時間をかけて学習したフレームワークが、数か月後のバージョンアップによって仕様が大幅に変わってしまったり、プログラミングスタイルの変化によって時流にそぐわないものになってしまっているということは大いにあり得ることです。

こういった背景もあり、「投資としての学習をどこにすべきか?」というご質問を良くいただきます。

フロントエンド Web の開発について確実に学習コストの回収が行えるのは、Web 標準の技術と、それに準ずるデファクト スタンダードの技術についてです。

あたりまえの話しですが、W3C の策定する Web 標準の仕様は強制力こそないものの、ベンダー間にまたがる仕様で、ベンダーの都合によって変更したり、勝手に削除したりできるものではありません。

たしかに、Web 標準化のプロセスのスピードは昨今の Web の進化の速度にそぐわないところは否めませんが、それでも各方面で合意のとれたデファクト スタンダード技術のスナップショットとして信頼に足るものです。

また、W3C で勧告となっていなくとも、すべてのメジャーな Web ブラウザーがサポートしている技術については学習しておいて損はないでしょう。

ただし、一部の先進的な Web ブラウザーだけがサポートしている機能は、いくら開発者に人気が高くても注意が必要です。たとえば WebSQLObject.observe などは当時人気があり、先進的な開発者がこれらの機能を使用して先進的なプログラミングで先進的なアプリケーションを開発しましたが、前者は HTML5 の仕様から外れ、後者は ECMA Script 2016 の仕様から外れ、後者においては唯一サポートしていた V8 エンジンでもサポートされなくなっています

新しいデファクトスタンダードな技術を選定する際には、周囲の声に惑わさず、各 Web ブラウザーのサポート状況などから慎重に判断したいところです。

JavaScript については ECMA Script 2015、2016 を充分学習しておくことをお勧めします。

とくに ECMA Script 2015 で記述したコードは Babel でコンパイルすることにより、少し古い Web ブラウザーでも解釈可能な Ecma Script 5 にトランスコンパイルが可能です。

そもそもの話しをすれば、Web ブラウザーのドキュメントウィンドウ内で動作するのは、HTML と CSS と JavaScript だけです。ちまたに溢れる様々な魔法のような機能を提供する開発リソースも、結局はそれらを使用した開発を効率よく行うために考え出された手品にすぎません。

新しいサービスを開発するうえで大事なことは、今現在の技術で最大限なにが実現できるかを正確に把握しておくことです。それを、なにを使ってどう実現するかは、次のステップで良いでしょう。

開発者のゴールとは

Web のフロントエンド、サーバーサイドともに日々新しい技術やさまざまな開発リソースが登場してきます。しかしながらそれらはすべて開発作業を効率よく行うための道具であり、結局のところ「目的」を達成するための「手段」にすぎません。

それでは「開発者の目的」とはなんでしょう? 次々と現れてくる新しい技術を追いかけて理解し、複雑な仕組みをプロダクトに実装することでしょうか?

たしかに技術を深く理解することは大事ですが、そのために開発を行っているわけではないでしょう。

開発者が開発を行う目的はなにか?、たくさんの選択肢や、新しい技術に戸惑ったとき、あらためて問い直してみると良いかもしれません。

(ちなみに、私は「ユーザーに安定した良いプロダクトを提供すること」だと思っています。)

Web はどこに向かうのか

昨今、Web ブラウザーには、WebRTC や Fetch といったより低いレイヤーを扱える API や、WebAssembly といった、従来 Web ブラウザーの枠を超えるような機能が次々と提案され、実装されています。

これらはすべて、Web ブラウザー上にこれまでにない高度なアプリケーションの実装を可能にするためのものです。

OS の API として用意されている機能を Web ブラウザー上に標準化された仕様で再実装することで、「Web」は、OS やデバイスの垣根を越えた抽象化されたアプリケーションのプラットフォームへと向かいつつあります。

この流れは「変化」ではなく「拡張」です。できることが増えるだけであり、いままで出来たなにかが変わってしまうわけではありません。

たとえば、10 年以上前に書かれた HTML であっても、Web 標準に沿った仕様で正しく記述されているならば最新の Web ブラウザーはきちんと描画を行いますし、JavaScript も同様です。

これから時代が進むにつれ、さらにぞくぞくと新しい Web 技術が登場してくると思いますが、どうか不安にならず、楽しみにしていただければと思います 。

 

まとめ

今回の記事は、de:code 2016 の 2 日めのセッション ARC-003「モダン Web: たった今と、ほんの少し未来の話」 をブログ記事として再構成したものを投稿しました。

セッションで紹介した非同期処理を制御する API コードについては次回の記事で紹介させていただきます。

 

Real Time Analytics

Clicky

Comments (0)

Skip to main content