2018年に注目したい3つのWebテクノロジー：Web Components、Progressive Web Apps(PWA)、Universal JavaScript


個人的に2018年に注目したいWebの技術は、Web Components、Progressive Web Apps(PWA)、Universal JavaScriptの3つです。実は2017年がこれらの技術の飛躍の年でしたが、まだまだ波が小さいので、2018年に大きなトレンドになるか注目しています。

# Web Components

![webcomponents.org](https://web-components-resources.appspot.com/assets/images/introducing-the-element-registry.png)

Web Componentsは、Webの標準技術を用いて、独自のHTMLタグを作成するための技術です。HTML、CSS、JavaScriptを用いて、装飾とふるまいをカプセル化して独自のタグとして定義します。React、Vue.jsなどもHTML、CSS、JavaScriptを用いて、装飾とふるまいをカプセル化して独自のタグとして定義しますが、Webの標準技術だけを用いているわけではないので、Component指向ではありますが、Web Componentsではありません。

## Extensible Web

Web ComponentsはExtensible Webという考えに沿った、開発者によるWebの拡張を実現する技術といえます。Extensible Webは、[The Extensible Web Manifesto](https://extensiblewebmanifesto.org/)で明示されている考えで、時間のかかるWeb機能の標準化を待つのではなく、開発者がWebを拡張できるようにし、開発者がWebのインフラの一部として、Webの未来をつくることができるようにする考え、取り組みです。
そもそも、Webは過去をふりかえると、jQueryというライブラリがWebを拡張し、jQueryの一部が標準化されるといった開発者がWebの未来に貢献するということが頻繁に起きています。それをもっとやりやすくしよう、開発者と標準化のフィードバックループを早くしようという考えです。

## Web Componentsを構成する4つのAPI

Extensible Webに沿ってHTMLを拡張するWeb Componentsは、次の4つの仕様をベースにしています。

### Custom Elements

Custom Elementsは、独自のタグを定義する仕様です。

### Shadow DOM

Shadow DOMは、カプセル化を実現する仕様です。Shadow DOMを使ってCSSのスタイルを独自タグに適用すれば、外部のクラス名とバッティングしたりすることがありません。

### HTML imports

HTML importsは、HTMLドキュメントが他のHTMLドキュメントを取り込む仕様です。

### HTML Template

ページの読み込み時には描画させず、型として定義して後からJavaScriptで利用するためのHTMLを記述するための仕様です。

## WebComponents.org

Web Componentsによって、開発者が独自のタグを定義できるようになったら、それをシェアするNode.jsのnpmのような仕組みが必要です。それが、webcomponents.orgです。すでに多くのCustom Elementsが登録されており、Calendarだけでも18もあります。汎用的なものは、自分でつくる前に探してみるとよいでしょう。誰でも登録できるので、よく使っている部品があればWeb Component化すれば、webcomponents.orgに登録できます。

## 2017年にほぼ全てのモバイルで標準サポート

もともと、Web ComponentsはChromeがリードしてきたため、Chromeは早くからWeb Componentsをサポートしていました。そして、2017年にSafariがWeb Componentsの4つの仕様全てをサポートしたことで、10億以上のモバイルデバイスがWeb Componentsをサポートすることになりました。今や、新しいAndroidとiPhoneであれば、Web Componentsが標準で使えるということです。その意味で、2017年はWeb Componentsにとって重要な年になりました。
デスクトップブラウザはまだサポートしていないものがありますが、他のWeb技術の例にもれず、それを埋めるためのPolyfillが提供されています。WebComponents.orgでブラウザのサポート状況とPolyfillのインストール方法が確認できます。

## リンク集

* [webcomponents.orgによるWeb Componentsの定義](https://www.webcomponents.org/introduction)
* [上記の日本語訳](https://qiita.com/jtakiguchi/items/b1315f53b3726ff11b61)
* [MDNによるWeb Componentsの説明](https://developer.mozilla.org/ja/docs/Web/Web_Components)
* [Extensibe Web Manifesto](https://github.com/extensibleweb/manifesto)
* [上記の日本語訳](https://github.com/extensibleweb/manifesto/blob/master/README.ja.md)
* [Webcomponents.org](https://www.webcomponents.org/)
* [MDNによるCustome Elementsの説明](https://developer.mozilla.org/ja/docs/Web/Web_Components/Custom_Elements)
* [HTML5 RocksによるCustom Elementsの説明](https://www.html5rocks.com/ja/tutorials/webcomponents/customelements/)
* [MDNによるShadow DOMの説明](https://developer.mozilla.org/ja/docs/Web/Web_Components/Shadow_DOM)
* [HTML5 RocksによるShadow DOMの説明](https://www.html5rocks.com/ja/tutorials/webcomponents/shadowdom-201/)
* [MDNによるHTML importsの説明](https://developer.mozilla.org/ja/docs/Web/Web_Components/HTML_Imports)
* [HTML5 RocksによるHTML importsの説明](https://www.html5rocks.com/ja/tutorials/webcomponents/imports/)
* [MDNによるHTML Templateの説明](https://developer.mozilla.org/ja/docs/Web/HTML/Element/template)
* [HTML5 RocksによるHTML Templateの説明](https://www.html5rocks.com/ja/tutorials/webcomponents/template/)
* [polymer.orgによるWeb Componentsの説明](https://polymer-jp.org/about-web-components/)


# Progressive Web Apps(PWA)

![PWA](https://qiita-image-store.s3.amazonaws.com/0/50720/f7022658-0ec2-dca0-c8e9-6e3d8dc9264b.png "PWA.png")


PWAはGoogleが提唱している技術で、簡単に説明すると、「スマホのネイティブアプリと同等のユーザーエクスペリエンスをWebで実現する技術」です。例えば、スマホはアプリのインストールができて、ホーム画面のアイコンから起動できます。また、オフラインでも使えたり、何か変更があったときにはプッシュ通知で知らせてくれます。PWAでは、これらの機能をService WorkerなどのWeb標準技術を用いて実現しています。
以下は、PWAの特徴の一部に過ぎません。PWAの考えに基づいてGoogleが中心となって技術を開発し、その技術がW3Cなどの標準技術になるということがおこっています。PWAはスマホ時代の到来によってネイティブアプリに主役の座を奪われたWebを進化させて、もう一度輝きを取り戻すための取り組みとも言えるかもしれません。

## アプリのインストール（ホーム画面へのアイコン追加）
ユーザーにアプリの情報を提供するWeb App Manifestを利用して、2回目のアクセス（間隔が5分以上）時に、ホーム画面にブックマーク・アイコンを追加します（ユーザーが同意した場合）。

## オフラインでの利用
アプリとサーバーの間のプロキシサーバーとして機能するService Workerを利用して、オフラインのときにはキャッシュを使ってアプリを動作させます。

## プッシュ通知
標準のWeb PushやGoogle Cloud Messagingなどのサービスを使って、ブラウザにプッシュ通知を送ります。

## App Shell

App Shellは、画面の枠だけをつくっておいて、中身のコンテンツは動的に読み込むデザインパターンです。画面の枠はキャッシュしておくことで、オフラインでも起動でき、高速に表示することができます。中身のコンテンツはAPIでデータをとってくるという訳です。
単純に、どこまでをキャッシュにして、どのようなときにキャッシュを更新するかは、難しい問題ですが、[The offline cookbook](https://jakearchibald.com/2014/offline-cookbook/)、[その日本語訳](https://github.com/kuu/the-offline-cookbook-ja/blob/master/ja.md)が参考になります。
まずは、[GoogleのApp Shell モデル](https://developers.google.com/web/fundamentals/architecture/app-shell?hl=ja)からはじめるとよいでしょう。

## PRPLパターン

PRPLは、PWAを構築および配信するためのパターンで、アプリの配信と起動時のパフォーマンスに重点を置いたデザインパターンで、次の頭文字から命名されています。

* Push: 最初の URL ルートに不可欠なリソースを Push（プッシュ）する。
* Render: 最初のルートを Render（レンダリング）する。
* Pre-cache: 残りのルートを Pre-cache（事前キャッシュ）する。
* Lazy-load: オンデマンドで残りのルートを Lazy-load（遅延読み込み）する。

Service Workerを用いたキャッシュやHTTP/2による通信の高速化、HTTP/2サーバープッシュなどによって高速化を実現します。

## AMPとPWA(PWAMP)

AMP(Accelerated Mobile Pages)は、GoogleとTwitterが共同で策定したモバイルページの高速化技術です。AMPは高速に表示する静的ページのため、基本的にJavaScriptが使えないなどのいくつかの条件があります。この条件を満たしたページを用意すると、Google検索でイナズママークとともに表示され、SEOがよくなります。高速化という意味で、AMPはPWAと共通点を持つPWAとAMPを組み合わせるPWAMPというアイディアもGoogle I/O 2017で発表されています。

1.AMP as PWA
AMPページでPWAを動かします。AMPの条件があるため、ホーム画面へのアイコン追加など、PWAの一部しか活用できません。

2.AMP to PWA
AMPからユーザーにアクセスしてもらい、PWAに移動してもらいます。

3.AMP in PWA
PWAのコンテンツとしてAMPを利用します。

## Polymer

PolymerはGoogleが開発したフレームワークで、Web Componentsの仕様に完全に準拠しています。また、Polymer App Toolboxが提供されており、コマンド一発でPWAおよびPRPLパターンに対応したアプリの雛形作成できます。Web Componentsに対応したPWAを簡単につくるためのフレームワークともいえます。
さらに、[Polymer Catalog](https://elements.polymer-project.org/)に便利なWeb Components部品が各種提供されています。
また、Polymerは標準技術であるWeb Componentsを使っているため、他のフレームワークとも共存できます。[Custom Elements Everywhere](https://custom-elements-everywhere.com/)で確認する限り、Angular、Vueは問題なく共存できそうです。Reactは一部問題があるようです。
JavaScriptのフレームワークは、次々新しいものが誕生するので迷うところですが、標準技術を採用しているという点を重視する場合には最右翼のフレームワークといえます。

## 2017時点のリサーチファームの評価

最新のThoughtWorks Technology Radar Vol.17ではなくなっていますが、一つ前の2017年5月のVol.16では[PWAはTRIALと評価](https://www.thoughtworks.com/radar/techniques/progressive-web-applications)されています。TRIALはトライアルベースで利用することを推奨する段階です。
また、Gartnerの[Hype Cycle for Mobile Applications and Development, 2017](https://www.gartner.com/doc/3762279/hype-cycle-mobile-applications-development)では、On the Riseの状態で、期待が上昇している段階になっています。
Web Componentsと同様、PWAにとっても2017年は重要な年で、大きな期待がよせられはじめた年でした。

## リンク集

* [GoogleのProgressive Web Appsページ](https://developers.google.com/web/progressive-web-apps/)
* [はじめてのプログレッシブ ウェブアプリ](https://developers.google.com/web/fundamentals/codelabs/your-first-pwapp/?hl=ja)
* [プログレッシブウェブアプリ詳解 ─ 過去・現在・未来](https://html5experts.jp/agektmr/20527/)
* [アプリのインストール（ホーム画面へのアイコン追加）の実装方法](https://developers.google.com/web/fundamentals/app-install-banners/?hl=ja)
* [オフラインでの利用の実装方法](https://developers.google.com/web/fundamentals/codelabs/your-first-pwapp/?hl=ja#service_worker_app_shell)
* [プッシュ通知の実装方法](https://developers.google.com/web/fundamentals/codelabs/push-notifications/?hl=ja)
* [App Shell](https://developers.google.com/web/fundamentals/architecture/app-shell)
* [The offline cookbook](https://jakearchibald.com/2014/offline-cookbook/)
* [上記の日本語訳](https://github.com/kuu/the-offline-cookbook-ja/blob/master/ja.md)
* [Node.jsのWeb Pushライブラリ](https://github.com/web-push-libs/web-push)
* [AMP](https://www.ampproject.org/ja/)
* [PWAMP](https://developers-jp.googleblog.com/2017/08/progressive-web-amp-amp-shadowreader.html)
* [Server-Side React Rendering](https://css-tricks.com/server-side-react-rendering/)
* [PRPLパターン](https://developers.google.com/web/fundamentals/performance/prpl-pattern/)
* [prpl-server-node](https://github.com/Polymer/prpl-server-node)
* [Google I/O 2017 (YouTubeでみれるPWAに関するプレゼンが多くあります)](https://events.google.com/io/)
* [Chrome Dev Summit 2017 (YouTubeでみれるPWAに関するプレゼンが多くあります)](https://developer.chrome.com/devsummit/)
* [Polymer Project](https://www.polymer-project.org/)
* [Polymer Catalog](https://elements.polymer-project.org/)
* [Custom Elements Everywhere](https://custom-elements-everywhere.com/)
* [ThoughtWorks Technology Radar PWA](https://www.thoughtworks.com/radar/techniques/progressive-web-applications)

# Universal JavaScript

![Universal JavaScript](http://static.ethomasjoseph.com/images/universal-js.png)

クライアント（ブラウザ）でもサーバー（Node.js）でも、環境に依存せずに実行できるJavaScriptをUniversal JavaScriptといいます。通常、ブラウザで動作するJavaScriptは画面があることを前提にしています。そのようなコードは、サーバー側では動作しません。そのため、Universal JavaScriptにするのはかなり大変です。しかし、それでも、Universal JavaScriptにするのには理由があります。

## SPAの問題

2014年のJolt Awardsをとった書籍「シングルページWebアプリケーション」で有名になったSPA(Single Page Application)は、今では多くのWebアプリが採用しています。しかし、SPAが広まるにつれ、同時にSPAの問題もうかびあがってきました。特に問題視されているのは次の2点です。

1. 初期ロードが重い
2. SEOが悪くなる

1はフロントに全ての処理を持ってきて、バックエンドは基本的にはデータなどをAPIで提供するだけにする訳ですから、どうしてもそうなってしまいます。また、2については、GoogleのクローラーはJavaScriptを実行しないので、SPAにしてしまうと、クローラーはSPAが動的に生成するページを認識できません。Googleはこの問題に対して対応しているようですが、現状はまだ解決されたとは言えない状況です。

## SSR

この2つの問題を解決するため、SSR(Server Side Rendering)という、初回ロード時のみ、サーバー側でHTMLをレンダリングさせる方法がよく用いられます。[Reactなどのいくつかのフレームワークが対応](https://css-tricks.com/server-side-react-rendering/)しています。しかし、SSRをするために、個別にコードを書かなければならないのは非常に大変です。
個別にSSRのコードを書くのではなく、SPAをデプロイすると、動的に生成されるページをプリレンダリングしてくれるサービスもあります。

* [Rendertron](https://github.com/GoogleChrome/rendertron)
* [Prerender](https://github.com/prerender/prerender)

## IsomorphicからUniversal JavaScriptへ

Universal JavaScriptと似た概念にIsomorphic JavaScriptというものがあります。書籍「アイソモーフィックJavaScript」では、完全に環境に非依存なものがUniversalで、コードや環境にある程度の変更が必要なものはIsomorphicとしています。Isomorphicには幅があり、完全に環境依存がなくなるとUniversalということです。
しかし、今では、Isomorphicという用語はあまり用いられないようです。用語がわかりにくいという理由もありますが、もともとは、完全に環境に非依存にすることが難しかった状況が改善されてきたという背景もあるようです。

## Next.jsとNuxt.js

### Next.js

Next.jsはReactアプリをコマンド一発でSSRするフレームワークです。`./pages`にSSRするコンポーネントを配置するなど、いくつかの規約があるので、既存のReactアプリに適用するのは難しいかもしれません。新しくReactプロジェクトをはじめる際には、ぜひとも採用したいフレームワークです。

### Nuxt.js

Nuxt.jsは、Next.jsと同じようにSSR用のフレームワークですが、ReactではなくVue.js用です。さらに、Nuxt.jsはSSRの他に、ES6/ES7のトランスパイレーション、JSとCSSのバンドル及びミニファイといったことも実施されます。ヤクの毛刈り的なことをまとめて引き受けてくれるフレームワークといえます。Vue.jsはライトウェイトで様々な組み合わせや利用環境に対応できるのがよい点の一つですが、大きなプロジェクトではそれがデメリットにもなりえます。Nuxt.jsを組み合わせると、ある意味での標準化ができ、SSRも簡単にできるので、非常に協力なツールになります。

### Angular Universal

~~Angular2でSSRを実現するライブラリです。"Server-side Rendering for Angular 2 apps"と銘打っているとおり、Angular2のみ対応しており、最新のAngularには対応していないようです。~~

Angular2までは[Angular Universal](https://universal.angular.io/)というライブラリでSSRを実現できます。ver4からは、「@angular/platform-server」という公式ライブラリでSSRが実現できます。

## リンク集

* [Universal JavaScript](https://medium.com/@mjackson/universal-javascript-4761051b7ae9#.d39eaqcjp)
* [Rendertron](https://github.com/GoogleChrome/rendertron)
* [Prerender](https://github.com/prerender/prerender)
* [Next.js](https://zeit.co/blog/next4)
* [Nuxt.js](https://nuxtjs.org/)
* [Vue.js製フレームワークNuxt.jsではじめるUniversalアプリケーション開発](https://html5experts.jp/potato4d/24346/)
* [Angular Universal](https://angular.io/guide/universal)