<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>Polymer &#8211; HTML5Experts.jp</title>
	<atom:link href="/tag/polymer/feed/" rel="self" type="application/rss+xml" />
	<link>https://html5experts.jp</link>
	<description>日本に、もっとエキスパートを。</description>
	<lastBuildDate>Sat, 07 Jul 2018 03:14:05 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.19</generator>
	<item>
		<title>Googleが新たに提唱するProgressive Web Appsの新たな開発パターン「PRPL」とは？</title>
		<link>/komasshu/19704/</link>
		<pubDate>Wed, 22 Jun 2016 01:00:14 +0000</pubDate>
		<dc:creator><![CDATA[小松 健作]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[I/O 2016]]></category>
		<category><![CDATA[PWApps]]></category>
		<category><![CDATA[Polymer]]></category>

		<guid isPermaLink="false">/?p=19704</guid>
		<description><![CDATA[「Google I/O 2016」では、これからのWebアプリ開発パターンとして提唱しているPWApps(Progressive Web Apps）について多くのプレゼンテーションがなされました。 PWAppsとは、最新...]]></description>
				<content:encoded><![CDATA[<p>「Google I/O 2016」では、これからのWebアプリ開発パターンとして提唱しているPWApps(Progressive Web Apps）について多くのプレゼンテーションがなされました。</p>

<p>PWAppsとは、最新のWeb技術を有効に活用し、漸進的（Progressive）に高度なユーザー体験を提供しようとする概念です。このPWAppsの概念を具体化する一つの手法として、「PRPL」（パープル）と名付けられた開発・提供パターンが提案されました。本稿ではこのPRPLを解説するとともに、その有効性や課題点を考察します。</p>

<p>本稿は、Google I/O 2016の二つのセッションに関する、解説記事です。</p>

<ul>
<li><a href="https://www.youtube.com/watch?v=fFF2Yup2dMM" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer and Progressive Web Apps: Building on the modern web</a></li>
<li><a href="https://www.youtube.com/watch?v=J4i0xJnQUzU" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Progressive, Performant, Polymer: Pick Three</a></li>
</ul>

<h2>PRPLの概要、PWAppsとの関係</h2>

<p>PRPLは、次の4つの頭文字をとった、開発パターンです。</p>

<ul>
<li>Push</li>
<li>Render</li>
<li>Pre-cache</li>
<li>Lazy-load</li>
</ul>

<p>モバイルWebアプリケーションにおいて、現行のWeb開発・提供パターンが抱える課題点を解決するものとしてGoogleが今回の I/Oで提案した新たなフレームワークパターンです。</p>

<p>Web Componentsや、Service Worker、HTTP/2 Serveer Pushといった Webの最新技術をフルに活用し、レスポンス性の高いユーザー体験を提供しようというものです。PWAppsの具体的なパターンの一つとして位置付けられます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/06/1.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/06/1.png" alt="The PRPL Pattern" width="640" height="330" class="aligncenter size-full wp-image-19706" srcset="/wp-content/uploads/2016/06/1.png 640w, /wp-content/uploads/2016/06/1-300x155.png 300w, /wp-content/uploads/2016/06/1-207x107.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>PRPLについては、以降のパラグラフで詳しく解説するとして、まず最初にPWAppsについて概説します。</p>

<p>PWAppsが最初に発表されたのは、昨年11月。シリコンバレーGoogleオフィスで開催された <a href="https://developer.chrome.com/devsummit" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Chrome Dev Summit</a>のことです。モバイルWebアプリにメインターゲットをおき、ネイティブアプリに近いユーザー体験（オフライン動作や高速なレスポンス性）を漸進的に提供していこうという考え方です。</p>

<p>ここで、漸進的といっても、イマイチピンと来ない方も多いことでしょう。具体例としてService Workerのパターンについて紹介します。Service Workerの詳細ついては、<a href="http://www.html5rocks.com/ja/tutorials/service-worker/introduction/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML5 Rocks</a>や<a href="https://html5experts.jp/kinuko/16537/" data-wpel-link="internal">Googleの安田絹子さんの記事</a>（Service WorkerのChrome実装者です！）を参照ください。</p>

<p>Service Workerは、オフラインWebを実現する最新Web標準技術の一つ。オフライン環境でも動作するWebアプリケーションの提供を可能とします。オールドファッションなオフライン Web（Application Cache）とは異なり、柔軟なキャッシュ制御が可能となるため、多様なWebアプリケーションにオフライン Webの世界を適用することができます。ネイティブアプリのようにオフラインでも動作するWebアプリ体験を提供することが可能となるわけです。</p>

<p>また、Service Workerは単なるオフラインアプリの実現にとどまりません。多様なキャッシュ制御ができるということは、リソース（HTMLやJavascriptファイルなど）のロード時間短縮が可能となることを意味しており、アプリキャッシュによる高速なレスポンス性を実現します。</p>

<p>さらに、Service Workerは、プッシュ通知もサポートします。これにより、該当のWebサイトにアクセスしていなくても、通常のモバイルアプリのようにプッシュ通知を提供することができます。Service WorkerはモバイルアプリとWebアプリとの間の様々なギャップを埋め、より高度なユーザー体験を提供するためのAPIなのです。</p>

<p>では、このService Workerと漸進性との関係はなんでしょう？答えは単純で、Service Workerは、それが対応していないブラウザ環境であっても、Webサイトのサービス提供自体を止めることはありません。</p>

<p>したがって、非対応ブラウザ利用ユーザーには、ベースとなるWebサービスのみを提供し、対応ブラウザ利用ユーザーには、オフライン対応・高速なレスポンス性・プッシュ通知といったより高度なユーザー体験を提供します。これが漸進的なWebアプリケーションと言われる所以です。</p>

<h2>現状のWeb開発課題を解決するPRPL</h2>

<p>さて、本題のPRPLです。これは前述のService Workerなど、様々な最新Web技術を活用したWeb開発・提供パターンです。もちろん、PWAppsの理念に基づいています。</p>

<h3>現状のWebアプリ開発の課題。バンドルの肥大化</h3>

<p>最近のWebアプリ開発手法は、コンポーネント化による独立性・安定性の向上と、バンドル（単一ファイルの生成）による高速性の両者に基づいています。BabelやReact、npmといったツール類を用い、ES2015やTypeScript記法による洗練されたコンポーネント志向のコーディングを行いつつ、mochaやwebpackなどを用い、オートメーション化されたテスト駆動開発と全てのコンポーネントを集約したコンパイルの実行、バンドルを行うのがベストプラクティスとなっています。</p>

<p>ここで、コンポーネント化のメリットは解説不要でしょう。Webアプリの各機能要素をライブラリとしてコンポーネント開発することで、独立性・安定性・再利用性といった様々な恩恵を得ることができます。</p>

<p>一方で、バンドル化のメリットはなんでしょうか？答えは、ロード時間の短縮です。この点は、PRPLを理解する上で重要な知識となりますので、より詳しく紹介します。</p>

<p>そもそも、Webはコンポーネント志向を支えるプラットフォームであると捉えることができます。それぞれのコンポーネント要素（Javascriptライブラリ、HTMLテンプレート、CSS）は、それぞれ個別のリソースファイルとして提供され、 &lt;script&gt; タグや、 &lt;link&gt; タグなどにより個別にダウンロード、ブラウザ内で一連のプログラムとして結合・コンパイルされ、Webサービスとして提供されます。</p>

<p>しかし、このような開発・提供手法は甚大なユーザー体験の低下を招きます。HTTP/1.1の制約により、ファイルロード時間の増大を促してしまうのです。HTTP/1.1はリクエスト＆レスポンス型のデータ転送プロトコルとなっているため、リソースファイルのダウンロードが完了しないと、次のファイルのダウンロードを開始することができません。</p>

<p>この影響は無視することができないものであり、仮にブラウザとWebサーバー間の往復転送遅延時間を0.1秒とし、300個のコンポーネントリソースをダウンロードしなければならないとなると、0.1 x 300で合計30秒の待ち時間がサービス起動にかかってしまいます（実際には、平行ダウンロードにより数分の一に短縮されますが、極端な例として理解ください）。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/06/2.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/06/2.png" alt="HTTP/1.1" width="640" height="332" class="aligncenter size-full wp-image-19713" srcset="/wp-content/uploads/2016/06/2.png 640w, /wp-content/uploads/2016/06/2-300x156.png 300w, /wp-content/uploads/2016/06/2-207x107.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>これを解決するのがバンドルです。Webアプリ開発時に、サーバーサイドで一連のコンポーネントリソースを結合した一つのファイル（バンドル）を生成し、サービス提供時には、バンドルファイルのみをダウンロードすることで、転送待ち時間によるサービス起動時間を短縮する手法が用いられています（バンドル時には単に結合するだけでなく、ブラウザ依存の解決や、構文チェック・コードの最適化・重畳リソースの削減など、各種コンパイルプロセスが実行されます）。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/06/3.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/06/3.png" alt="App bundling" width="640" height="335" class="aligncenter size-full wp-image-19714" srcset="/wp-content/uploads/2016/06/3.png 640w, /wp-content/uploads/2016/06/3-300x157.png 300w, /wp-content/uploads/2016/06/3-207x108.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>しかし、これは新たな問題を引き起こしました。それはバンドルファイルの肥大化です。全てのコンポーネントが一つのリソースファイルに集約されるため、設計を怠るととんでもないサイズのバンドルファイルが生成されます。</p>

<p>最近では、SPA（Single-Page Application）の進展により、全てのルート（SPAに不慣れな方は、個別のWebページと考えていただいて結構です）を制御する一つのバンドルファイルが提供されることも珍しくありません。</p>

<p>このようなケースでは数百キロバイトのバンドルファイルとなることもチラホラ。ダウンロード時間の増大をもたらします。これは、モバイル環境のユーザーにとっては、とくに深刻な状況になりえます。</p>

<h3>コンポーネント志向への回帰。PRPLによる解決</h3>

<p>このバンドルファイルの肥大化問題を解決するのがPRPLです。最新のWeb技術を活用することで、バンドルを行わずとも、転送待ち時間によるユーザー体験の低下を解決することができます。</p>

<h4>コンポーネントの定義</h4>

<p>PRPLでは、各コンポーネントがWeb ComponentsのCustom Elementsで提供されることを前提とします。具体的には、各コンポーネントが カスタム要素としてHTMLファイルとして提供され、親となるHTMLからはHTML Importsにより各コンポーネントの利用が宣言されます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/06/4.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/06/4.png" alt="HTML Imports" width="640" height="333" class="aligncenter size-full wp-image-19715" srcset="/wp-content/uploads/2016/06/4.png 640w, /wp-content/uploads/2016/06/4-300x156.png 300w, /wp-content/uploads/2016/06/4-207x108.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>この手法の重要な点は、標準化された手法によりコンポーネントの利用が宣言されること、これによりサーバーサイドでHTML Importsのリンクを解析し、Webサービスに必要となるコンポーネントツリーを得ることができます。これが、その後の HTTP/2 Server pushの適用につながります。</p>

<h4>HTTP/2 Server pushの適用</h4>

<p>先に解説した通り、HTML Importsで記述した場合、個別のリソースファイルの転送待ち時間によるサービス起動時間の増大が発生します。これを解決するため、PRPLではHTTP/2 Server pushが利用されます。</p>

<p>HTTP/2は、HTTP/1.1に続く最新バージョンのファイル転送プロトコル。HTTP/1.1のリクエスト＆レスポンスによる待ち時間の制約を受けずに、複数リソースファイルを効率的・スピーディーにダウンロードすることが可能になります。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/06/5.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/06/5.png" alt="HTTP/2" width="640" height="331" class="aligncenter size-full wp-image-19716" srcset="/wp-content/uploads/2016/06/5.png 640w, /wp-content/uploads/2016/06/5-300x155.png 300w, /wp-content/uploads/2016/06/5-207x107.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>HTTP/2では、ダウンロード完了を待つことなく、以降のリソースダウンロードを行うことができます。したがって、サーバーサイドでバンドルすることなく、個別のコンポーネントファイルを高速に転送することができるのです。</p>

<p>PRPLでは、さらなる転送時間の短縮を図るため、HTTP/2 Server pushが用いられます。先にも書いた通り、PRPLでは各コンポーネントファイルがHTML Importsの記法により親となるHTMLファイルに記載されています。したがって、最初のHTMLファイルがダウンロード完了しないと、各コンポーネントファイルのダウンロードを開始することができません。</p>

<p>しかし、HTTP/2 Server pushを用いると、この待ち時間すら短縮することができます。前述の通り、PRPLでは、サーバーサイドで HTML Importsを解析し、コンポーネントツリーを得ます。そして、そのコンポーネントを最初のHTMLファイルに対するレスポンスヘッダーに記述することで、HTTP/2サーバーはクライアントからのリクエストを待つことなく、以降のコンポーネントリソースをPushすることができます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/06/6.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/06/6.png" alt="HTTP Request Headers" width="640" height="331" class="aligncenter size-full wp-image-19717" srcset="/wp-content/uploads/2016/06/6.png 640w, /wp-content/uploads/2016/06/6-300x155.png 300w, /wp-content/uploads/2016/06/6-207x107.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/06/7.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/06/7.png" alt="HTTP/2 + Server Push" width="640" height="333" class="aligncenter size-full wp-image-19718" srcset="/wp-content/uploads/2016/06/7.png 640w, /wp-content/uploads/2016/06/7-300x156.png 300w, /wp-content/uploads/2016/06/7-207x108.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>これにより、いわゆる0 RTT（Round-Trip Time）で、全てのコンポーネントリソースをブラウザに転送することが可能になります。</p>

<h4>Service workerによるpre cache</h4>

<p>ここまでであげた手法により、<em>初期起動に必要</em>となる リソースを高速に転送し、ユーザーの起動待ち時間を短縮することが可能となりました。しかし、Webサービスは、初期画面だけではありません。その後の、ユーザー操作に基づいた各画面の提供が必要となります。</p>

<p>例えば、ショッピングサイトでは、各商品画面や商品購入画面が必要となります。これらを形成するコンポーネントは、初期画面に含まれるものもあるでしょうし、それ以外のものも含まれるでしょう。これらのコンポーネントリソースのダウンロード待ち時間を短縮するために、PRPLではService Workerが用いられます。</p>

<p>PRPLでは、初期画面用のコンポーネントリソースをService Workerを用いて、キャッシュに保存します。以降の画面で該当のコンポーネントが必要になった場合は、このキャッシュが用いられるためダウンロードは発生しません。</p>

<p>また、初期画面を表示したあと、以降の画面で必要となるコンポーネントリソースをバックグラウンドで事前にダウンロードし、Service Workerを用いキャッシュとして保存します（pre cache）。したがって、これらのコンポーネントリソースについても待ち時間は発生しません。非常にレスポンス性の高いWebアプリをon-the-flyで提供することが可能となります。</p>

<h4>さらにユーザー体験を向上する lazy load</h4>

<p>最後にlazy loadです。Webアプリのリソースには優先度があります。例えば、ファーストビューには表示されない画像ファイル、初期画面のメニューコンポーネントなどは、優先度が低いリソースの典型的なものです（メニューは、ファーストビューに含まれますが、最初からは表示されてなくてもいいですよね！）。</p>

<p>これらのリソースについては、lazy-loadとして、優先度の低いものとして宣言してしまいます。こうすることで、ブラウザはこれらのリソースのダウンロード順番の優先度を下げ、ファーストビューに本当に必要なものを優先して表示することができるようになります。</p>

<h2>サンプルサイト、開発ツール</h2>

<p>PRPLを活用したサンプルサイトとして、ショッピングサイトのサンプルが公開されています。</p>

<p><a href="https://shop.polymer-project.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">https://shop.polymer-project.org/</a></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/06/8.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/06/8.png" alt="SHOP" width="640" height="333" class="aligncenter size-full wp-image-19719" srcset="/wp-content/uploads/2016/06/8.png 640w, /wp-content/uploads/2016/06/8-300x156.png 300w, /wp-content/uploads/2016/06/8-207x108.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>Chromeのdev tool、networkタブのwarter fallパターンから、PRPLの転送フローを確認することができます。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/06/9.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/06/9.png" alt="SHOP - Push" width="640" height="330" class="aligncenter size-full wp-image-19720" srcset="/wp-content/uploads/2016/06/9.png 640w, /wp-content/uploads/2016/06/9-300x155.png 300w, /wp-content/uploads/2016/06/9-207x107.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>また、開発ツール<a href="https://www.polymer-project.org/1.0/toolbox/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer App Toolbox</a>ではPRPLの一端が提供されています。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2016/06/10.png" data-wpel-link="internal"><img src="/wp-content/uploads/2016/06/10.png" alt="Polymer App Toolbox" width="640" height="331" class="aligncenter size-full wp-image-19721" srcset="/wp-content/uploads/2016/06/10.png 640w, /wp-content/uploads/2016/06/10-300x155.png 300w, /wp-content/uploads/2016/06/10-207x107.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p></p><pre class="crayon-plain-tag">$ npm install -g polymer-cli
$ mkdir my-app; cd my-app
$ polymer init app-drawer-template
#... write code ...
$ polymer build</pre><p></p>

<p>HTTP/2対応ブラウザ、非対応ブラウザ用に、それぞれPRPLの概念に基づいた非bundle版、bundle版のjsが生成されます（こういったところに、PWAppsの概念が適用されています）。ただし、こちらの開発ツールでは、HTTP/2サーバーは提供されておらず、PRPL概念の一部を具体化したものとなっています。その点は、注意してください。</p>

<h2>PRPLは即座に利用可能か？</h2>

<p>さて、今回のGoogle I/Oで発表・提案された新たな開発・提供手法のPRPL。最新のWeb技術を活用することで、従来のWebアプリが内包する課題を解決し、モバイル環境での最高のユーザー体験提供を目指したものです。ただ、ここで気になるのが、以下の2点です。</p>

<ul>
<li>「PRPLは今すぐ、production環境に適用できるものなのか？」</li>
<li>「本当にこれまでの開発プラクティスよりも優れているのか？」</li>
</ul>

<p>この点について、（あくまで）個人的な見解を述べ、本稿を締めたいと思います。</p>

<p>まず結論から言うと、「<em>Productionでの利用は、まだ早い</em>」 というのが僕の率直な感想です。</p>

<p>その理由として、以下の点があげられます。</p>

<h4>まだHTTP/2の環境が整備されていない</h4>

<p>HTTP/2は、最近標準化が完了したばかり、実装はまだ完全には追いついていません。実際、apahceやnginxではHTTP/2の基本機能は搭載されているものの、Server pushまだ未サポートです。</p>

<p>また、これらの実装が完了したからといって、それがすぐ Productionに適用できるというものではありませんし、AmazonのELBやHerokuなどIaaS/PaaS事業者側のサポートも必要となるでしょう。WebSocketがそうであったように、サーバーサイドのエコシステムが整備されるのにはしばらく時間が必要です。</p>

<h4>まだ開発者フレンドリーではない</h4>

<p>開発ツールPolymer App Toolboxを見てみてもわかりますが、PRPLの概念はnpm + webpackのような開発者フレンドリーな開発手法とは相性が悪いです（実際、bowerが用いられています）。</p>

<p>Webアプリのコンポーネント開発において、Javascript部分が占める割合は非常に大きく、これをbowerベースで行い、いちいちHTML Importsで記述することは大変なストレスとなります。やはり、npm + webpackでストレスレスにコーディングしたい…、というのがJSエンジニアの率直な意見でしょう。</p>

<h4>cacheとの相性が悪い</h4>

<p>PRPLで用いられているHTTP/2 Server pushですが、Webのキャシュと非常に相性が悪いことが知られています。基本的に、ブラウザの状態と無関係にリソースをPushする仕組みのため、ブラウザにキャッシュがあろうがなかろうが、リソースをPushしてしまいます。</p>

<p>したがって、「初回の起動である」、「常にダイナミックに変動するリソースである」の場合を除いてHTTP/2 Server pushの効果は限定的ですし、逆に負の効果をもたらします(キャッシュがあるのであれば、リソースをPushする必要はない)。バンドルのサイズ肥大化の問題も、persistant cache制御さえちゃんとしてやれば、初回起動時およびバンドル変更時の問題だけになります。</p>

<h2>最後に</h2>

<p>最後にネガティブな意見を述べましたが、僕はPRPLの考えには基本的に賛同しています。Googleは常にWebをより良いものにするため、努力を続けている企業。その姿勢の表れであると感じています。</p>

<p>本稿で述べたPRPLの限界点は、現状のツール環境に依存するところが大きく、新たなツールが登場することでこの状況は一変することでしょう（本来、ツールは概念の一部を具現化するものであって、それをもって概念全体を評価されるべきものではありません）。</p>

<p>さまざまな概念やツールが融合し、開発者がフィードバックしていくことで、よりよい形が作り上げられていく。これまでのWeb開発の進化がそうであったように、そのような文脈の中でPRPLや、それのベースとなっているPWAppsが進化していくことでしょう。</p>
]]></content:encoded>
			</item>
		<item>
		<title>Polymer v1.1のAPIまとめと周辺リソースの紹介</title>
		<link>/1000ch/17410/</link>
		<pubDate>Thu, 29 Oct 2015 01:06:17 +0000</pubDate>
		<dc:creator><![CDATA[泉水翔吾]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Polymer]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=17410</guid>
		<description><![CDATA[連載： 基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜 (6)Googleが開発するWeb ComponentsのライブラリPolymerのバージョン1.1が、2015年8月13日に...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/web-components-2/" class="series-214" title="基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜" data-wpel-link="internal">基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜</a> (6)</div><p>Googleが開発するWeb Componentsのライブラリ<a href="https://www.polymer-project.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer</a>のバージョン1.1が、2015年8月13日にリリースされました。本記事では、Polymer v1.1のAPIの主要なAPIを解説しつつ、その参考情報を紹介していきます。</p>

<p>また、この記事は「<a href="https://html5experts.jp/1000ch/14400/" data-wpel-link="internal">Web ComponentsのこれからーPolymer 0.8、X-Tag、Brick、Bosonic</a>」を事前に読むと理解が深まりますが、これからPolymer v1.1を始めてみるということであれば、本記事単体でも参考にしてもらえればと思います。</p>

<h1>Polymer v1.1までの変更点</h1>

<p>v0.5からv0.8にかけての差分は<a href="https://html5experts.jp/1000ch/14400/" data-wpel-link="internal">前回の記事</a>にて紹介しましたが、その1週間後にv0.9がリリースされ、さらに2週間後にv1.0がリリースされています。</p>

<ul>
<li><a href="https://blog.polymer-project.org/updates/2015/03/27/why-0.8/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">0.8 released! &#8211; polymer blog</a></li>
<li><a href="https://blog.polymer-project.org/announcements/2015/05/14/0.9-release/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">0.9 released! &#8211; polymer blog</a></li>
<li><a href="https://blog.polymer-project.org/announcements/2015/05/29/one-dot-oh/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">1.0 &#8211; polymer blog</a></li>
<li><a href="https://blog.polymer-project.org/announcements/2015/08/13/1.1-release/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">1.1 Release &#8211; polymer blog</a></li>
<li><a href="https://www.polymer-project.org/1.0/docs/migration.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Migration guide</a></li>
</ul>

<p>v0.8からv1.0にかけてAPIに変更が加えられていますが、v1.0からv1.1へかけては破壊的なAPIの変更はありません。今回は以降で、Polymer v1.x系の主な機能と、参考リソースの紹介をしていきます。</p>

<p><img src="/wp-content/uploads/2015/10/polymer-project-640x541.png" alt="polymer-project" width="640" height="541" class="alignnone size-large wp-image-17419" srcset="/wp-content/uploads/2015/10/polymer-project.png 640w, /wp-content/uploads/2015/10/polymer-project-300x254.png 300w, /wp-content/uploads/2015/10/polymer-project-207x175.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>カスタム要素の登録</h2>

<p>&lt;dom-module&gt; に &lt;template&gt; と &lt;script&gt; を記述して宣言します。 &lt;script&gt; 内で実行している<code>Polymer()</code>関数は、 &lt;dom-module&gt; に指定しているID（カスタム要素の名前）を渡し、その他の引数でカスタム要素の振る舞いを決定します。返り値にはカスタム要素のコンストラクタが返却されるので、それを使ってカスタム要素のインスタンスを生成することも可能です。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="import" href="bower_components/polymer/polymer.html"&gt;

&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    &lt;style&gt;
      div { color: red; }
    &lt;/style&gt;
    &lt;div&gt;Shadow DOM in My Element&lt;/div&gt;
  &lt;/template&gt;

  &lt;script&gt;
    var MyElement = Polymer({is: 'my-element'});
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<p>v0.8との違いは、カプセル化されるカスタム要素のスタイルを記述する &lt;style&gt; と、<code>Polymer</code>関数を実行する &lt;script&gt; を &lt;dom-module&gt; の中に書くようになった点です。v0.5までの &lt;polymer-element&gt; を彷彿させます。v1.1では &lt;template&gt; の外側に &lt;style&gt; を書いてもスタイルが適用されますが、パフォーマンスは悪く推奨されません。</p>

<h3>カスタムコンストラクタ</h3>

<p>カスタム要素のコンストラクタを自前で書きたい場合は、<code>Polymer()</code>関数の引数として、<code>factoryImpl</code>キーワードと共にコンストラクタ関数を渡します。カスタムコンストラクタによって、引数を渡すことが可能になります。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  var MyElement = Polymer({
    is: 'my-element',
    factoryImpl: function(foo, bar) {
      // custom constructor is called
    }
  });

  var myInstance = new MyElement('foo', 100);
&lt;/script&gt;</pre><p></p>

<p>この<code>factoryImpl</code>はコンストラクタ関数（ここでは<code>MyElement</code>）を<code>new</code>キーワードと共呼び出した場合のみ実行され、HTMLドキュメントで &lt;my-element&gt; が評価された場合には呼ばれません。</p>

<h3>ネイティブ要素の継承</h3>

<p>ネイティブ要素を継承したカスタム要素を作る場合は、<code>Polymer()</code>関数の引数に<code>extends</code>キーワードに継承するネイティブのHTML要素を指定します。v0.5まではカスタム要素の継承もサポートされていましたが、Custom Elementsの仕様として<code>document.registerElement()</code>にカスタム要素名を渡せないのと同様、ブラウザネイティブの要素（<code>input</code>や<code>button</code>など）のみを指定できるようになっています。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  var MyElement = Polymer({
    is: 'my-element',
    extends: 'button'
  });
&lt;/script&gt;</pre><p></p>

<p>ネイティブ要素を拡張するカスタム要素を使うには、<code>extends</code>に指定した要素にカスタム要素名を<code>is</code>属性に指定します。JavaScriptからインスタンスを生成する場合は、コンストラクタを<code>new</code>するか、<code>document.registerElement()</code>の第二引数にカスタム要素名を指定してください。</p>

<p></p><pre class="crayon-plain-tag">&lt;button is="my-element"&gt;My Element&lt;/button&gt;

&lt;script&gt;
  console.log(new MyElement() instanceof HTMLButtonElement);
  // =&gt; true
  console.log(document.createElement('button', 'my-element') instanceof HTMLButtonElement);
  // =&gt; true
&lt;/script&gt;</pre><p></p>

<h3>ライフサイクルコールバック</h3>

<p>カスタム要素には4つのライフサイクルが存在し、Polymerでもそれらをハンドリングできます。ライフサイクルについては<a href="https://html5experts.jp/1000ch/11142/" data-wpel-link="internal">Web Componentsを構成する4つの仕様 ー Web Components基礎編</a>という記事の「カスタム要素の挙動を設定する」をセクションにて解説しています。ブラウザネイティブでは<code>createdCallback</code>・<code>attachedCallback</code>・<code>detachedCallback</code>、<code>attributeChangedCallback</code>の4つが定義されていますが、Polymerでは<code>Callback</code>が省略されている他、<code>ready</code>というShadow Root配下のDOM構築が完了したタイミングで発火されるハンドラも定義できるようになっています。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  Polymer({
    is: 'my-element',
    created: function () {
      console.log('my-elementが生成されました');
    },
    attached: function () {
      console.log('my-elementがHTMLドキュメントに追加されました');
    },
    detached: function () {
      console.log('my-elementがHTMLドキュメントから切り離されました');
    },
    attributeChanged: function (name, type) {
      console.log('my-elementの' + name + '属性が変更されました');
    },
    ready: function () {
      console.log('my-elementのDOM構築が完了しました');
    }
  });
&lt;/script&gt;</pre><p></p>

<p>ハンドラの実行順序をまとめると以下のようになります。</p>

<ol>
<li><code>created</code>コールバック</li>
<li><code>ready</code>コールバック</li>
<li><code>factoryImpl</code>コールバック</li>
<li><code>attached</code>コールバック</li>
<li>(<code>detached</code>コールバック)</li>
</ol>

<h3><code>behaviors</code>を使った振る舞いの制御</h3>

<p>カスタム要素の振る舞いを制御するには、これまでのように<code>Polymer()</code>に直接ハンドラなどを指定するほか、<code>behaviors</code>にプロトタイプとなるようなオブジェクトを渡すことでも可能です。オブジェクトで定義できるのは先程登場したライフサイクルコールバック、後述するデフォルト属性やプロパティ、オブザーバー（<code>observer</code>）、イベントハンドラの登録（<code>listener</code>）です。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
var MyBehavior = {
  ready: function() {
    console.log('DOM is ready');
  }
};

Polymer({
  is: 'my-element',
  behaviors: [MyBehavior]
});
&lt;/script&gt;</pre><p></p>

<p>見ての通り、<code>behaviors</code>にはオブジェクトを配列で指定することが可能です。複数指定されてハンドラが重複する（例えば、複数のオブジェクトで<code>ready</code>が定義されている）場合は、配列上で後から出現するオブジェクトが優先されます（つまり右辺が優先されます）。</p>

<h2>カスタム要素のデフォルト属性</h2>

<p>カスタム要素のデフォルト属性は、引数の<code>hostAttributes</code>に定義します。<code>hostAttributes</code>に指定した属性とその値は、カスタム要素の属性のデフォルト値になります。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  var MyElement = Polymer({
    is: 'my-element',
    hostAttributes: {
      role: 'navigation'
    }
  });
&lt;/script&gt;</pre><p></p>

<p>この時 &lt;my-element&gt; は、デフォルトで &lt;my-element role=&quot;navigation&quot;&gt;&lt;/my-element&gt; として評価されます。</p>

<h2>カスタム要素のプロパティ</h2>

<p>カスタム要素のプロパティは、引数の<code>properties</code>に定義します。プロパティ名をキーに、<code>type</code>や<code>value</code>などの属性を渡すことでプロパティの特徴を定義します。簡略化された形としては、<code>propertyName: type</code>という指定も可能です</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  Polymer({
    is: 'my-element',
    properties: {
      foo: {
        type: Number,
        value: 0,
        observer: 'fooChanged'
      }
      bar: {
        type: String,
        computed: 'computeBar(foo)'
      }
    }
    fooChanged: function(newValue, oldValue) {
      // ...
    },
    computeBar: function(foo) {
      return String(foo + 100);
    }
  });
&lt;/script&gt;</pre><p></p>

<p>ここでは<code>foo</code>と<code>bar</code>の2つを<code>my-element</code>のプロパティとして定義していますが、それぞれ<code>observer</code>と<code>computed</code>という属性を渡しています。</p>

<h3>オブザーバー関数を指定する<code>observer</code></h3>

<p><code>observer</code>はプロパティの変更を監視するオブザーバー関数を指定する属性です。ここでは<code>fooChanged</code>という関数を定義しているので、関数名を文字列で渡しています。v0.5までは<code>propertyNameChanged</code>といったような命名規則を用いてオブザーバー関数を定義していましたが、v1.1においてその機能はありません。監視する関数には引数として、変更後の値（<code>newValue</code>）と変更前の値（<code>oldValue</code>）が引数と渡されるので、前後値を利用することができます。</p>

<h3>コンピュート関数を指定する<code>computed</code></h3>

<p><code>computed</code>はプロパティの値を動的に算出するための関数を指定する属性です。<code>observer</code>同様に関数名を文字列で渡しますが、ここでは<code>bar</code>プロパティに対し<code>computeBar(foo)</code>という値を渡しています。この記述によって<code>computeBar</code>関数には<code>foo</code>プロパティが引数として渡され、<code>bar</code>の値は関数が返却する値を参照します。</p>

<h3>HTML属性に反映するかどうかを指定する<code>reflectToAttribute</code></h3>

<p>プロパティの値に変更があっても通常はHTML属性に反映されませんが、<code>reflectToAttribute</code>に<code>true</code>を指定するとHTMLの属性も更新されるようになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  Polymer({
    is: 'my-element',
    properties: {
      foo: {
        type: String,
        reflectToAttribute: true
      }
    },
    ready: function() {
      this.foo = 'Hello!';
      // this.setAttribute('foo', 'Hello!');と同等の振る舞いが得られる
    }
  });
&lt;/script&gt;</pre><p></p>

<p>この時、<code>ready</code>の関数が実行されたタイミングで &lt;my-element&gt;&lt;/my-element&gt; は &lt;my-element foo=&quot;Hello!&quot;&gt;&lt;/my-element&gt; となり、<code>setAttribute('foo', 'Hello!')</code>を実行したときと同様の振る舞いが得られます。</p>

<h2>イベントハンドラの登録</h2>

<p>v0.5以前まではイベントハンドラの登録をブラケットを使って宣言的に定義していましたが、v1.1からはブラケットを使わなくなった他、<code>listeners</code>プロパティにイベントとそのハンドラをハッシュ形式で定義が可能です。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    &lt;button on-click="clickHandler"&gt;Button&lt;/button&gt;
  &lt;/template&gt;

  &lt;script&gt;
    var MyElement = Polymer({
      is: 'my-element',
      listeners: {
        'tap': 'myElementTapHandler'
      },
      clickHandler: function(e, detail) {
        // button click handler
      },
      myElementTapHandler: function(e, detail) {
        // my-element tap handler
      }
    });
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<h3>ジェスチャーイベントのハンドリング</h3>

<p>先程のサンプルで<code>tap</code>というDOMネイティブには存在しないイベントに対して<code>myElementTapHandler</code>というハンドラを登録していますが、Polymerは自前で実装するにはやや面倒な4つのイベントをサポートしています。</p>

<ul>
<li><code>down</code>: マウスや指によって要素が押下された時</li>
<li><code>up</code>: マウスや指が押下後に離された時</li>
<li><code>tap</code>: <code>down</code>と<code>up</code>が連続して発生した時</li>
<li><code>track</code>: マウスや指が押下されたまま移動した時</li>
</ul>

<p>それぞれのイベントのハンドラに渡されるイベント引数の<code>detail</code>プロパティには様々な付加情報が渡されます。詳しくは<a href="https://www.polymer-project.org/1.0/docs/devguide/events.html#gestures" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">公式ドキュメント</a>を確認してください。</p>

<h3>カスタムイベントの発火</h3>

<p><code>fire</code>という関数を実行することで、ホスト要素を呼び出し元オブジェクトとしてカスタムイベントを発行することが出来ます。引数にはカスタムイベント名と、ハンドラの<code>detail</code>プロパティに渡すデータを指定します。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    &lt;button on-click="clickHandler"&gt;Button&lt;/button&gt;
  &lt;/template&gt;

  &lt;script&gt;
    var MyElement = Polymer({
      is: 'my-element',
      clickHandler: function(e, detail) {
        this.fire('foo', {
          bar: 100
        });
      }
    });
  &lt;/script&gt;

&lt;/dom-module&gt;

&lt;my-element&gt;&lt;/my-element&gt;

&lt;script&gt;
  var myElement = document.querySelector('my-element');
  myElement.addEventListener('foo', function(e) {
    console.log(e.detail.bar);
    // =&gt; 100
  });
&lt;/script&gt;</pre><p></p>

<p>ここでは &lt;my-element&gt; のボタンをクリックした時に<code>foo</code>というカスタムイベントを発行し、付加データとして<code>{ bar: 100 }</code>という値を渡しています。</p>

<h2>データバインディング</h2>

<p>データバインディングは以前と同様にカーリーブラケット<code>{{}}</code>およびスクエアブラケット<code>[[]]</code>で指定します。ブラケットではプロパティおよびコンピュート関数を評価することが可能で、v0.5まで有効だった演算子などはサポートされていません。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    &lt;input value="{{foo}}" type="text"&gt;
    &lt;input value="[[bar]]" type="text"&gt;
  &lt;/template&gt;

  &lt;script&gt;
    Polymer({
      is: 'my-element',
      properties: {
        foo: String,
        bar: Number
      }
    });
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<p>ここでは&lt;my-element&gt;のプロパティとして定義している<code>foo</code>や<code>bar</code>を、 &lt;input&gt; の<code>value</code>にバインディングしています。これによって<code>foo</code>や<code>bar</code>の値に変更があると、&lt;input&gt;に自動で反映されます。</p>

<h3>カーリーブラケット<code>{{}}</code>とスクエアブラケット<code>[[]]</code></h3>

<p>カーリーブラケット<code>{{}}</code>とスクエアブラケット<code>[[]]</code>の差は、データバインディングの方向が一方向に制限されるかどうかの違いです。<code>{{}}</code>のデータバインディングは双方向か一方向かが記述によって変わりますが、<code>[[]]</code>は一方向のみであり参照しているプロパティを受け取るのみです。</p>

<p>カーリーブラケット<code>{{}}</code>で指定した際にバインディングの振る舞いを決定するのは、プロパティの<code>notify</code>フラグと<code>readOnly</code>フラグです。</p>

<p></p><pre class="crayon-plain-tag">&lt;script&gt;
  Polymer({
    is: 'my-element',
    properties: {
      foo: {
        type: String,
        notify: true
      },
      bar: {
        type: Number,
        readOnly: true
      }
    }
  });
&lt;/script&gt;</pre><p></p>

<p><code>notify</code>フラグはプロパティの変更をホスト要素に通知するかどうか、<code>readOnly</code>フラグはプロパティが読み取り専用かどうかを決定します。この例では<code>notify: true</code>なので、 &lt;my-element foo=&quot;{{value}}&quot;&gt;&lt;/my-element&gt; としたときに<code>foo</code>に変更があると<code>value</code>へ値が反映されます。</p>

<h3>ネイティブ要素との双方向データバインディング</h3>

<p>ネイティブ要素との双方向データバインディングも <strong>target-prop=&quot;{{hostProp::target-change-event}}&quot;</strong> という構文でサポートしています。ここでは&lt;input&gt;に入力された値に括弧を付与して&lt;div&gt;に埋め込んでいます。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    &lt;input value="{{foo::input}}" type="text"&gt;
    &lt;div&gt;{{computeBar(foo)}}&lt;/div&gt;
  &lt;/template&gt;

  &lt;script&gt;
    Polymer({
      is: 'my-element',
      properties: {
        foo: {
          type: String
        }
      },
      computeBar: function(foo) {
        return `「${foo}」`;
      }
    });
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<p>入力された値を参照するタイミングは<code>input</code>イベントで、バインドするホストプロパティは<code>foo</code>なので、 <strong>input value=&quot;{{foo::input}}&quot;&gt;</strong> になります。これによって、ネイティブ要素のプロパティからカスタム要素へのプロパティへのデータバインディングが行われます。</p>

<h3>属性とのデータバインディング</h3>

<p>属性に対してデータをバインディングするには以下のように<code>$=</code>を使い、ブラケット<code>{{}}</code>にはこれまでと同様にカスタム要素のプロパティやコンピュート関数を記述します。</p>

<p></p><pre class="crayon-plain-tag">&lt;template&gt;
  
  &lt;!-- Attribute binding --&gt;
  &lt;my-element selected$="{{value}}"&gt;&lt;/my-element&gt;
  &lt;!-- results in &lt;my-element&gt;.setAttribute('selected', this.value); --&gt;

  &lt;!-- Property binding --&gt;
  &lt;my-element selected="{{value}}"&gt;&lt;/my-element&gt;
  &lt;!-- results in &lt;my-element&gt;.selected = this.value; --&gt;
  
&lt;/template&gt;</pre><p></p>

<p>プロパティとのデータバインディングには &lt;my-element foo={{value}}&gt; と記述することで<code>document.querySelector('my-element').foo = value</code>を振る舞いますが、HTMLの属性にバインディングするためには &lt;my-element foo$={{value}}&gt; のように<code>$=</code>で指定することで <code>document.querySelector('my-element').setAttribute('foo', value)</code> が動的に実行されます。</p>

<p>ネイティブの属性である<code>class</code>や<code>style</code>には、次のように<code>$=</code>でバインディングすることが可能です。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- class --&gt;
&lt;div class$="{{foo}}"&gt;&lt;/div&gt;

&lt;!-- style --&gt;
&lt;div style$="{{background}}"&gt;&lt;/div&gt;

&lt;!-- href --&gt;
&lt;a href$="{{url}}"&gt;

&lt;!-- label for --&gt;
&lt;label for$="{{bar}}"&gt;&lt;/label&gt;

&lt;!-- dataset --&gt;
&lt;div data-bar$="{{baz}}"&gt;&lt;/div&gt;</pre><p></p>

<p>HTML上の属性名とDOMのプロパティ名が異なる場合には留意が必要でしょう。data-*の場合、<code>data-foo</code>への実際のプロパティは<code>element.dataset.foo</code>となるため、<code>data-foo={{bar}}</code>ではバインディングできず、<code>element.setAttribute('data-foo', bar)</code>となる<code>data-foo$={{bar}}</code>を使う必要があります。</p>

<h3>Templateのリピート</h3>

<p>配列のデータは &lt;template is=&quot;dom-repeat&quot;&gt; を使ってリピートし、要素ひとつひとつを参照することが出来ます。以下は<code>is="dom-repeat"</code>を使って配列を展開しているサンプルです（公式より引用）。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="employee-list"&gt;

  &lt;template&gt;
    &lt;div&gt; Employee list: &lt;/div&gt;
    &lt;template is="dom-repeat" items="{{employees}}"&gt;
      &lt;div&gt;# &lt;span&gt;{{index}}&lt;/span&gt;&lt;/div&gt;
      &lt;div&gt;First name: &lt;span&gt;{{item.first}}&lt;/span&gt;&lt;/div&gt;
      &lt;div&gt;Last name: &lt;span&gt;{{item.last}}&lt;/span&gt;&lt;/div&gt;
    &lt;/template&gt;
  &lt;/template&gt;

  &lt;script&gt;
    Polymer({
      is: 'employee-list',
      ready: function() {
        this.employees = [
          {first: 'Bob', last: 'Smith'},
          {first: 'Sally', last: 'Johnson'}
        ];
      }
    });
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<p>&lt;template is=&quot;dom-repeat&quot;&gt; に加えて展開したい配列を<code>items</code>属性で指定します。配列の要素の数だけ &lt;template &gt; の内部が繰り返されますが、この中では要素を表す<code>item</code>と配列のインデックスを示す<code>index</code>という二つの変数を参照できます。</p>

<p><code>items</code>で参照している配列に変更を加える場合には、インスタンスの関数をそのまま使うのではなくPolymerのインスタンスが備えている専用の関数を使います。例えばこのサンプルの<code>employees</code>に値を追加する場合は、 <code>this.employees.push({...})</code>ではなく<code>this.push('employees', {...})</code>とする必要があります。<code>push</code>の他には<code>pop</code>、<code>splice</code>、<code>shift</code>、<code>unshift</code>も同様です。これらの関数を使わないと、配列への変更が検知されずに再描画されません。</p>

<p>Polymerのデータバインディングの更なる詳細については<a href="https://www.polymer-project.org/1.0/docs/devguide/data-binding.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Data binding &#8211; Polymer 1.0</a>を参照してください。</p>

<h2>Polymer内部で行うDOM操作</h2>

<p>&lt;dom-module&gt;内部のDOMの操作を行う場合は、Shadow RootのDOM APIではなく専用のインターフェースが用意されています。</p>

<h3>IDが与えられている要素の参照</h3>

<p>要素に対してIDが与えられていると、<code>this.$.id</code>という形で自動的に参照が生成されます。これはv0.5まで存在していた機能なので、馴染みのある人もいるかと思います。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    This is my-element &lt;span id="foo"&gt;&lt;/span&gt;!
  &lt;/template&gt;

  &lt;script&gt;
    Polymer({
      is: 'my-element',
      ready: function() {
        this.$.foo.textContent = this.foo;
      }
    });
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<p>また、動的に生成された要素を参照する場合は<code>this.$$(selector)</code>という関数が用意されています。これにCSSセレクタを渡すと、セレクタにマッチする最初の要素が返却されます。</p>

<h3><code>Polymer.dom()</code>を使ったDOM操作</h3>

<p>Polymer内部のDOM操作を行う場合は、Shadow Root配下の要素のDOM APIを直接実行するのではなく、<code>Polymer.dom()</code>という専用のAPIが用意されています。<code>Polymer.dom()</code>の引数にはNodeを渡し、返却されるオブジェクトには、ネイティブのDOM APIと同等の振る舞いをするAPIが用意されています。いずれもDOMのAPIと同じ命名と引数で設計されていますが、サブセットとして用意されているに過ぎず、完全に互換性があるわけではないことに注意してください。</p>

<h4>親子関係</h4>

<ul>
<li><code>Polymer.dom(parent).childNodes</code></li>
<li><code>Polymer.dom(node).parentNode</code></li>
<li><code>Polymer.dom(node).firstChild</code></li>
<li><code>Polymer.dom(node).lastChild</code></li>
<li><code>Polymer.dom(node).firstElementChild</code></li>
<li><code>Polymer.dom(node).lastElementChild</code></li>
<li><code>Polymer.dom(node).previousSibling</code></li>
<li><code>Polymer.dom(node).nextSibling</code></li>
<li><code>Polymer.dom(node).textContent</code></li>
<li><code>Polymer.dom(node).innerHTML</code></li>
</ul>

<h4>クエリ</h4>

<ul>
<li><code>Polymer.dom(parent).querySelector(selector)</code></li>
<li><code>Polymer.dom(parent).querySelectorAll(selector)</code></li>
</ul>

<h4>コンテンツの参照</h4>

<ul>
<li><code>Polymer.dom(contentElement).getDistributedNodes()</code></li>
<li><code>Polymer.dom(node).getDestinationInsertionPoints()</code></li>
</ul>

<h4>属性の操作</h4>

<ul>
<li><code>Polymer.dom(node).setAttribute(attribute, value)</code></li>
<li><code>Polymer.dom(node).removeAttribute(attribute)</code></li>
<li><code>Polymer.dom(node).classList</code></li>
</ul>

<p><code>Polymer.dom</code>から行う追加や削除といったDOM操作は、パフォーマンスを考慮し遅延して実行するようになっています。そのため、操作後のノードの座標やgetComputedStyle()を使ったスタイルの取得をする場合は、操作を<code>Polymer.dom.flush()</code>を使って適時実行し、反映します。</p>

<h2>カスタム要素のスタイリング</h2>

<p>CSSのスタイリングは、これまでと同様にShadow DOMをスタイリングする記法が適用されます。PolymerはShadow DOMの実装状況で振るまいが変わらないように、Shady DOMという軽量なポリフィルを採用しているため、CSSセレクタをネイティブと同様に書くことはできません。</p>

<p>例えば、&lt;content&gt;を参照する<code>::content</code>セレクタです。Shadow DOMがブラウザネイティブに実装されていれば単一でも評価されるはずですが、Shady DOMの互換性として<code>::content</code>セレクタには何らかの親セレクタを指定する必要があります。これは <strong>::content .bar</strong> と記述された場合にShady DOMで実現しているスコープを再現できなくなるためです。この場合、 <strong>.foo &gt; ::content .bar</strong> と書く必要があり、実際には <strong>.foo &gt; .bar</strong> のように評価されます。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;

  &lt;template&gt;
    &lt;style&gt;
      :host {
        display: block;
        border: 1px solid red;
      }
      .foo &gt; ::content .bar {
        background: orange;
      }
    &lt;/style&gt;

    &lt;div class="foo"&gt;&lt;content&gt;&lt;/content&gt;&lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
    Polymer({
      is: 'my-element'
    });
  &lt;/script&gt;

&lt;/dom-module&gt;</pre><p></p>

<h2>まとめ</h2>

<p>Polymer v1.1の主な機能について解説しました。v0.5 → v0.8 → v0.9 → v1.0&#8230;とAPIに多くの変更が加えられてきましたが、メジャーリリースになったことで、これまでのような大きな変更は（ <strong>おそらく</strong> ）なくなるでしょう。</p>

<p>最後に、今年9月の14日〜15日にオランダのアムステルダムにて開催された<a href="https://www.polymer-project.org/summit" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer Summit 2015</a>にて、参考リソースが多く公開されたのでそれを紹介します。</p>

<h3>Polymer Codelabs</h3>

<p><a href="http://www.code-labs.io/polymer-summit" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer Codelabs</a>は、Polymerを使ったアプリケーションを作成していくチュートリアル集です。Polymer Summitに合わせて11個のチュートリアルが公開されています。こちらも英語ですが、環境のセットアップから丁寧に解説されています。</p>

<h3>セッション動画リスト</h3>

<p>Polymer Summit 2015の各セッションはすべて以下のチャンネルで配信されていますので、興味のある方は是非チェックしてみてください。</p>


<!-- iframe plugin v.4.3 wordpress.org/plugins/iframe/ -->
<iframe width="560" height="315" src="https://www.youtube.com/embed/jVn8tlnwAEs?list=PLNYkxOF6rcICdISJclfQhj2S8QZGjXV8J" frameborder="0" 0="allowfullscreen" scrolling="yes" class="iframe-class"></iframe>

]]></content:encoded>
		
		<series:name><![CDATA[基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜]]></series:name>
	</item>
		<item>
		<title>Polymer 1.0最新情報！（後編）ーGoogle I/O Web Appの作り方、Polymer Starter Kitで始めるMaterial Design、etc.</title>
		<link>/ryoyakawai/15883/</link>
		<pubDate>Wed, 01 Jul 2015 00:00:39 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google I/O]]></category>
		<category><![CDATA[Polymer]]></category>

		<guid isPermaLink="false">/?p=15883</guid>
		<description><![CDATA[連載： Google I/O 2015 特集 (6) 本記事は、「Polymer 1.0最新情報」の後編になります（前編はこちらから）。Google I/OでPolymer 1.0が取り上げられた「Polymer and...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google_io_2015/" class="series-313" title="Google I/O 2015 特集" data-wpel-link="internal">Google I/O 2015 特集</a> (6)</div><p><style>.post-detail-contents p{text-indent:0; overflow:hidden}</style></p>

<p>本記事は、「Polymer 1.0最新情報」の後編になります（前編は<a href="https://html5experts.jp/ryoyakawai/15885/" target="_blank" data-wpel-link="internal">こちら</a>から）。Google I/OでPolymer 1.0が取り上げられた「Polymer and modern web APIs: In production at Google scale」のセッションをレポートします。Polymerの最新情報や活用事例、Polymer Catalog、Polymer Starter Kitなど、盛りだくさんのこのセッションの翻訳と解説を前後編に分けてお伝えします。</p>

<p>後編となる本記事では、「ライブサイトへの適用例（後半）」、「Polymer Starter Kitとは」を解説します。</p>

<h2>ライブサイトへの適用例（後半）</h2>

<p>前編に引き続き、Polymerのライブサイトへの適用例の後半です。コードを交えながら具体的に解説していきます。</p>

<h3>Google I/O Web App</h3>

<p>このアプリは社内ではIOWA（アイオワ）と呼んでいる。IOWAはModen Web Platformでの良い実装例で、デスクトップでもモバイルでも動作して、コンテンツが最初に読込まれるときマテリアルデザインのエフェクトと共に表示され、ページとコンテントの間の表示での大きなエフェクトついているし、デスクトップでもモバイルでもビデオをクリックすると全画面になる。Webアプリでここまでネイティブアプリ感が出せている。</p>

<p>そのIOWAには想像できる新しいWeb APIのほとんど全てが使われている。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-22-at-11.09.12-PM.png" alt="NewAPIs_IOWA" width="640" height="357" class="alignnone size-full wp-image-15600" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-22-at-11.09.12-PM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-22-at-11.09.12-PM-300x167.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-22-at-11.09.12-PM-207x115.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>使っているAPIたち</figcaption>
</figure></p>

<p>ここからIOWAのポイントは以下です。</p>

<ul>
<li><strong>バックエンド</strong>：広範囲に渡ってAppEngine上でGoを使用</li>
<li><strong>Material Designの実装に関して</strong>：Web Animation、Promiseで各種エフェクトを実現</li>
<li><strong>開発したチーム</strong>：ソフトウェア エンジニアではなく、Developer Relationsチーム</li>
<li><strong>ツール</strong>：誰でも使うことのできる3rdパーティ製のツールを使い、Googleの特別なツールは使っていない</li>
</ul>

<p>ここから実装方法に関しての説明になります。</p>

<h4>Templateを使ったSPA（シングル・ページ・アプリケーション）の実現</h4>

<p>Google Santa Tracker 2014ではURLルーティングを行うことでSPAを実現していましたが、IOWAではTemplateとHTML Importsを使って動的にコンテンツを読み込でいるそうです。</p>

<ol>
<li>異なるid属性を付けた複数のTemplateを1つのページに配置</li>
<li>ref属性を持ったTemplateタグを配置</li>
<li>ref属性に予め埋め込んだTemplateのidどれかを指定</li>
</ol>

<p>すると、指定したidのTemplateのコンテンツがTemplateの中に差し込まれます。IOWAは予め複数ファイルでページをTemplateとして用意して、必要に応じてそれらのファイルを動的に読み込む（HTML Imports）ことでSPAが実現されている、とのことでした。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Untitled1.gif" alt="template" width="640" height="357" class="alignnone size-full wp-image-15618" />
<figcaption>TemplateとHTML Importsを使った動的なコンテンツを読み込み</figcaption>
</figure></p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-12.53.20-AM.png" alt="import_Pomyler1.0" width="640" height="358" class="alignnone size-full wp-image-15622" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-12.53.20-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-12.53.20-AM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-12.53.20-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Polymer 1.0でTemplateとHTML Importsを使ったSPAを実現させるコード</figcaption>
</figure></p>

<h4>Material Designの実現</h4>

<p>ビデオ等は遅延ゼロの理想状態でMaterial Desginの動きは説明されているが、Webアプリではそうはいかないので工夫が必要です。IOWAではWeb Animation、Promiseを使い、ロジカルなアニメーションのシーケンスを作ることで実現しているそうです。</p>

<ol>
<li>Promiseが&#8221;page-transition-start&#8221;のEventを発行し、ページトップ部分の色を変更するのと同時にコンテンツをページ表示領域から外側にスライドしフェードアウトさせる</li>
<li>Import Page Method（TemplateとHTML Importを使ったSPA実現方法）を使ってページのコンテンツをAjaxで取得する</li>
<li>コンテンツの準備が完了したら、ページ全体のアニメーションを実行する。このアニメーションは基本的にコンテンツを200ms以下の時間でページにスライドさせていて、パララックスのエフェクトもかけている</li>
<li>動的なページ読み込みとアニメーションが完了した時点で、例えばJavaScriptの実行のようなページを構成するために必要な処理が実行できるようになる</li>
</ol>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-1.02.04-AM.png" alt="webanimation_promises" width="640" height="358" class="alignnone size-full wp-image-15626" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-1.02.04-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-1.02.04-AM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-1.02.04-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Material Designを実現しているAnimation flowのコード</figcaption>
</figure></p>

<p>このように、PromiseとWeb Animation APIをWrapして利用することでCSSのアニメーションが動いたり、ネットワーク接続が発生したりと非同期な処理が起こっている状態でも、ロジカルな同期が可能です。</p>

<h4>オフライン ファーストの実現</h4>

<p>IOWAで注目すべき機能で、Service Workersを使って実現している。Service WorkersのおかげでWeb開発者が実現できることの代表例は以下です。</p>

<ul>
<li>ページキャッシュ</li>
<li>プッシュ通知（Push Notification）</li>
<li>バックグラウンド・シンク</li>
<li>ネットワークリクエストの横取り</li>
</ul>

<p>IOWAではこれらの機能を使い、アクセス解析を行うGoogle Analyticsへのリクエストをオンライン時はリアルタイムに、オフライン時は横取りをして一旦IndexDBに蓄積。オンラインになった段階で再現をしてオフライン時のアクセス解析を可能にしています。一般的にも、こうすることで重要なインサイトを逃さず見ることができるでしょう。</p>

<h4>オフライン時の動作の実装で注意した点</h4>

<p>Webサイトがオフラインでも動作することはユーザは体験したことがないので、例えばオフラインになったときにアプリケーションを終了されてしまうことを防いだりします。またオフライン動作することに驚かれないために、IOWAでは「オンラインからオフライン」に遷移した時にアプリケーション側で何が起こっているかユーザが把握できるよう、トースト（自動的に消える小さなお知らせエリア）で状態を知らせることができるように注意して実装してます。</p>

<p>実際に以下のリストのような事象が起こった場合にトーストを出しています。</p>

<ul>
<li><strong>初回アクセス時</strong>：次回からは最初からオフラインで動作します</li>
<li><strong>オフライン時の情報情報更新</strong>：オンラインになった時に情報をサーバに通知します</li>
</ul>

<p>オフラインとは電波（Wi-Fi、3G、4G等）の状況が悪いとき、Airplaneモード等でインターネットにつながらなくなった状態のことを指しています。</p>

<h4>プッシュ通知(Push Notifications)</h4>

<p>プッシュ通知はNativeなアプリでは当たり前になっている機能ですが、Webの世界では真新しい機能になります。もちろん、アプリが開いていない状態でも通知を受けることが可能です。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-2.12.31-AM.png" alt="pushnotification" width="640" height="337" class="alignnone size-full wp-image-15644" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-2.12.31-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-2.12.31-AM-300x158.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-2.12.31-AM-207x109.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>プッシュ通知を表示させた例</figcaption>
</figure></p>

<p>プッシュ通知も新しい機能なので、オフライン時の動作と同じく状況をトーストで通知しています。このプッシュ通知を動作させるためには、ユーザが通知を受ける/受けないを選択することに加えて、通知を受け取る許可をユーザがブラウザに対して行う必要があります。</p>

<p>プッシュ通知を行う目的はWebサイト/アプリへの再訪にあります。IOWAではその効果測定のためにプッシュ通知からどれだけユーザが実際にサイト/アプリに再訪してくれたかをAnalyticsを利用して計測しています。</p>

<p>プッシュ通知の送信は一見難しそうですが、Elementがあるので心配しないでください。実際にはこのような形で実装することができます。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Untitled2.gif" alt="PushNotification" width="640" height="358" class="alignnone size-full wp-image-15725" />
<figcaption>プッシュ通知の送信</figcaption>
</figure></p>

<p>プッシュ通知を使う目的はWebサイト/アプリへの再訪です。なのでIOWAではプッシュ通知からどれだけユーザが実際にサイト/アプリに再訪してくれたかの計測をAnalytics利用して行っています。</p>

<p>ここまでお話してきた、オフライン動作の実現、Service Workers、プッシュ通知に関してもElementが存在していて、Platinum Elementsに実装しています。</p>

<p><a href="https://elements.polymer-project.org/browse?package=platinum-elements" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：Platinum Elements（英語）</a></p></p>

<p>最後に「6ヶ月の出来事のお話しだったので、駆け足の説明で盛りだくさんになってしまった。紹介した2つはライブサイトも動作しているし、ソースコードも公開しているので、詳しくはそちらをご覧ください」と結びました。</p>

<p>(Speaker: Eric Bidelman)</p>

<p>リンク：Google I/O web app <a href="https://html5experts.jp//events.google.com/io2015" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[ライブサイト]</a> <a href="https://html5experts.jp//github.com/GoogleChrome/ioweb2015/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[コード]</a></p>

<h2>Polymer Starter Kitとは</h2>

<p>「PolymerのDeveloper Toolを担当しているAddy Osmaniです」と自己紹介から始まりました。</p>

<p>そして間髪入れず、最近の出来事からの例えを交えて「物事の筋道にはステップを踏まないと思い通りのモノは作れない」ということの説明が始まりました。</p>

<p>Addyの友達に赤ちゃんが生まれたそうで、赤ちゃんのスケッチしてプレゼントしようと考えたそうです。そしてスケッチ方法をGoogle.comで検索をすると「まずは丸を書くことが最初のステップ（Step1）」という結果だったそうです。「実現可能性を確信したけど、次のステップを探した結果がStep2でした。このStep1からStep2への飛躍は非常に大きく、これを目標に続けると最終的にはStep1.5のようになることも少なくない」と続きます。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Untitled3.gif" alt="draw_baby" width="640" height="358" class="alignnone size-full wp-image-15738" />
<figcaption>赤ちゃんの顔のスケッチ：Step1、Step2、Step1.5</figcaption>
</figure></p>

<p>Polymerはまさに例に挙げたStep1からStep2へ移行しようとしている段階なので、これを避けるべくPolymer Teamは「Polymer Starter Kit」で、この状況の回避を行うとのこと。「Polymer Starter Kit」は、過去1年間でPolymerを使ったプロジェクトGoogle I/O App、Web Starter Kit、Google Santa Trackerを見返して、そこから得られた知見を1つにまとめた結果です。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-12.16.13-AM.png" alt="PolymerStarterKit" width="640" height="315" class="alignnone size-full wp-image-15744" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-12.16.13-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-12.16.13-AM-300x148.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-12.16.13-AM-207x102.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Polymer Starter Kit</figcaption>
</figure></p>

<p>ここから「Polymer Starter Kitがどのようなものなのか？」の説明に入ります。</p>

<h3>Material Design</h3>

<p>非常に高いレベルでMaterial Designをサポートしています。Toolbar，Header-Panelのようなモバイルアプリを開発するときに必ず必要になるパーツ、URLルーティングや複数の画面サイズにフィットするような仕組みもサポートしている。CSS Custom Propertyを使って、アプリ全体のテーマカラーを数行のコードで変更する可能で、非常にパワフル。</p>

<p>モバイルWebアプリ開発ではテーマカラーの変更、クロスデバイス（Android、iOS、Windows Phone）でホーム画面へのアイコンリンクの準備も最初からできているので、再訪へとつなげられる。</p>

<h3>Adaptive UI</h3>

<p>今回のI/OでMaterial Design Teamが発表したガイドライン。これはデバイスによってインタラクションをどう作り込むのがよいのかのガイドラインですが、Polymer Starter Kitはこれらを全てを含んでいる。あくまでもこれらは1つの例でしかないので、必要に応じてカスタマイズすることも可能。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-27-at-8.07.25-PM.png" alt="adaptiveui" width="640" height="358" class="alignnone size-full wp-image-15980" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-27-at-8.07.25-PM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-27-at-8.07.25-PM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-27-at-8.07.25-PM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Adaptive UI</figcaption>
</figure>
<a href="http://www.google.com/design/spec/layout/adaptive-ui.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：Adaptive UI（英語）</a></p>

<h3>App Template</h3>

<p>Navigation Card Layout、住所録のようなアプリに最適なNavigation List Detail Layout、List Card Over Layout(Wider Card View Layout)などが用意されていて、すぐに利用できるLayoutのセットとなっている。</p>

<h3>Offline-first (in your app)</h3>

<p>Ericもオフラインの重要性を訴えた通りで、またRob Dodsonも「2015年は、もしアプリがオフラインをサポートしていないのであれば、それは本当の意味でのモバイルWebエクスピリエンスを提供できていない、という考え方が現実になるだろう」と言っています。良いことにPolymer Starter Kitはデフォルトでオフライン ファーストになっているので何の設定をすることもなくAirplaneモードや、オフラインになったときにもアプリに含まれる全てのページにアクセスすることが可能。</p>

<h3>Service Workers</h3>

<p>素晴らしい機能だけど、導入するには多くの設定が必要です。ですが、</p>

<p>&gt; There is an element for that!</p>

<p>で、Polymer CatalogにあるPlatinum Elementsを使えば、Service Workersを使ったキャッシュ機能を簡単に実装することができます。</p>

<p>Service Workersのセット・アップの例です。Service Workersの登録し、キャッシュのストラテジを数行で設定している。例では「Network First」をキャッシュのストラテジとして、キャッシュしたいファイル名を予め宣言しています。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.15.19-AM.png" alt="Platinum Element" width="640" height="358" class="alignnone size-full wp-image-15754" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.15.19-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.15.19-AM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.15.19-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Plutinum Elementsを使ったオフラインキャッシュのコード</figcaption>
</figure>
<a href="https://elements.polymer-project.org/browse?package=platinum-elements" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：Platinum Elements（英語）</a></p>

<h3>Production-ising Cache</h3>

<p>ユーザにできるだけ小さく、できるだけ速いアプリを提供するという意味ではビルドプロセスはとても重要。Polymer TeamはストリーミングビルドシステムのGulpが大好きなので、Polymer　Starter Kitに採用している。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.27.47-AM.png" alt="BuildByGulp" width="640" height="360" class="alignnone size-full wp-image-15757" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.27.47-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.27.47-AM-300x169.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.27.47-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Gulpを使ったビルドシステム</figcaption>
</figure></p>

<p>web-component-testerなどのクオリティテスト、Vulcanize等のミニフィケーション等が可能。Browser Syncを使っているので、アプリに変更を加えるとその変更はクロスデバイスで伝搬され（クリック/タップ、スクロールも含む）全てのデバイスで一度に確認することも可能。</p>

<p>実際に「Polymer Starter Kit」を適応して「Paper Reader」という名のRSSリーダアプリを作ったお話は変わります。</p>

<p>使った技術の一覧で、これらの1つ1つにElementが存在しています。</p>

<ul>
<li>記事をGoogle Feedから取得（RSS、Atom、Media RSS feedに対応）</li>
<li>既読/未読の管理にはFirebaseを利用</li>
<li>オフラインでの動作</li>
<li>新着のプッシュ通知</li>
</ul>

<p>まとめると、Polymer Starter Kitは大きく分けて、以下の4つを含んでいる。</p>

<ul>
<li>Components</li>
<li>Layout</li>
<li>Theming</li>
<li>Build tools</li>
</ul>

<p>「これらのElementやPolymer Starter Kitを使って、何を作るかはあなた次第です」</p>

<p>と最後に結び、Matthew McNultyに戻ります。</p>

<p>(Speaker: Addy Osmani)</p>

<p><a href="https://html5experts.jp//developers.google.com/web/tools/polymer-starter-kit/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：Polymer Starter Kit（英語）</a></p>

<h2>まとめ</h2>

<p>ここ2年間で、Polymerが約束をして実現したことは以下の通り。</p>

<ul>
<li>Web Components</li>
<li>Interoperability</li>
<li>宣言的な書き方ができること</li>
</ul>

<p>ChromeではWeb Componentsがリリースされて1年、またProductionに耐えられるPolymer 1.0がリリースされた。</p>

<p>Salesforde、Vaadin、Atabistなどの3rdパーティも、PolymerをProduction用に使っている。Google Santa Tracker、Google I/O web appはオフラインで動作します、Polymer Starter Kitも今日から使えるし、今後は1.0には入れられなかった新しい機能、Elementを早いペースで次々に追加する予定です。</p>

<p>Polymerについての情報の取得等のリンクは以下。</p>

<ul>
<li>最新情報：<a href="https://html5experts.jp//polymer-project.org" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">polymer-project.org</a></li>
<li>Polymer Teamと直接会話：<a href="https://html5experts.jp//polymer-slack.herokuapp.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Slackチャンネル</a></li>
</ul>

<p>そして、Polymer単独のカンファレンスの告知がありました。</p>

<p>「2015年9月15日にアムステルダムにて、PolymerだけのカンファレンスPolymer Summitを開催します。1日中、Polymerを、また最先端のWeb開発を学びにくてください」とのことです！</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.21.54-AM.png" alt="Polymer Summit" width="640" height="359" class="alignnone size-full wp-image-15761" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.21.54-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.21.54-AM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.21.54-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Polymer Summit@アムステルダム 2015/09/15</figcaption>
</figure></p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.26.35-AM.png" alt="PolymerTeam" width="640" height="359" class="alignnone size-full wp-image-15763" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.26.35-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.26.35-AM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.26.35-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Polymer Teamの皆さん</figcaption>
</figure></p>

<p>最後に「バグも見つけてね」でセッションは終了でした。</p>

<p>(Speaker: Matthew McNulty)</p>

<h2>あとがき</h2>

<p>個人的にはPolymerを最初に触ったのが2013年頃で、そのキッカケは楽器系のアプリを作った時に必ず使いたくなるリッチなノブ、スライダ、スイッチ、鍵盤を簡単に配置できる世界を夢見た<a href="https://github.com/g200kg/webaudio-controls" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">webaudio-controls</a>が開発され始め、それに乗っかって一緒にはじめたことでした。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/webaudio-controls.png" alt="webaudio-controls" width="350" class="alignnonewp-image-15858" srcset="/wp-content/uploads/2015/06/webaudio-controls.png 555w, /wp-content/uploads/2015/06/webaudio-controls-300x153.png 300w, /wp-content/uploads/2015/06/webaudio-controls-207x106.png 207w" sizes="(max-width: 555px) 100vw, 555px" />
<figcaption>webaudio-controls</figcaption>
</figure>
</p></p>

<p>今回のセッションに参加して、その中で何度もリピートされていた言葉、
&#8220;<q>There is an element for that!</q>&#8220;（それ、エレメントあるよ！）をwebaudio-controlsを作ってから、実際に自分自身が言っていたことに気が付きました。</p>

<p>また、ブラウザにMIDI機器を接続して遊べるWebアプリを、簡単に作ることができる世界を夢見て<a href="https://github.com/ryoyakawai/x-webmidi/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">x-webmidi</a>というElementも作りました。これを作った理由は「ゼロから書くのはちょっと…という理由で手が出しずらい、という印象を少しでも和らげたい」からでした。</p>

<p>この「手軽に使えること」だったり「ゼロから書くのはちょっと…という理由で手が出しずらい、という印象を少しでも和らげたい」という想いがさらに一般に拡がりElementが量産されたのであれば、その未来はブラウザにはよりプリミティブなAPIが実装されるようになり、ブラウザのAPIをより使いやすくする、APIを組合せることで新たな枠組みを作るためのWeb Componentsが「ブラウザのAPIとWebアプリの中間に新たなクリエイティブな層」を創り出して、Web開発がExtensible Webな時代へ突入するのかな？なんて、Webの未来をモヤモヤ考えさせられる2015年のPolymerのセッションでした。</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2015 特集]]></series:name>
	</item>
		<item>
		<title>Polymer 1.0最新情報！（前編）ーPolymer 1.0とPolymer Catalog、活用事例の徹底解説</title>
		<link>/ryoyakawai/15885/</link>
		<pubDate>Tue, 30 Jun 2015 06:00:23 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google I/O]]></category>
		<category><![CDATA[Polymer]]></category>

		<guid isPermaLink="false">/?p=15885</guid>
		<description><![CDATA[連載： Google I/O 2015 特集 (5) Polymerは、Google I/O 2015にて1.0が正式リリースとしてアナウンスされました。本記事は、Google I/OでPolymerが取り上げられた「P...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google_io_2015/" class="series-313" title="Google I/O 2015 特集" data-wpel-link="internal">Google I/O 2015 特集</a> (5)</div><p><style>.post-detail-contents p{text-indent:0; overflow:hidden}</style></p>

<p><img src="/wp-content/uploads/2015/06/POLYMER-1.0.png" alt="POLYMER 1.0" width="300" class="wp-image-15439" align="left" srcset="/wp-content/uploads/2015/06/POLYMER-1.0.png 599w, /wp-content/uploads/2015/06/POLYMER-1.0-300x209.png 300w, /wp-content/uploads/2015/06/POLYMER-1.0-207x144.png 207w" sizes="(max-width: 599px) 100vw, 599px" />
Polymerは、Google I/O 2015にて1.0が正式リリースとしてアナウンスされました。本記事は、Google I/OでPolymerが取り上げられた「Polymer and modern web APIs: In production at Google scale」のセッションをレポートします。Polymerの最新情報や活用事例、Polymer Catalog、Polymer Starter Kitなど
盛りだくさんのこのセッションの翻訳と解説を前後編に分けてお伝えします。</p>

<p>前編となる本記事では、「Polymer1.0の特徴」、「Polymer Catalogとすぐに使えるElements」、「ライブサイトへの適用例（前半）」を解説します。</p>

<h2>Polymer1.0の特徴</h2>

<p>Polymerが全体的にどう変わったのか、その特徴をまとめて説明してくれました。Polymer1.0の特徴を全て紹介しきれていないとのことですが、セッションで特に紹介されていたのは以下の通りです。</p>

<ul>
<li><strong>高速化(0.5と比較)</strong>：Chromeでは3倍、モバイルSafariでは4倍高速化した</li>
<li><strong>軽量化(0.5と比較)</strong>：以前より35％コード量減らしPolyfillも含めてgzipをすると19kb-42kb</li>
<li><strong>Shady DOMの採用</strong>：スピードを重視したShadow DOMのPolyfillで100％互換ではない</li>
<li><strong>CSS Custom プロパティ</strong>：プロパティの変更だけでテーマやスタイルの変更を可能に</li>
</ul>

<p>「PolymerはWeb標準技術であるWeb Componentsのライブラリであって、そのElementを作ることができます。なので、結果的にそれらのElementはWeb標準技術の上に作られたのと同意である。他のブラウザ上でも動作するし、AngularやReactといったFrameworkの中に一緒に共存させることもできる、というところが最大の特徴であり利点でもあります」</p>

<p>セッションでは、これらの説明をコンテナを運ぶ物流システムに例え「標準化を元に作られたコンテナ（Polymer Element）だからこそ、標準化されたボート・電車・トラックで効率的に運ぶことだってできる（ブラウザのInteroperabolity）」という形で説明をしていました。この例えは、Polymer TeamはSan Franciscoのオフィスにいて、普段の会話の中に湾を行き交う輸送船について話すことが多いことに由来しているそうです。</p>

<p>(Speaker: Matthew McNulty)</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-12.39.14-AM.png" alt="SF_Bay" width="640" height="358" class="alignnone size-full wp-image-15430" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-12.39.14-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-12.39.14-AM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-12.39.14-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>サンフランシスコ オフィスからの眺め</figcaption>
</figure></p>

<h2>Polymer Element Catalogとすぐに使えるElements</h2>

<p>ここからPolymerを使ってWebアプリを作るときのElementについて話に変わります。</p>

<p>「Polymer Teamは全ての開発者にPolymerを使って高品質なアプリを簡単に作ってもらうことを目標にしています。そして、アプリはElementによって出来が左右されるので、高品質なアプリを作るには高品位なElementが不可欠です。なのでGoogleでは高品質なElementを提供します」</p>

<p>という導入があり、続いて具体的にElementの説明です。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-11.20.41-PM.png" alt="PolymerCatalog" width="640" height="360" class="alignnone size-full wp-image-15480" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-11.20.41-PM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-11.20.41-PM-300x169.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-11.20.41-PM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Polymer Catalogに用意されているElementのセット一覧 (2015年5月末の状態)</figcaption>
</figure></p>

<p>まずは去年から公開されていたElementとして、Iron Element、Paper Elementが紹介されています。そして、新しく追加されたElementとして、Google Web Components、Platinum Elements、Gold Elementsがあります。</p>

<ul>
<li><b style="background-color:#81c784;padding:5px">Iron Element (Fe)</b><br>新しく聞こえますが、Core Elementから名称を変更しました。内容は以前と変わらずElementの基本となり、どのアプリケーションにも使うようなエレメントのセット。</li>
<li><b style="background-color:#efefef;padding:5px">Paper Element (Md)</b><br> Material DesignのリファレンスになるElementのセット。</li>
<li><b style="background-color:#64b5f6;padding:5px">Google Web Components (Go)</b><br> Google SDKとも言えるようなElementでGoogleのServiceやAPI（GCP、Drive、Map、Hangout、Calendar、Analytics、YouTube、Docs、Chrome Web Store、アドレス帳など）を利用する際に利用するElementのセット。</li>
<li><b style="background-color:#cfd8dc;padding:5px">Platinum Elements (Pt)</b><br> オフライン・キャッシング、ServiceWorkers、Push Notificationのようなとてもパワフルな機能を最も簡単に利用することのできるElementのセット。このElementを使うことで、半年前には夢だと思っていたような機能が簡単に実装可能。</li>
<li><b style="background-color:#ffbb4d;padding:5px">Gold Elements (Au)</b><br> モバイルでの高品質な決済のチェックアウト遷移を作成できるElementのセット。日付、カード番号等の自動Validationが可能。</li>
</ul>

<p>これらのうち、新しく追加された3つのElementは、Web開発者が特定の問題を解決するために用意しているものとのことです。このPolymer Catalogについては次のように説明しています。</p>

<p>「このサイトの目的は、解決したい問題がある場合は解決策を見つければいいのだけど、例えば、何かに触発されたかったり、思ったこともないようなデザインを見つけたかったり・眺めたかったり、考えたこともないようなアプリケーションを考えたいという場合もあります。この2つ「解決策を見つける」、「インスピレーションを得たい」を実現させる為に、Elementをブラウスでき、デモを動作可能で、ドキュメントも読むことができるのがPoymer Catalogです」</p>

<p><a href="https://elements.polymer-project.org/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：Polymer Catalog（英語）</a></p>

<h3>Polymerを使ってアプリを実装、公開している3rdパーティとそのアプリの紹介</h3>

<p>「Polymer TeamではWeb開発者が「実装したい」と考えるであろう機能は、&#8221;<q>There is an element for that!</q>&#8220;（それ、Elementであるよ！）
と言えるようにりたいと思っていますが、我々の以外でも同じことを想っている方々は多くいます。そこで、ここでは出版関連を行っているAtabist、Enterprise向けのJavaアプリ用のFrameworkを作っているVaadin、そしてSalesforceの3つの事例を紹介します」</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-12.51.47-AM.png" alt="3rdparty" width="640" height="361" class="alignnone size-full wp-image-15792" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-12.51.47-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-12.51.47-AM-300x169.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-12.51.47-AM-207x117.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>PolymerでElementを作り公開している3rd Partyの紹介</figcaption>
</figure></p>

<h4>Atabist</h4>

<p>出版関連を行っている会社で、Web上に本を作るPlatformをリリース。Webは音声、映像、画像、地図、ブラフを一緒に配置して1つにまとめるにはとてもよい媒体で、これらの1つ1つをPolymerのElementにして自由に配置できるようにしたのがこのPlatform。</p>

<p><a href="https://atavist.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：Atabist（英語）</a></p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-26-at-10.20.47-PM.png" alt="vaadin" width="640" height="420" class="alignnone size-full wp-image-15903" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-26-at-10.20.47-PM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-26-at-10.20.47-PM-300x197.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-26-at-10.20.47-PM-207x136.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>インタラクティブにSoundCloudをページ上に配置している例</figcaption>
</figure></p>

<h4>Vaadin</h4>

<p>Enterprise向けのアプリを書くためのFrameworkを作っている有名な会社の1つで、Front-endのComponentsはPolymer Elementを使って実装している。特に大量のデータを表示することに重きを置き開発されていて、例えば、v-gridというElementを作っていて、これを使うとアドレス帳のようなモノを表示、LazyLoading、行または列の複数選択の機能もElementを実装することができる。グラフを描くElementも作っていてタグ名を変えるだけで、グラフの種類を変更することができる。</p>

<p><a href="http://vaadin.github.io/components-examples/v-grid/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：v-grid（英語）</a></p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-26-at-10.13.22-PM.png" alt="vaadin" width="640" height="359" class="alignnone size-full wp-image-15596" />
<figcaption>アドレス帳のElementの例</figcaption>
</figure></p>

<h4>Salesforce</h4>

<p>Salesforceは彼らのPlatform上でそのデータを表示するアプリケーションを作るためのSDK、APIを公開している。このアプリケーション開発をより簡単にしたいということで、Polymer Elementでの提供を行っている。</p>

<p><a href="https://sfdc-designer.herokuapp.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ：デザイナ（英語）</a></p>

<h4>Google社内でのPolymerの実用例</h4>

<p>最後にGoogle社内でのPolymerの実用例の紹介です。Polymer Teamは「GoogleさんはLiveサイトでPolymerを使っているの？」とよく聞かれるそうですが「もちろん使っている」とのことで、そのうち3つを紹介してくれました。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/Translate.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/Translate-150x150.png" alt="Translate" width="120" height="120" class="alignleft size-thumbnail wp-image-15908" /></a>
<strong>Translate</strong>：Translation TeamはTranslateの質を上げるためにコミュニティのメンバーが参加して作り上げることのできるシステムを新しく作った。サイト全体がPaper Elementを使ったMaterial Designを採用している。このプロダクトはFront-endエンジニア2人で2～3ヶ月の開発期間で完成させることができたとのこと。Paper Elementを使っているので、開発者はどうやってMaterial Desiginを実装するかということは気にせず、アプリケーションの本質部分に集中して開発を進めらたそうです。</p>

<p><a href="https://translate.google.com/community" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ（英語）</a></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/PlayMusic.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/PlayMusic-150x150.png" alt="PlayMusic" width="120" height="120" class="alignright size-thumbnail wp-image-15905" /></a>
<strong>Play Music</strong>：Play TeamもPaper Elementを使ってMaterial Designを採用しているので、アプリケーションの本質部分に集中して開発を進めることができたとのことです。Play Musicは現在はPolymer Elementの組合せで作られていて、同じような音楽再生用WebサイトにElementを再利用することも可能です。（日本からはアクセスできません）</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/youtube_web.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/youtube_web-150x150.png" alt="youtube_web" width="120" height="120" class="alignleft size-thumbnail wp-image-15906" /></a>
<strong>YouTubeのモバイルWebサイト</strong>：多くのPolymerを使ったサイトはまだGoogle社内にしか公開されていないのですが、その中の1つ、それがYouTubeのモバイルのFront-End。これも全てがPolymer Elementで作られています。キビキビ動き、アニメーション、トランジションもついていて、とてもよいUIに仕上がっている。またビデオを画面の角にドラッグして動かすというWebでは実現が可能とは予想していなかったであろう動作も実現できている。このようにWebでもNativeのような最高の動作をPolymer Elementで作ることができる。</p>

<p>「Elementはとても素晴らしく、紹介したような素晴らしいElementを作ることができます。Polymer Teamは引続き素晴らしいElementを開発していきます。そして、コミュニティからもっと素晴らしいElementが出てくることを楽しみにしています」</p>

<p>と結び、次のライブサイトへの適用例の説明に移りました。</p>

<p>(Speaker: Taylor Savage)</p>

<h2>ライブサイトへの適用例（前半）</h2>

<p>ここからはEric Bidelmanにバトンタッチです。彼の3年間を振り返ってのお話からです。</p>

<p>Polymer Teamにいて「これはどうやってWeb Componentsで実現するの？」ということを開発者と話してきて、そこでよく質問にあがる具体例が「どうやってSPA（Single Page Application）をWeb Componentsでどう実装するのか？」、「他言語化やLazyLoad、またURLルーティングはど実現するのか？」というような「Polymerを使ってどう実現したいモノを実装するか？」という部分です。それに対してPolymer Teamはこう答えているそうです。</p>

<p>&gt; There is an element for that!</p>

<p>という掴みがあり、続いてEric Bidelmanが前回のI/Oから数多くの実験を実際に行い、Google.com上のアプリを作りそれらを公開して、実際に使えるのかを試してみた、というストーリで実例を2つ紹介してくれました。</p>

<p>「これらの事例ではPolymer1.0ではなく、ちょっと遅いけどGoogle.comで公開されているのは0.5。なんだけど、1.0と書き方が少し違うだけで本質的なPolymerの部分は同じなので、これからお話をする事例には影響は特にないのです」</p>

<p>と捕捉があって、Google Santa Tracker 2014とGoogle I/O Web Appの説明が始まります。</p>

<h3>Google Santa Tracker 2014</h3>

<p>このアプリは12月に公開されたアプリで、サンタ村を訪れることができ、12月中は毎日新しいゲームを提供したりしているAdvent Calendarのアプリ。日々提供されるゲームだったり、そのSceneのことを社内ではLaunchと呼んでいて、それらの全部がElementになっていて、Web AudioだったりWeb GLだったりを使っているものもある。クリスマスイブには今どこでサンタがプレゼントを配っているかも見ることができる。もちろんそれもElementになっている。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-20-at-8.06.39-PM.png" alt="SantaTracker" width="636" height="539" class="alignnone size-full wp-image-15586" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-20-at-8.06.39-PM.png 636w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-20-at-8.06.39-PM-300x254.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-20-at-8.06.39-PM-207x175.png 207w" sizes="(max-width: 636px) 100vw, 636px" />
<figcaption>Google Santa Tracker 2014</figcaption>
</figure></p>

<p>コード的な説明です。&lt;santa-app&gt; が全体をオーケストレーションするElementで、Google Analyticsに、また音楽の再生・停止をするEventの発火を行う。&lt;santa-app&gt; の内部にはさらにElementが入っている。URLルーティングもElementを作って対応していて、LazyLoadingのElementとを結びつけ、ユーザがSceneを選択したときにJavaScript、CSSが動的に読み込まれるような仕組みになっている。このプロジェクト全体的にElementはDeclarativeにしていて、各Sceneのプログレスバー、背景色、背景画像もそのおかげでHTMLのAttributeでの設定が可能になっている。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-10.55.33-AM1.png" alt="SantaTracker2014" width="640" height="360" class="alignnone size-full wp-image-15818" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-10.55.33-AM1.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-10.55.33-AM1-300x169.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-10.55.33-AM1-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>&lt;santa-app&gt;のElement</figcaption>
</figure>
  </li>
</ul></p>

<p>Google Santa Tracker 2014の説明は以上でした。</p>

<p>リンク：Google Santa Tracker <a href="https://html5experts.jp//santatracker.google.com" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[ライブサイト]</a> <a href="https://html5experts.jp//github.com/google/santa-tracker-web" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[コード]</a></p>

<p>（後編に続きます）</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2015 特集]]></series:name>
	</item>
		<item>
		<title>Web ComponentsのこれからーPolymer 0.8、X-Tag、Brick、Bosonic</title>
		<link>/1000ch/14400/</link>
		<pubDate>Thu, 07 May 2015 00:00:38 +0000</pubDate>
		<dc:creator><![CDATA[泉水翔吾]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Polymer]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=14400</guid>
		<description><![CDATA[連載： 基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜 (5)この記事は、連載「基礎からわかるWeb Components徹底解説～仕様から実装まで理解する〜」の第5回目になります。...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/web-components-2/" class="series-214" title="基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜" data-wpel-link="internal">基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜</a> (5)</div><p>この記事は、連載「基礎からわかるWeb Components徹底解説～仕様から実装まで理解する〜」の第5回目になります。今回は、先日発表されたPolymer 0.8の変更点、MozillaのWeb Componentsへの関わり方やX-Tag、Brick、BosonicといったPolymer以外の周辺ライブラリについて紹介します。</p>

<h2>Polymer 0.8のリリース</h2>

<p>先日、Polymerのバージョン0.8がリリースされました。</p>

<ul>
<li><a href="https://blog.polymer-project.org/updates/2015/03/27/why-0.8/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">0.8 Released! &#8211; Polymer Blog</a></li>
</ul>

<p>0.8は1.0のリリースに向けたアルファリリースと位置付けられています。APIも正式版への提案として大きく変更が加えられており、これまでとの互換性も保たれていません。既に実践でPolymerを使っていて、0.8へアップデートを行う場合はこれまでのコンポーネントを作り直す必要があります。</p>

<p>アルファ版ということで、ユーザーのフィードバックや再設計を経て、さらなる変更がある可能性もありますが、より完成度の高いライブラリに近づいていくことでしょう。アップデートに伴い、どのような変更があるのかを見ていきます。</p>

<h3>ポリフィルライブラリ</h3>

<p>これまでポリフィルライブラリとして推奨されてきた<code>webcomponents.js</code>ですが、以降は<code>webcomponents-lite.js</code>が推奨されています。<code>webcomponents.js</code>と<code>webcomponents-lite.js</code>の差はShadow DOMのポリフィルを含んでいるかどうかなのですが、Polymer 0.8ではよりシンプルで軽量な <strong>shady DOM</strong> というShadow DOMのポリフィルを含んでいるためです。</p>

<ul>
<li><a href="https://github.com/webcomponents/webcomponentsjs" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">webcomponents/webcomponentsjs</a></li>
<li><a href="https://github.com/webcomponents/webcomponents-lite" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">webcomponents/webcomponents-lite</a></li>
</ul>

<p>異なる用途でShadow DOMのポリフィルを必要とする場合は別ですが、Polymerを利用するためであれば、<code>webcomponents.js</code>の重いShadow DOMのポリフィルを含まず、軽量な<code>webcomponents-lite.js</code>を選択するのが望ましいと言えます。</p>

<h3>軽量化とパフォーマンスの向上</h3>

<p>APIの大きな見直し（後述）と抜本的なリファクタリングによって、ライブラリのファイルサイズの軽量化と実行パフォーマンスの向上が図られています。以下は<a href="http://polymerlabs.github.io/benchmarks/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PolymerLabs/benchmarks</a>で試すことができるベンチマークの結果です（Polymer公式サイトより引用）。初期描画までの時間の棒グラフになっており、低ければ低いほど描画までの時間が短くパフォーマンスが良いということになります。</p>

<p><img src="/wp-content/uploads/2015/04/benchmark-640x480.png" alt="benchmark" width="640" height="480" class="alignnone size-large wp-image-14436" srcset="/wp-content/uploads/2015/04/benchmark.png 640w, /wp-content/uploads/2015/04/benchmark-300x225.png 300w, /wp-content/uploads/2015/04/benchmark-207x155.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>いくつかのデバイス・ブラウザで計測されていますが、いずれも0.5に比べて0.8が数倍高速に動作するという結果が出ています。もとよりWeb ComponentsはHTML ImportsのCustom Elementsの遅延評価されるという性質によるコンポーネントのがたつきやチラつきが問題になりがちですが、最も重要である初期描画までのパフォーマンスが向上されているのは嬉しいところです。</p>

<h2>互換性のない大きなAPIの変更</h2>

<p>冒頭で述べた通り、0.5以前と互換性はありません。</p>

<ul>
<li><a href="https://www.polymer-project.org/0.8/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">About this release &#8211; Polymer</a></li>
<li><a href="https://www.polymer-project.org/0.8/docs/migration.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Migration guide &#8211; Polymer</a></li>
</ul>

<p>リリースノートとマイグレーションガイドを元に主な変更点を見ていきます。さらなる詳細な差分については、公式ドキュメントを確認してください。</p>

<h3>カスタム要素の登録</h3>

<p>これまでは、&lt;polymer-element&gt;要素を用いてカスタム要素の登録を行ってきました。</p>

<p></p><pre class="crayon-plain-tag">&lt;polymer-element name="my-element"&gt;
  &lt;template&gt;
    &lt;style&gt;
      div { color: red; }
    &lt;/style&gt;
    &lt;div&gt;Shadow DOM in My Element&lt;/div&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer();
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p>0.8からは以下のように、&lt;dom-module&gt;を起点にした方法に変更されます。&lt;dom-module&gt;要素のIDに登録したいカスタム要素名（ここでは<code>my-element</code>）を指定し、<code>Polymer</code>コンストラクタでそのIDを参照しています。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="my-element"&gt;
  &lt;style&gt;
    div { color: red; }
  &lt;/style&gt;
  &lt;template&gt;
    &lt;div&gt;Shadow DOM in My Element&lt;/div&gt;
  &lt;/template&gt;
&lt;/dom-module&gt;

&lt;script&gt;
  var MyElement = Polymer({is: 'my-element'});
&lt;/script&gt;</pre><p></p>

<p><code>Polymer({is: 'my-element'});</code>の実行より前に、&lt;dom-module&gt;がロードされている必要があります。&lt;style&gt;タグを&lt;template&gt;の外に配置するようになった点にも注意して下さい。要素の継承についても同様に<code>extends</code>キーワードで行うことができますが、0.5以前では可能であったカスタム要素の継承は廃止され、&lt;button&gt;や&lt;textarea&gt;のようなビルドインのHTML要素のみになっています。また、これまでは<code>constructor</code>属性にコンストラクタ関数名を指定していましたが、0.8では属性が廃止されるとともに<code>Polymer()</code>がカスタム要素のコンストラクタを返却するようになりました。</p>

<p><code>document.registerElement</code>の第二引数に指定する<code>extends</code>の値にもカスタム要素名を指定することはできず、コンストラクタ関数の返却も<code>document.registerElement</code>が行います。いずれも素の挙動に近い振る舞いになったと言えるでしょう。</p>

<h3>カスタム要素のパースの順序</h3>

<p>カスタム要素を含むカスタム要素を作成する場合は、内包するカスタム要素が事前に登録されている必要があります。つまり、&lt;child-element&gt;を含む&lt;parent-element&gt;を作成する場合、&lt;child-element&gt;が事前に登録されていなければなりません。</p>

<h3>デフォルト属性とプロパティの宣言</h3>

<p>カスタム要素のデフォルト属性とプロパティ宣言の方法も変わります。0.5までは以下のように、デフォルト属性は&lt;polymer-element&gt;に、プロパティの宣言は<code>attributes</code>にスペース区切りで指定していました。</p>

<p></p><pre class="crayon-plain-tag">&lt;polymer-element name="your-element" attributes="foo bar" role="button" layout horizontal wrap&gt;
  &lt;template&gt;
    &lt;button&gt;Your Element&lt;/button&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer({
      foo: 0,
      bar: 'Hello!'
    });
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p>0.8以降は以下のように、<code>Polymer()</code>コンストラクタに<code>hostAttributes</code>や<code>properties</code>を渡すことで宣言します。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="your-element"&gt;
  &lt;template&gt;
    &lt;button&gt;Your Element&lt;/button&gt;
  &lt;/template&gt;
&lt;/dom-module&gt;

&lt;script&gt;
  Polymer({
    is: 'your-element',
    hostAttributes: {
      role: 'button',
      class: 'layout horizontal wrap'
    },
    properties: {
      foo: {
        type: Number,
        value: 0
      },
      bar: {
        type: String,
        value: 'Hello!'
      }
    }
  });
&lt;/script&gt;</pre><p></p>

<p><code>layout</code>、<code>horizontal</code>、<code>wrap</code>といったようなレイアウトに関するカスタム属性も通常のCSSクラスになり、<code>hostAttributes</code>の<code>class</code>に指定します。また、このレイアウト機能はPolymerのコアから分離され<code>polymer.html</code>に同梱されなくなったので、別途<code>layout.html</code>をインポートする必要があります。</p>

<h3>オブザーバーの登録</h3>

<p>プロパティの値の監視や、宣言的なイベントハンドラ登録といった機能もPolymerの強力な機能のひとつですが、これらにも少々変更があります。</p>

<p>これまでは、<code>foo</code>というプロパティに対して<code>fooChanged</code>というオブザーバー関数を宣言すると命名規則によって自動でバインドされる機能がありました。また、IDを振った要素は<code>this.$.id</code>という形でコンストラクタ内でノードを参照することが可能であり、それを<code>observers</code>に定義することでもプロパティの監視が可能でした。</p>

<p></p><pre class="crayon-plain-tag">&lt;polymer-element name="your-element" attributes="foo"&gt;
  &lt;template&gt;
    &lt;input type="text" id="input"&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer({
      foo: 0,
      observers: {
        'this.&amp;.input.value': 'inputValueChanged'
      },
      fooChanged: function (oldValue, newValue) {
        console.log('newValue is ', newValue);
      },
      inputValueChanged: function () {
        console.log('this.&amp;.input.value is changed');
      }
    });
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p>0.8からはこの<code>propertyName</code>に対して<code>propertyNameChanged</code>という関数を定義することで自動バインドされる仕組みと、IDを振った要素が<code>this.$</code>にぶら下がる機能が廃止されます。これによってプロパティの監視を行うには、以下のように、ブラケットで囲った変数に対し、<code>observer</code>属性にオブザーバー関数を明示的に宣言することになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="your-element"&gt;
  &lt;template&gt;
    &lt;input type="text" value="{{inputValue}}"&gt;
  &lt;/template&gt;
&lt;/dom-module&gt;

&lt;script&gt;
  Polymer({
    is: 'your-element',
    properties: {
      foo: {
        type: Number,
        value: 0,
        observer: 'fooChanged'
      },
      inputValue: {
        observer: 'inputValueChanged'
      }
    },
    fooChanged: function (oldValue, newValue) {
      console.log('newValue is ', newValue);
    },
    inputValueChanged: function () {
      console.log('inputValue is changed');
    }
  });
&lt;/script&gt;</pre><p></p>

<p>暗黙的にオブザーバー関数がバインドされる分、直感的に解り難い機能であったので、このように明示的な宣言方法になるのは嬉しいところです。</p>

<h3>イベントハンドラの登録とデータバインディング</h3>

<p>ブラケット<code>{{}}</code>によるデータバインディングや、イベントハンドラの登録もPolymerお馴染みの機能ですが、これらにも少々変更があります。</p>

<p></p><pre class="crayon-plain-tag">&lt;polymer-element name="our-element"&gt;
  &lt;template&gt;
    &lt;input type="text" value="{{firstName}}"&gt;
    &lt;input type="text" value="{{lastName}}"&gt;
    &lt;button on-click="{{onClick}}"&gt;Say full name&lt;/button&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer({
      onClick: function () {
        alert("{{firstName + ' ' + lastName}}");
      }
    });
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p>0.8からは<code>{{}}</code>内の式の評価はサポートされなくなります。</p>

<p>この例で言えば、<code>"{{firstName + ' ' + lastName}}"</code>のような表現はできなくなります。代わりに<code>computed</code>を用いて、式評価後の値を参照するプロパティを宣言する必要があります。これは0.5以前とは異なり、0.8からは<code>properties</code>の配下に定義する属性になることに注意してください。</p>

<p>同じく、<code>{{}}</code>を使って<code>on-click="{{onClick}}"</code>のように定義していたイベントハンドラの登録は、カーリーブラケットを使わずに記述します。</p>

<p></p><pre class="crayon-plain-tag">&lt;dom-module id="our-element"&gt;
  &lt;template&gt;
    &lt;input type="text" value="{{firstName}}"&gt;
    &lt;input type="text" value="{{lastName}}"&gt;
    &lt;button on-click="onClick"&gt;Say full name&lt;/button&gt;
  &lt;/template&gt;
&lt;/dom-module&gt;

&lt;script&gt;
  Polymer({
    is: 'our-element',
    properties: {
      firstName: String,
      lastName: String,
      fullName: {
        type: String,
        computed: 'computeFullName(firstName, lastName)'
      }
    },
    computeFullName: function (firstName, lastName) {
      return firstName + ' ' + lastName;
    },
    onClick: function () {
      alert('{{fullName}}');
    }
  });
&lt;/script&gt;</pre><p></p>

<p>このように<code>fullName</code>に<code>computed: computeFullName(firstName, lastName)</code>とすることで<code>computeFullName</code>の実行結果を参照することが可能です。</p>

<h3>DOMの操作</h3>

<p>Polymer内でDOM操作を行う場合、通常のShadow Rootから実行するDOMのAPIではなく、<code>Polymer.dom</code>という専用のAPIを使う必要があります。</p>

<ul>
<li><code>Polymer.dom(parent).appendChild(node)</code></li>
<li><code>Polymer.dom(parent).insertBefore(node, beforeNode)</code></li>
<li><code>Polymer.dom(parent).removeChild(node)</code></li>
<li><code>Polymer.dom(parent).querySelector(selector)</code></li>
<li><code>Polymer.dom(parent).querySelectorAll(selector)</code></li>
<li><code>Polymer.dom(parent).childNodes</code></li>
<li><code>Polymer.dom(node).parentNode</code></li>
<li><code>Polymer.dom(contentElement).getDistributedNodes()</code></li>
<li><code>Polymer.dom(node).getDestinationInsertionPoints()</code></li>
</ul>

<p><code>Polymer.dom</code>から行う追加や削除といったDOM操作は、パフォーマンスを考慮し遅延して実行するようになっています。そのため、操作後のノードの座標や<code>getComputedStyle()</code>を使ったスタイルの取得をする場合は、操作を<code>Polymer.dom.flush()</code>を使って適時実行し、反映します。</p>

<p></p><pre class="crayon-plain-tag">// 従来のDOM操作
this.appendChild(node);
this.shadowRoot.appendChild(node);

// Polymer.domを使ったDOM操作
Polymer.dom(this).appendChild(node);
Polymer.dom(this.root).appendChild(node);</pre><p></p>

<p>いずれもDOMのAPIと同じ命名と引数で設計されていますが、サブセットとして用意されているに過ぎず、完全に互換性があるわけではありません。例えば、<code>firstChild</code>といったプロパティは用意されていないので、この場合は代わりに<code>childNodes[0]</code>を使ってください。</p>

<h2>MozillaのWeb Componentsへの関わり方</h2>

<p>MozillaもWeb Componentsに対し、積極的な姿勢を見せています。FirefoxでもWeb Componentsの仕様のうち、いくつかが実験的に実装され、またX-TagやBrickといったWeb Componentsをつかったコンポーネント作成を後押しするライブラリもリリースしています。</p>

<h3>X-Tag</h3>

<p><a href="https://github.com/x-tag" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">X-Tag</a>はWeb Componentsの作成をサポートするライブラリです。<code>webcomponents.js</code>をポリフィルとし、記述の簡略化や一元化いったライブラリとしての目的もPolymerと似ている部分がありますが、Polymerに比べて多くのブラウザをサポートしているという特徴があります。X-Tagのブラウザターゲットは以下の通りです。</p>

<ul>
<li>Firefox 5+ desktop &amp; mobile</li>
<li>Chrome 4+, Android 2.1+</li>
<li>Safari 4+ desktop &amp; mobile</li>
<li>Internet Explorer 9+</li>
<li>Opera 11+ desktop &amp; mobile</li>
</ul>

<p>以下は公式ドキュメント引用のX-Tagを使ったカスタム要素作成のコード例です。Polymerほど多機能ではない分、シンプルで全体像を把握しやすいかもしれません。</p>

<p></p><pre class="crayon-plain-tag">xtag.register('x-accordion', {
  // extend existing elements
  extends: 'div',
  lifecycle:{
    created: function(){
      // fired once at the time a component
      // is initially created or parsed
    },
    inserted: function(){
      // fired each time a component
      // is inserted into the DOM
    },
    removed: function(){
      // fired each time an element
      // is removed from DOM
    },
    attributeChanged: function(){
      // fired when attributes are set
    }
  },
  events: {
    'click:delegate(x-toggler)': function(){
      // activate a clicked toggler
    }
  },
  accessors: {
    'togglers': {
      get: function(){
        // return all toggler children
      },
      set: function(value){
        // set the toggler children
      }
    }
  },
  methods: {
    nextToggler: function(){
      // activate the next toggler
    },
    previousToggler: function(){
      // activate the previous toggler
    }
  }
});</pre><p></p>

<h3>Brick</h3>

<p>X-Tagだけでなく、UIコンポーネント群として配布しているのが<a href="http://mozbrick.github.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Brick</a>です。PolymerとX-Tagとの関係になぞらえるなら、BrickはCore ElementsやPaper Elementsと同じような存在と言えます。以前まではX-Tagが使われていましたが、現在は非依存になっています。</p>

<p>BrickもPolymerの対抗馬として注目されていましたが、開発が中断されているのか、最近は更新がない状態です。参照しているポリフィルライブラリも<code>webcomponents.js</code>ではなく、旧称の<code>platform.js</code>になっているので、利用する場合は注意してください。</p>

<h3>Web Componentsの各仕様へのMozillaの対応</h3>

<p>2014年12月の記事ですが、MozillaのWeb Componentsに対する興味深い記事が公開されました。</p>

<ul>
<li><a href="https://hacks.mozilla.org/2014/12/mozilla-and-web-components/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Mozilla and Web Components: Update</a></li>
</ul>

<p>記事には、端的に述べると <strong>「Custom ElementsとShadow DOMの実装は進め、HTML Importsの実装は見送ります。差し当たって、HTML Importsの機能はJavaScriptのライブラリでやってください。」</strong> とあります。HTML Importsが実装されないことについての議論がコメント欄にて行われていますが、この記事の筆者である<a href="https://annevankesteren.nl/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Anne van Kesteren</a>は以下のように述べています。</p>

<p>&gt; Both ES6 modules and service workers open up resource dependency management to web developers. And while ES6 modules is mostly intended for JavaScript, we want to see what kind of dependency systems will be built on these two systems in libraries and frameworks before committing to a standardized design. Especially before committing to one that is not influenced by them. <strong>（ES6 modulesやService Workersも依存関係の解決に関わってくる。ES6 modulesはJavaScript向けのものだし、ライブラリやフレームワークにとってどのような機構になるかを見たい）</strong></p>

<p>依存管理の仕組みが、HTML ImportsとES6 modules、Service Workerのような、Web WorkersのimportScriptsといった方法が複数存在してしまうことを懸念してのことと察します。例えばHTML ImportsとES6 modulesは目的を共有するものではないはずですが、HTML ImportsでロードするHTML内でES6 modulesが使われるようなケースも加味して、様子を見たいということでしょう。</p>

<h2>Bosonic</h2>

<p>BosonicもPolymerやX-Tag同様に、Web Componentsの作成を支援するライブラリです。</p>

<ul>
<li><a href="http://bosonic.github.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Bosonic Web Component</a></li>
<li><a href="https://github.com/bosonic/bosonic" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">bosonic/bosonic &#8211; GitHub</a></li>
</ul>

<p>PolymerやX-Tagと異なるのは、これらのようにライブラリとして機能を補完したりするのではなく、作成したWeb ComponentsをBosonicを使って事前にビルドするトランスパイラであるという点です。Bosonicでビルドすることで、Internet ExplorerやSafariを含めたWeb Componentsに関するAPIが実装されていないブラウザでも機能するコードが生成されます。</p>

<p>Bosonicはブラウザターゲットは以下の通りです。</p>

<ul>
<li>Internet Explorer 9, 10, 11</li>
<li>Safari 8</li>
<li>Android 4.4</li>
<li>iOS 8.1</li>
<li>Chrome 35</li>
<li>Firefox 30</li>
</ul>

<h3>Bosonicで生成するコード例</h3>

<p>以下は公式で例示されている&lt;b-hello-world&gt;というWeb ComponentsをBosonicを使ってビルドする例です。</p>

<p></p><pre class="crayon-plain-tag">&lt;element name="b-hello-world"&gt;
  &lt;style&gt;
    :host {
      text-align: center;
      font-weight: bold;
      color: red;
    }
  &lt;/style&gt;
  &lt;template&gt;
    &lt;p&gt;Hello world!&lt;/p&gt;
  &lt;/template&gt;
  &lt;script&gt;
    ({
      createdCallback: function() {
        var root = this.createShadowRoot();
        root.appendChild(this.template.content.cloneNode(true));
      }
    });
  &lt;/script&gt;
&lt;/element&gt;</pre><p></p>

<p>Bosonicを使ってコンパイルすると、以下の様なCSSとJavaScriptのコードが出力されます。</p>

<p></p><pre class="crayon-plain-tag">b-hello-world {
  text-align: center;
  font-weight: bold;
  color: red;
}</pre><p></p>

<p></p><pre class="crayon-plain-tag">(function () {
  var BHelloWorldPrototype = Object.create(HTMLElement.prototype, {
    createdCallback: {
      enumerable: true,
      value: function () {
        var root = this.createShadowRoot();
        root.appendChild(this.template.content.cloneNode(true));
      }
    }
  });
  window.BHelloWorld = document.registerElement('b-hello-world', { prototype: BHelloWorldPrototype });
  Object.defineProperty(BHelloWorld.prototype, '_super', {
    enumerable: false,
    writable: false,
    configurable: false,
    value: HTMLElement.prototype
  });
  Object.defineProperty(BHelloWorldPrototype, 'template', {
    get: function () {
      var fragment = document.createDocumentFragment();
      var div = fragment.appendChild(document.createElement('div'));
      div.innerHTML = ' &lt;p&gt;Hello world!&lt;/p&gt; ';
      while (child = div.firstChild) {
        fragment.insertBefore(child, div);
      }
      fragment.removeChild(div);
      return { content: fragment };
    }
  });
}());</pre><p></p>

<p>これらのファイルと、いくつかのポリフィル（HTMLImports、MutationObservers、WeakMap、Custom Elements）をHTMLでロードすることで、非対応のブラウザでも&lt;b-hello-world&gt;を使うことができます。</p>

<h3>トランスパイラとして導入するメリット</h3>

<p>新しいAPIで書かれたコードを、非対応のブラウザ向けに従来のAPIで実行できるようにするというのは、ES6を<a href="https://babeljs.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Babel</a>でES5に変換するというアプローチと同様です。新しい技術の導入は常にブラウザサポートと天秤にかかり、サポートを優先するが故に新しい技術を試すことができないというジレンマも多いでしょう。しかし、こういったトランスパイラによって、新しい技術の導入と古いブラウザのサポートが、コストをかけずに両立できるのは非常に嬉しいところなのではないでしょうか。</p>

<p>&lt;element&gt;タグを使った古い記述であったり、リポジトリの更新もしばらくされていないなど、使うには少々抵抗があります。しかし、トランスパイラというアプローチは非常に興味深いものがありますので、メンテナンスが再開されるのを期待したいところです。</p>

<h2>まとめ</h2>

<p>Polymer 0.8のアップデート、X-Tag・Brick・Bosonic、およびFirefoxの実装状況について紹介しました。</p>

<p>ブラウザの実装状況は、Internet Explorer・Safariが未だに思わしくありません。仕様についても、FirefoxがHTML Importsの実装を遅らせたようにまだ確実とはいえない状況です。しかしこれは議論が行われている表れでもあり、Polymerの0.8がリリースされたことも含めて、Web Componentsに関する技術は普及に向けて着実に前進しているといえます。</p>

<p>しかし、Shadow DOMによってCSSやJSがカプセル化されても、今度はコンポーネント化のアプローチについて頭を悩ませることになるでしょう。Web Componentsが一般化するには仕様の安定やブラウザのサポートだけではなく、我々開発者でナレッジを蓄積していくことが最も重要です。</p>
]]></content:encoded>
		
		<series:name><![CDATA[基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜]]></series:name>
	</item>
		<item>
		<title>基本的な要素・機能を提供するCore ElementsとMaterial Designを実現するPaper Elements</title>
		<link>/1000ch/12477/</link>
		<pubDate>Thu, 12 Feb 2015 04:00:00 +0000</pubDate>
		<dc:creator><![CDATA[泉水翔吾]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Material Design]]></category>
		<category><![CDATA[Polymer]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=12477</guid>
		<description><![CDATA[連載： 基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜 (4)この記事は、連載「基礎からわかるWeb Components徹底解説～仕様から実装まで理解する〜」の第4回目になります。...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/web-components-2/" class="series-214" title="基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜" data-wpel-link="internal">基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜</a> (4)</div><p>この記事は、連載「<a href="https://html5experts.jp/series/web-components-2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">基礎からわかるWeb Components徹底解説～仕様から実装まで理解する〜</a>」の第4回目になります。今回は、前回紹介したGoogleが開発するWeb Componentsのライブラリ、Polymerを元に作られたコンポーネント群「Core Elements」と「Paper Elements」について紹介します。</p>

<h2>Core ElementsとPaper Elements</h2>

<p>Core ElementsとPaper ElementsはGoogleが開発するWeb Components群です。Core Elementsは、Webを構成する要素をWeb Componentsとして切り出し抽象化したものであり、Paper Elementsはデザインコンセプト<a href="http://www.google.com/design/spec/material-design/introduction.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Material Design</a>をWebで実現します。</p>

<p>いずれもPolymerをベースに作られている他、各コンポーネントが異なるコンポーネントに依存したつくりになっているものもあります。アーカイブファイルの配布もされていますが、<a href="http://bower.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Bower</a>であればインストール時に依存関係は自動で解決されるため、意識する必要はありません。</p>

<h2>インストールして実際に利用する例</h2>

<p>Core Elementsのひとつである<a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-image" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-image</code></a>というコンポーネントを、Bowerを使ってインストールし、実際に使う例を以下に示します。<code>core-image</code>は通常の<code>img</code>タグにはない、画像のリサイズやプリロードといった機能を備えたWeb Componentsです。</p>

<p>まず、コマンドラインからBowerを使って<code>core-image</code>をインストールします。<code>bower.json</code>に依存情報を記録する場合は<code>--save</code>オプションを付けます。</p>

<p></p><pre class="crayon-plain-tag">$ bower install Polymer/core-image</pre><p></p>

<p>実行後は、デフォルトであれば<code>bower_components</code>フォルダ配下に<code>core-image</code>と、<code>core-image</code>が依存するサブリソースがダウンロードされています。<code>core-image</code>が依存するのはPolymer Coreのみですが、Polymer Coreが依存するリソースがさらに存在するので、それらもダウンロードされています。</p>

<p>ダウンロードした<code>core-image.html</code>をHTML内でロードすることで、<code>core-image</code>要素を使えるようになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;html&gt;
  &lt;head&gt;
    &lt;link rel="import" href="bower_components/core-image/core-image.html"&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;core-image src="http://lorempixel.com/400/400"&gt;&lt;/core-image&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre><p></p>

<p>サンプルでは、ダウンロードされたPolymer Coreを参照していませんが、ロードしているcore-image.htmlの中でPolymer Coreのインポートが行われているため、改めてPolymer Coreを読み込む必要はありません。</p>

<p>Polymerチームは、依存管理にBowerを使うことを推奨しています。自身でWeb Componentsを作成し、公開する場合は依存するリソースを<code>bower.json</code>に書き、コンポーネント内のサブリソースへの参照も、Bowerが使われることを意識するとよいでしょう。</p>

<h2>基本的な要素・機能を提供するCore Elements</h2>

<p>Core Elementsは、ユーザーインターフェースの基礎です。よく使われるけどブラウザネイティブには提供されていない機能や、Polymerの強力な機能との橋渡しとなるコンポーネントを提供します。後述のPaper Elementsの土台になっているように、拡張前提のコンポーネントも多くあります。</p>

<ul>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer core elements</a> Polymer公式サイトのCore Elementsのページ</li>
<li><a href="http://www.polymer-project.org/components/core-elements/demo.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Core Elements Sampler</a> Core Elementsのサンプル集</li>
</ul>

<h3>UI関連のCore Elements</h3>

<p>UIに関するCore Elementsとしては、既存のHTMLでは提供されていないドロップダウンやオーバーレイといった汎用的なUIや、既存のUIの機能を補完しているコンポーネントが用意されています。</p>

<p>例えば、<a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-dropdown" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-dropdown-menu</code></a>を使ったドロップダウンが挙げられます。ドロップダウンのUIは今や当たり前のように見かけますが、要件が出る度にイチから実装していたケースも多いのではないでしょうか。</p>

<p>以下は、<code>core-dropdown-menu</code>と<code>core-menu</code>及び<code>core-item</code>を組み合わせて実装するドロップダウンメニューの例（公式サイトから引用）です。</p>

<p></p><pre class="crayon-plain-tag">&lt;core-dropdown-menu label="Choose a pastry"&gt;
  &lt;core-dropdown class="dropdown"&gt;
    &lt;core-selector&gt;
      &lt;core-item label="Croissant"&gt;&lt;/core-item&gt;
      &lt;core-item label="Donut"&gt;&lt;/core-item&gt;
      &lt;core-item label="Financier"&gt;&lt;/core-item&gt;
      &lt;core-item label="Madeleine"&gt;&lt;/core-item&gt;
    &lt;/core-selector&gt;
  &lt;/core-dropdown&gt;
&lt;/core-dropdown-menu&gt;</pre><p></p>

<p>他にも以下のようなインターフェースが切り出されています。</p>

<ul>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-collapse" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-collapse</a> 折りたたみコンテンツ</li>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-drag-drop" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-drag-drop</a> ドラッグアンドドロップ</li>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-menu" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-menu</a> メニューアイテム</li>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-overlay" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-overlay</a> 他のコンテンツに覆いかぶさるオーバーレイ</li>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-tooltip" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-tooltip</a> ホバー時に表示されるツールチップ</li>
</ul>

<p>機能を補完している例としては、<a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-input" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-input</code></a>があります。</p>

<p><code>core-input</code>は<code>is="core-input"</code>のように、ネイティブHTMLの拡張として利用します。拡張されたinput要素は、<code>aria-label</code>や<code>aria-disabled</code>といった<a href="https://developer.mozilla.org/ja/docs/Web/Accessibility/ARIA" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ARIA</a>で定義されるアクセシビリティを自動で保管したり、フォームとしてサブミットされた時の値を<code>committedValue</code>として取得できるようになります。</p>

<p>他には前述の<code>core-image</code>も、後者に該当すると言えるでしょう。</p>

<h3>アニメーション関連のCore Elements</h3>

<p>Core ElementsにはUIパーツだけでなく、アニメーションを抽象化したコンポーネント群があります。その中核を成すのが<a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-animation" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-animation</code></a>です。</p>

<p><code>core-animation</code>でアニメーションを定義し、<code>core-animation-keyframe</code>と<code>core-animation-prop</code>でアニメーションの具体的な挙動を指定します。以下は<code>core-animation</code>要素でアニメーションを定義する例（公式サイトから引用）です。</p>

<p></p><pre class="crayon-plain-tag">&lt;core-animation id="fadeout" duration="500"&gt;
  &lt;core-animation-keyframe&gt;
    &lt;core-animation-prop name="opacity" value="1"&gt;&lt;/core-animation-prop&gt;
  &lt;/core-animation-keyframe&gt;
  &lt;core-animation-keyframe&gt;
    &lt;core-animation-prop name="opacity" value="0"&gt;&lt;/core-animation-prop&gt;
  &lt;/core-animation-keyframe&gt;
&lt;/core-animation&gt;

&lt;div id="el"&gt;Fade me out&lt;/div&gt;

&lt;script&gt;
  var animation = document.getElementById('fadeout');
  animation.target = document.getElementById('el');
  animation.play();
&lt;/script&gt;</pre><p></p>

<p>ここではキーフレーム毎に透過度を変化させ、フェードアウトのアニメーションを宣言しています。そして、アニメーションさせたい要素を、<code>core-animation</code>の<code>target</code>属性に指定することでフェードアウトさせてます。これはJavaScriptのコードで命令的に行っています。</p>

<p>複数のアニメーションを組み合わせて使いたい場合は、<a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-animation-group" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-animation-group</code></a>というグルーピングを担うコンポーネントもあります。</p>

<h3>ブラウザAPI関連のCore Elements</h3>

<p>提供しているのは、汎用的なアイコンやユーザーインターフェースといったビジュアルに関わる部分に限りません。Core ElementsではAjaxやキーボードアクションのハンドリング等、見た目には直接関わらない機能もWeb Componentsとして抽象化しています。</p>

<ul>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-a11y-keys" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-a11y-keys</a> キー押下のハンドリング</li>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-ajax" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-ajax</a> Ajaxの定義及びハンドリング</li>
<li><a href="https://www.polymer-project.org/docs/elements/core-elements.html#core-localstorage" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">core-localstorage</a> ローカルストレージへのアクセス</li>
</ul>

<p>今まではJavaScriptからそれぞれのAPIを実行し制御していた機能ですが、これらによって、他の要素との連携がPolymerが提供するデータバインディング機能などで容易になる他、HTMLに記述することで宣言的に挙動を定義していくことが可能になります。</p>

<p>以下はデータバインディングを利用して<code>input</code>要素に入力した値をローカルストレージに保存する例です。</p>

<p></p><pre class="crayon-plain-tag">&lt;input type="text" value="{{value}}"&gt;
&lt;core-localstorage name="localstorage-key" value="{{value}}"&gt;&lt;/core-localstorage&gt;</pre><p></p>

<p><code>core-localstorage</code>の<code>value</code>属性の値がローカルストレージに保存されるので、<code>input</code>の<code>value</code>とバインドすることで入力値がそのまま保存されるようになります。今まではイチからJavaScriptで制御していたことを考えれば、よりわかりやすく、そしてグッと楽になっています。</p>

<h2>Material Designを実現するPaper Elements</h2>

<p>Paper ElementsはMaterial DesignをWebで実現するWeb Components群です。Polymer Coreへ依存している他、Core Elementsをベースに構成されているコンポーネントが多くを占めています。</p>

<p><img src="/wp-content/uploads/2015/02/paper-ripple.png" alt="paper-ripple" width="1136" height="885" class="alignnone size-full wp-image-12496" srcset="/wp-content/uploads/2015/02/paper-ripple.png 640w, /wp-content/uploads/2015/02/paper-ripple-300x233.png 300w, /wp-content/uploads/2015/02/paper-ripple-1024x797.png 1024w, /wp-content/uploads/2015/02/paper-ripple-207x161.png 207w" sizes="(max-width: 1136px) 100vw, 1136px" /></p>

<p>Material Designについては、<a href="https://html5experts.jp/ahomu/9307/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">話題のMaterial DesignをWebで実現！Polymerで「Paper Elements」を試そう</a>という記事を一読するとよいでしょう。</p>

<ul>
<li><a href="https://www.polymer-project.org/docs/elements/paper-elements.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer paper elements</a> Polymer公式サイトのPaper Elementsのページ</li>
<li><a href="http://www.polymer-project.org/components/paper-elements/demo.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Paper Elements Sampler</a> Paper Elementsのサンプル集</li>
</ul>

<h3>UI関連のPaper Elements</h3>

<p>UI関連のPaper Elementsとしては、Core ElementsのUIコンポーネントにMaterial Designを取り入れた要素が多くあります。これは要素の一覧を見比べてもらうとわかるかと思います。</p>

<p>以下は<a href="https://www.polymer-project.org/docs/elements/paper-elements.html#paper-dropdown-menu" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>paper-dropdown-menu</code></a>の利用例です。</p>

<p></p><pre class="crayon-plain-tag">&lt;paper-dropdown-menu label="Your favorite pastry"&gt;
  &lt;paper-dropdown class="dropdown"&gt;
    &lt;core-menu class="menu"&gt;
      &lt;paper-item&gt;Croissant&lt;/paper-item&gt;
      &lt;paper-item&gt;Donut&lt;/paper-item&gt;
      &lt;paper-item&gt;Financier&lt;/paper-item&gt;
      &lt;paper-item&gt;Madeleine&lt;/paper-item&gt;
    &lt;/core-menu&gt;
  &lt;/paper-dropdown&gt;
&lt;/paper-dropdown-menu&gt;</pre><p></p>

<p>このように、利用方法もほぼ同じです。Paper Elementsとして独自に拡張しているのは、影やエフェクトのdurationなどのMaterial Designの表現に関わる部分だけとも捉えられます。</p>

<h3>Material Designを体現するエフェクト</h3>

<p>影の動きや波紋のようなインタラクションや、奥行きを表現するZ座標のルールといった、特徴的なMaterial Designのコンセプトを担うのは、以下のコンポーネントです。</p>

<ul>
<li><a href="https://www.polymer-project.org/docs/elements/paper-elements.html#paper-ripple" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">paper-ripple</a> クリックした位置から波紋が広がるエフェクト</li>
<li><a href="https://www.polymer-project.org/docs/elements/paper-elements.html#paper-spinner" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">paper-spinner</a> 円状のスピナー</li>
<li><a href="https://www.polymer-project.org/docs/elements/paper-elements.html#paper-shadow" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">paper-shadow</a> 紙で持ち上げられ影がついたようなエフェクト</li>
</ul>

<p>特に<code>paper-ripple</code>と<code>paper-shadow</code>はMaterial Designのコンセプトの中核を担っており、Paper Elementsのほとんどが、この2つのいずれかに（あるいは両方に）依存したコンポーネントになっています。</p>

<h2>paper-shadowを利用する例</h2>

<p>実際に<code>paper-shadow</code>を取り入れてみます。以下は<code>paper-shadow</code>を使わずにレイアウトしています。</p>

<p><img src="/wp-content/uploads/2015/02/lp-without-shadow-1024x797.png" alt="lp-without-shadow" width="1024" height="797" class="alignnone size-large wp-image-12559" srcset="/wp-content/uploads/2015/02/lp-without-shadow-1024x797.png 1024w, /wp-content/uploads/2015/02/lp-without-shadow-300x233.png 300w, /wp-content/uploads/2015/02/lp-without-shadow-207x161.png 207w, /wp-content/uploads/2015/02/lp-without-shadow.png 640w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>

<p><code>paper-shadow</code>を使うには、冒頭で解説したようにBowerを使ってインストールして、影を付けたい要素を<code>paper-shadow</code>タグで囲むだけです。</p>

<p></p><pre class="crayon-plain-tag">&lt;paper-shadow z="2"&gt;
  &lt;core-selector id="theme-selector" selected="default"&gt;
    &lt;paper-item name="arta"&gt;Arta&lt;/paper-item&gt;
    &lt;paper-item name="ascetic"&gt;Ascetic&lt;/paper-item&gt;
    &lt;paper-item name="color-brewer"&gt;Color Brewer&lt;/paper-item&gt;
    &lt;paper-item name="docco"&gt;Docco&lt;/paper-item&gt;
    ...
  &lt;/core-selector&gt;
&lt;/paper-shadow&gt;</pre><p></p>

<p>このコードの場合は<code>core-selector</code>を囲っていますが、Core Elementsである必要はありません。<code>div</code>でも<code>section</code>でも大丈夫です。適用すると以下のようになります。</p>

<p><img src="/wp-content/uploads/2015/02/lp-with-shadow-1024x797.png" alt="lp-with-shadow" width="1024" height="797" class="alignnone size-large wp-image-12560" srcset="/wp-content/uploads/2015/02/lp-with-shadow-1024x797.png 1024w, /wp-content/uploads/2015/02/lp-with-shadow-300x233.png 300w, /wp-content/uploads/2015/02/lp-with-shadow-207x161.png 207w, /wp-content/uploads/2015/02/lp-with-shadow.png 640w" sizes="(max-width: 1024px) 100vw, 1024px" /></p>

<p><a href="http://1000ch.github.io/syntax-highlight" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">サンプルページ</a>では、簡単ではありますが他のPaper Elementsも使っています。Paper Elementsを取り入れる例としては、<a href="https://html5experts.jp/girlie_mac/12359/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PolymerでMaterial Designなチャットアプリを作ろう</a>という記事に、より実践的なチュートリアルがあります。</p>

<h2>Polymer Designer</h2>

<p>Core ElementsやPaper Elementsを試す手段として<a href="http://polymer-designer.appspot.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer Designer</a>があります。</p>

<p><img src="/wp-content/uploads/2015/02/polymer-designer.png" alt="polymer-designer" width="1136" height="885" class="alignnone size-full wp-image-12478" srcset="/wp-content/uploads/2015/02/polymer-designer.png 640w, /wp-content/uploads/2015/02/polymer-designer-300x233.png 300w, /wp-content/uploads/2015/02/polymer-designer-1024x797.png 1024w, /wp-content/uploads/2015/02/polymer-designer-207x161.png 207w" sizes="(max-width: 1136px) 100vw, 1136px" /></p>

<p>Polymer Designerではブラウザ上で、Core ElementsやPaper Elementsをドラッグアンドドロップで配置し、データバインディング等もGUI上で行いコンポーネントを作成することが可能なツールです。Web上でお手軽に試したい場合には、こちらを使うのもよいでしょう。</p>

<p>使い方については<a href="https://html5experts.jp/1000ch/8906/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Componentsが変えるWeb開発の未来</a>という記事で触れています。</p>

<h2>おわりに</h2>

<p>Core ElementsとPaper Elementsの概要・使い方について紹介しました。Web Componentsを使ってWebページの基礎を組み立てるならCore Elementsは便利ですし、Material DesignをWebに取り入れるには、Paper Elementsが既にデファクトスタンダードと言えるかもしれません。</p>

<p>使う分にはもちろん便利なCore ElementsとPaper Elementsですが、興味があればGitHubで公開されているソースコードを見てみることをオススメします。どういった設計でどのように抽象化しているかを見るのも、今後Web Componentsを自分で作っていく上できっと参考になるはずです。</p>
]]></content:encoded>
		
		<series:name><![CDATA[基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜]]></series:name>
	</item>
		<item>
		<title>PolymerでMaterial Designなチャットアプリを作ろう</title>
		<link>/girlie_mac/12359/</link>
		<pubDate>Tue, 27 Jan 2015 01:29:37 +0000</pubDate>
		<dc:creator><![CDATA[Tomomi Imura]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Polymer]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=12359</guid>
		<description><![CDATA[今年注目のオープンWebテクノロジーのひとつに、Web Componentsが挙げられると思います。HTML5Experts.jpでも今まで幾度も関連記事、Polymer.jsについての記事が紹介されてきました。今回は実...]]></description>
				<content:encoded><![CDATA[<p>今年注目のオープンWebテクノロジーのひとつに、Web Componentsが挙げられると思います。HTML5Experts.jpでも今まで幾度も関連記事、Polymer.jsについての記事が紹介されてきました。今回は実際に、PolymerとMaterial Designのデザインコンセプトを用いて、視覚的にもユーザエクスペリエンスにも優れたチャットアプリを実際に作ってみましょう。</p>

<p><img src="/wp-content/uploads/2015/01/paper-chat-cover.png" alt="Material Design and Polymer" width="1360" height="600" class="aligncenter size-full wp-image-12358" srcset="/wp-content/uploads/2015/01/paper-chat-cover.png 640w, /wp-content/uploads/2015/01/paper-chat-cover-300x132.png 300w, /wp-content/uploads/2015/01/paper-chat-cover-1024x451.png 1024w, /wp-content/uploads/2015/01/paper-chat-cover-207x91.png 207w" sizes="(max-width: 1360px) 100vw, 1360px" /></p>

<p>まず始める前にこのライブデモ、<a href="http://pubnub.github.io/paper-chat/index.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Kitteh Anonymous</a>をデスクトップまたはモバイルのモダンブラウザで実際に試してみてください。ここでは、このデモの簡略版である<a href="http://pubnub.github.io/paper-chat/lite.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Liteバージョン</a>を実際に作成する方法をステップ・バイ・ステップで紹介したいと思います。</p>

<h3>必要な知識</h3>

<ul>
    <li><a href="https://www.polymer-project.org/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Polymer</a>の基礎知識</li>
    <li>パッケージマネージャ、<a href="https://www.polymer-project.org/docs/start/getting-the-code.html#using-bower" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Bower</a>の基本的な使い方（Polymerと依存するファイルをインストール、アップデートするのに使いますが、必ずしも使う必要はありません）</li>

</ul>

<p>泉水翔吾さんの記事、<a href="https://html5experts.jp/1000ch/11905/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Componentsを簡単・便利にするライブラリ「Polymer」を使いこなそう</a>や、佐藤歩さんの<a href="https://html5experts.jp/ahomu/9307/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">話題のMaterial DesignをWebで実現！Polymerで「Paper Elements」を試そう</a>を先に読むのをおすすめします。</p>

<h3>PolymerとWebスタンダード</h3>

<p>ちまたに数多く存在する、JavaScript UI library。<a href="https://www.polymer-project.org/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Polymer</a>も単にまたそのひとつ、と思うかもしれません。しかしPolymerが他と違うのは、これがW3C WebプラットフォームプリミティブのWeb Componentsを基礎に作られていることです。このWeb Componentsファミリーに含まれるものに</p>

<ul>
    <li><a href="http://w3c.github.io/webcomponents/spec/shadow/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Shadow DOM</a></li>
    <li><a href="http://w3c.github.io/webcomponents/spec/custom/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Custom Elements</a></li>
    <li><a href="http://w3c.github.io/webcomponents/spec/imports/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">HTML Imports</a></li>
</ul>

<p>などが挙げられます。</p>

<p>そしてPolymerに含まれる<pre class="crayon-plain-tag">webcomponents.js</pre> は W3C DOM4の<a href="http://www.w3.org/TR/dom/#mutation-observers" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">DOM mutation observers</a>や ECMAScript standardsである <pre class="crayon-plain-tag">Object.observe()</pre> のPolyfillの役目を果たしています。</p>

<h3>レゴブロックのようにWebを構築しよう</h3>

<p><img src="/wp-content/uploads/2015/01/lego.png" alt="lego" width="150" class="alignright size-full wp-image-12352" srcset="/wp-content/uploads/2015/01/lego.png 300w, /wp-content/uploads/2015/01/lego-261x300.png 261w, /wp-content/uploads/2015/01/lego-180x207.png 180w" sizes="(max-width: 300px) 100vw, 300px" />
Polymer webコンポーネントはカプセル化された何度も再利用できるコンポーネント。まるでレゴで家を構築するかのように、既存のパーツを使ったり自分で組み立てたパーツを使ったりと、いろいろなパーツを組み合わせてWebアプリを作ることができます。</p>

<p>実際にPolymerでアプリを作るには、まず必要な要素をインポートしてから使うことになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- Import element --&gt; 
&lt;link rel="import" href="paper-fab"&gt; 
... 
&lt;!-- Use element --&gt; 
&lt;paper-fab icon="send"&gt;&lt;/paper-fab&gt;</pre><p></p>

<h3>Material DesignとPolymerの関係</h3>

<p><a href="http://www.google.com/design/spec/material-design" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Material Design</a>は、既存のどのスクリーンサイズやデバイスにでも対応できる、ビジュアルとインタラクションデザインにすぐれたデザインスペックで、もともとはAndroid 5.0 Lollipop用にデザインされたものが、のちにWeb用としてPolymerのPaper Elementsとして適応されるようにました。</p>

<h2>1. Paper Elementsを使ってみよう</h2>

<p>さて実際にこれらを使って自分のアプリを作ってみましょう。 まず、Polymerをインストール、そしてアプリ構築に必要なコンポーネントをインポートします。</p>

<h3>1.1. Polymerをインストール</h3>

<p><pre class="crayon-plain-tag">$ bower install --save Polymer/polymer</pre></p>

<p>これで必要最低限のファイルがそろいます。</p>

<p><img src="/wp-content/uploads/2015/01/install-polymer.png" alt="polymer file structure" width="1032" height="443" class="aligncenter size-full wp-image-12357" srcset="/wp-content/uploads/2015/01/install-polymer.png 640w, /wp-content/uploads/2015/01/install-polymer-300x128.png 300w, /wp-content/uploads/2015/01/install-polymer-1024x439.png 1024w, /wp-content/uploads/2015/01/install-polymer-207x88.png 207w" sizes="(max-width: 1032px) 100vw, 1032px" /></p>

<p>インストールが終わったら、index.htmlの <pre class="crayon-plain-tag">&lt;head&gt;</pre> セクションに、 <pre class="crayon-plain-tag">webcomponents.min.js</pre> のみをロードさせます。</p>

<p></p><pre class="crayon-plain-tag">&lt;!DOCTYPE html&gt; 
&lt;html&gt; 
  &lt;head&gt; 
    &lt;script src="bower_components/webcomponentsjs/webcomponents.min.js"&gt;&lt;/script&gt; 
  &lt;/head&gt; 
  &lt;body&gt;
...</pre><p></p>

<h3>1.2. UI コンポーネントをインポート</h3>

<p>このデモのUIには、いくつかのPolymer CoreとPaper Elements、そして自作のカスタム要素が使われています。</p>

<ol>
    <li>core-scaffold (レスポンシブレイアウトを構成するheader、toolbar、menuなどがすでに揃った骨組み)</li>
    <li>core-item</li>
    <li>paper-input</li>
    <li>paper-fab</li>
    <li>カスタム (のちに作成しましょう)</li>
</ol>

<p><img src="/wp-content/uploads/2015/01/md-polymer-components.png" alt="polymer paper elements" width="855" height="345" class="aligncenter size-full wp-image-12356" srcset="/wp-content/uploads/2015/01/md-polymer-components.png 640w, /wp-content/uploads/2015/01/md-polymer-components-300x121.png 300w, /wp-content/uploads/2015/01/md-polymer-components-207x83.png 207w" sizes="(max-width: 855px) 100vw, 855px" /></p>

<p>Bowerを使って４つのcomponentsをインストールします。</p>

<p></p><pre class="crayon-plain-tag">$ bower install Polymer/core-scaffold 
$ bower install Polymer/core-item 
$ bower install Polymer/paper-input 
$ bower install Polymer/paper-fab</pre><p></p>

<p>インストールが終わったら、これらをHTML importsを使ってインポートします。</p>

<p></p><pre class="crayon-plain-tag">&lt;script src="bower_components/webcomponentsjs/webcomponents.min.js"&gt;&lt;/script&gt;   

&lt;link rel="import" href="bower_components/core-scaffold/core-scaffold.html"&gt; 
&lt;link rel="import" href="bower_components/core-item/core-item.html"&gt; 
&lt;link rel="import" href="bower_components/paper-input/paper-input.html"&gt; 
&lt;link rel="import" href="bower_components/paper-fab/paper-fab.html"&gt;</pre><p></p>

<p>このようにすることで、これらの要素がDOM上で使われる前に依存ファイルを含めて全てがしっかりロードされることになります。</p>

<h3>1.3. ベーシックUIの構成</h3>

<p>まず、 <pre class="crayon-plain-tag">&lt;core-scaffold&gt;</pre> を使って、ベースとなるレイアウトを構成しましょう。この要素は、レスポンシブな骨組みを簡単に作る(scaffold）ことができる便利な要素で、サブコンポーネントとして <pre class="crayon-plain-tag">&lt;core-header-panel&gt;</pre> 、 
<pre class="crayon-plain-tag">&lt;core-toolbar&gt;</pre> 
、 <pre class="crayon-plain-tag">&lt;core-drawer-panel&gt;</pre> などがすでに含まれています。</p>

<p></p><pre class="crayon-plain-tag">&lt;body fullbleed unresolved&gt;
  &lt;core-scaffold&gt;

    &lt;!-- ドロウアーパネル --&gt;
    &lt;core-header-panel navigation flex&gt;
        &lt;core-toolbar class="tall"&gt;
            &lt;!-- an avatar and username will be here --&gt;
        &lt;/core-toolbar&gt;
    &lt;/core-header-panel&gt;

    &lt;!-- アプリのタイトル --&gt;
    &lt;div tool layout horizontal flex&gt;
        &lt;span flex&gt;Kitteh Anonymous&lt;/span&gt;
        &lt;core-icon icon="account-circle"&gt;&lt;/core-icon&gt;
        &lt;span&gt;&lt;!-- number of people online --&gt;&lt;/span&gt; 
    &lt;/div&gt;

    &lt;!-- メインコンテンツ --&gt;
    &lt;div flex&gt;
            ...
    &lt;/div&gt;
  &lt;/core-scaffold&gt;
&lt;/body&gt;</pre><p></p>

<p>これでアプリのコア・ストラクチャーができました。  <pre class="crayon-plain-tag">&lt;core-scaffold&gt;</pre> は実際はこの例よりもより簡単に使うとこができるのですが、このデモでは左のドロウアー部分のヘッダの高さをかえて、ベーシックスタイルよりも少し凝ったデザインにしています。</p>

<p>ここで <pre class="crayon-plain-tag">&lt;body&gt;</pre> に見慣れない属性が使われていることにお気づきかと思います。 この <pre class="crayon-plain-tag">fullbreed</pre> はbodyをビューポートにぴったり合わせるため、 <pre class="crayon-plain-tag">unresolved</pre> はスタイライズされていないコンテンツが一瞬画面に表示される現象(FOUC)を防ぐために使われています。</p>

<p>他、要素の要所に <pre class="crayon-plain-tag">flex</pre> 属性が使われています。PolymerはCSSスタンダードのFlexboxを属性として使っており、この子要素に <pre class="crayon-plain-tag">layout horizontal | vertical</pre> が使われた時、この子要素が横または縦に、スクリーンにある分だけのスペースに引き伸ばされます。下の図を見てください。ヘッダUIのタイトル部分が引き伸ばされているため、右のアイコンと数字がきれいに右端に寄せて表示されています。</p>

<p><img src="/wp-content/uploads/2015/01/flex.png" alt="flex" width="495" height="155" class="aligncenter size-full wp-image-12355" srcset="/wp-content/uploads/2015/01/flex.png 495w, /wp-content/uploads/2015/01/flex-300x93.png 300w, /wp-content/uploads/2015/01/flex-207x64.png 207w" sizes="(max-width: 495px) 100vw, 495px" /></p>

<h3>1.4. 個々のUI Elementsを使う</h3>

<p>次に、このベースレイアウトの中に、先ほど一緒にインポートした個々のUIパーツを使います。 例えば次に示すコードサンプルでは、スクリーン横幅にあわせスタイライズされたインプットと、送信ボタンを表示しています。</p>

<p>二重カーリーブラケットに囲まれた <pre class="crayon-plain-tag">{{input}}</pre> 、 <pre class="crayon-plain-tag">{{sendMyMessage}}</pre>に注目してださい。これは式や <pre class="crayon-plain-tag">on-</pre>で始まるイベントハンドラとして使われます。次のチャプターで簡単に説明します。</p>

<p></p><pre class="crayon-plain-tag">&lt;!-- メインコンテンツ --&gt;   
&lt;div class="send-message" layout horizontal&gt;
 &lt;paper-input flex label="Type message..." id="input" value="{{input}}"&gt;&lt;/paper-input&gt;
 &lt;paper-fab icon="send" id="sendButton" on-tap="{{sendMyMessage}}"&gt;&lt;/paper-fab&gt; 
&lt;/div&gt;</pre><p></p>

<p>実際のアプリの中でコンポーネントがどのようにインポートされているかは、GitHub Repo上の<a href="https://github.com/pubnub/paper-chat/blob/gh-pages/lite.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">lite.html</a>のソースコードを見て確認してみてください。</p>

<h3>1.5. データバインディング</h3>

<p>PolymerはHTMLの新スタンダードである <pre class="crayon-plain-tag">&lt;template&gt;</pre>を使って、宣言的で双方向のデータバインディングをサポートしています。 Polymerのデータバインディングにはいくつか方法があるのですが、ここでは <pre class="crayon-plain-tag">&lt;template&gt;</pre> でアプリの全コードを囲むことによって自動バインディングを可能にしています。</p>

<p></p><pre class="crayon-plain-tag">&lt;body fullbleed unresolved&gt;
  &lt;template is="auto-binding"&gt;
    &lt;core-scaffold&gt;
      ...
    &lt;/core-scaffold&gt;
  &lt;/template&gt;
&lt;/body&gt;</pre><p></p>

<p>これで、前チャプター(1.4)で既出の<pre class="crayon-plain-tag">paper-input</pre> の例にあるように、ユーザが入力する値を<pre class="crayon-plain-tag">{{input}}</pre>を使って得ることができます。</p>

<p></p><pre class="crayon-plain-tag">var template = document.querySelector('template[is=auto-binding]');
doSomething(template.input);</pre><p></p>

<p>他、このデータモデルを使えば、要素を繰り返し使うようなマークアップを簡略化するなどということもできるのです。 実際にドロウアーパネルUIの中に、<pre class="crayon-plain-tag">core-item</pre>を使ったリストを作成してみましょう。</p>

<p></p><pre class="crayon-plain-tag">&lt;template repeat="{{item in items}}"&gt;
  &lt;core-item icon="{{item.icon}}" label="{{item.title}}"&gt;&lt;/core-item&gt;
&lt;/template&gt;</pre><p></p>

<p><pre class="crayon-plain-tag">core-item</pre>のコンテンツは、JavaScript側で、items配列を使ってオブジェクトで指定します。 ここでは、<pre class="crayon-plain-tag">&lt;core-icons&gt;</pre>で既に用意されている<a href="http://www.polymer-project.org/components/core-icons/demo.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">アイコンのセット</a>を使っています。</p>

<p></p><pre class="crayon-plain-tag">template.items = [
  {title: 'Uno', icon: 'cloud'},
  {title: 'Dos', icon: 'polymer'},
  {title: 'Tres', icon: 'favorite'}
];</pre><p></p>

<p>これで、モデルを生成・変更した時に自動的にテンプレートにインスタンスが生成され、DOM上には下の図のように表示されます。
<img src="/wp-content/uploads/2015/01/core-item.png" alt="core-item" width="257" height="186" class="aligncenter size-full wp-image-12351" srcset="/wp-content/uploads/2015/01/core-item.png 257w, /wp-content/uploads/2015/01/core-item-207x149.png 207w" sizes="(max-width: 257px) 100vw, 257px" /></p>

<h2>2. カスタム要素の作成</h2>

<p>メインUIとなる部分にチャットの会話を表示させましょう。このUIパーツには、アバター、ユーザーID、チャットのテキストが表示させるようにしたいのですが、Polymer CoreにもPaperにもそういったバーツは存在しません。ですので自分でカスタム要素を作ってみましょう。</p>

<p>まず新規のHTMLファイルを作成します。ここではこのファイル名を、<pre class="crayon-plain-tag">x-chat-list.html</pre>とします。</p>

<p>このカスタム要素は、属性、<pre class="crayon-plain-tag">avatar</pre>、<pre class="crayon-plain-tag">color</pre>、 <pre class="crayon-plain-tag">username</pre>、<pre class="crayon-plain-tag">text</pre>を扱います。</p>

<p><img src="/wp-content/uploads/2015/01/x-chat-list.png" alt="custom element" width="450" height="188" class="aligncenter size-full wp-image-12354" srcset="/wp-content/uploads/2015/01/x-chat-list.png 450w, /wp-content/uploads/2015/01/x-chat-list-300x125.png 300w, /wp-content/uploads/2015/01/x-chat-list-207x86.png 207w" sizes="(max-width: 450px) 100vw, 450px" /></p>

<p>ここでは、カスタム要素の作製法を一から説明はしませんが、簡略化されたカスタム要素は次のようになります。</p>

<p></p><pre class="crayon-plain-tag">&lt;polymer-element name="x-chat-list" attributes="avatar color username text"&gt;
  &lt;template&gt;
  &lt;section class="user-list" layout horizontal&gt;
    &lt;div class="avatar {{color}}" style="background-image: url({{avatar}})"&gt;&lt;/div&gt;
    &lt;div flex&gt;
      &lt;div class="username"&gt;{{username}}&lt;/div&gt;
      &lt;div class="text"&gt;{{text}}&lt;/div&gt;
    &lt;/div&gt;
  &lt;/section&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer('x-chat-list', { // デフォルト値を指定
      avatar: '', 
      color: '',
      username: '',
      text: ''
    });
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p>この例ではわかりやすく見せるために、 <pre class="crayon-plain-tag">&lt;style&gt;...&lt;/style&gt;</pre>部分が省略されていますが実際にUIのカスタム要素を作るにはCSSは不可欠でしょう。CSSを含む全ソースコードの<pre class="crayon-plain-tag">x-chat-list.html</pre> は<a href="https://github.com/pubnub/paper-chat/blob/gh-pages/x-chat-list.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">GitHub Repo</a>で見てください。</p>

<p>できあがったら<pre class="crayon-plain-tag">index.html</pre>に戻って、このカスタム要素をインポートします。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="import" href="x-chat-list.html"&gt;</pre><p></p>

<p></p><pre class="crayon-plain-tag">&lt;div flex class="chat-list"&gt;
  &lt;template repeat="{{message in messages}}"&gt;
    &lt;x-chat-list color="{{message.color}}" 
                 avatar="{{message.avatar}}" 
                 username="{{message.uuid}}" 
                 text="{{message.text}}"&gt;&lt;/x-chat-list&gt;
  &lt;/template&gt;
&lt;/div&gt;</pre><p></p>

<p>データは実際の生のチャットの会話を、PubNubデータ・ストリームサービスを使って表示させます。詳しくは次のセクションで説明します。</p>

<p>かなりはしょってしまいましたが、カスタム要素を作る詳しい説明は<a href="https://www.polymer-project.org/docs/start/tutorial/step-2.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">公式のドキュメント</a>を参照してください。</p>

<h2>3.PubNub Elementでメッセージの送信・受信をする</h2>

<p><img src="/wp-content/uploads/2015/01/pubnub-polymer.png" alt="pubnub-element" width="231" height="160" class="aligncenter size-full wp-image-12353" srcset="/wp-content/uploads/2015/01/pubnub-polymer.png 231w, /wp-content/uploads/2015/01/pubnub-polymer-207x143.png 207w" sizes="(max-width: 231px) 100vw, 231px" /></p>

<p>アプリのUI部分はすべて完成しましたので、今度はチャットルームそのものを作ってみましょう。データの送受信は<a href="http://pubnub.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">PubNub</a>が提供するリアルタイム・データストリームのPolymerエレメント版である、 <pre class="crayon-plain-tag">&lt;pubnub-element&gt;</pre> を使います。 今まで使った要素と違うのはこの要素にはユーザインターフェイスが伴わないことです。では何をしてくれるのかというと、要素でカプセル化されたPubNub APIがクラウドでデータのpublish / subscribeのやりとりをはたしてくれるのです。なので私たちがサーバを立てる必要はありません。</p>

<p><pre class="crayon-plain-tag">&lt;pubnub-element&gt;</pre>はサードパーティAPIを使用しますので、まず自分のAPI keysを作成しておく必要があります。 <a href="http://www.pubnub.com/get-started/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">PubNubアカウントはここから取得してください</a>。短時間試してみたいだけならば、<pre class="crayon-plain-tag">publish_key</pre>と<pre class="crayon-plain-tag">publish_key</pre>を<em>demo</em>にして使うこともできます。</p>

<h3>3.1. &lt;pubnub-element&gt;をインストール・インポート</h3>

<p>インストールは、他の要素同様にBowerを使うことができます。</p>

<p><pre class="crayon-plain-tag">$ bower install --save pubnub-polymer</pre></p>

<p>インストール後は<pre class="crayon-plain-tag">index.html</pre>でこれをインポートします。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="import" href="bower_components/pubnub-polymer/pubnub-element.html"&gt;</pre><p></p>

<h3>3.2. &lt;pubnub-element&gt;を使う</h3>

<p>まず、 <pre class="crayon-plain-tag">&lt;core-pubnub&gt;</pre>を使ってクライアントの初期化をします。</p>

<p></p><pre class="crayon-plain-tag">&lt;core-pubnub publish_key="your_pub_key" subscribe_key="your_sub_key" uuid="{{uuid}}"&gt;
&lt;/core-pubnub&gt;</pre><p></p>

<p>ここで使われる<pre class="crayon-plain-tag">uuid</pre>とはチャットルームの各ユーザのユニークIDで、ランダムな文字列を使います。このアプリでは、おのおののユーザがアクセスした時に、<em>navy-siamese</em>（濃紺色・シャム猫）のように、色と猫の種類の文字列の組み合わせで構成されたIDが与えられるようにします。</p>

<p></p><pre class="crayon-plain-tag">var randomColor = function() {   
  var colors = ['navy', 'slate', 'olive',...];   
  return colors[(Math.random() * colors.length) &gt;&gt;&gt; 0];
};

var randomCat = function() { ... }; 

template.uuid = randomColor() + '-' + randomCat();</pre><p></p>

<p><img src="/wp-content/uploads/2015/01/cats.png" alt="cat avatars" width="626" height="46" class="aligncenter size-full wp-image-12350" srcset="/wp-content/uploads/2015/01/cats.png 626w, /wp-content/uploads/2015/01/cats-300x22.png 300w, /wp-content/uploads/2015/01/cats-207x15.png 207w" sizes="(max-width: 626px) 100vw, 626px" /></p>

<h3>3.3. メッセージの送信</h3>

<p><pre class="crayon-plain-tag">&lt;core-pubnub-publish&gt;</pre>はチャンネルのサブスクライバー全てにメッセージを送信することができる要素です。</p>

<p></p><pre class="crayon-plain-tag">&lt;core-pubnub publish_key="demo" subscribe_key="demo"&gt;
  &lt;core-pubnub-publish id="pub" channel="polymer-chat" message="Hello"&gt;
  &lt;/core-pubnub-publish&gt;
&lt;/core-pubnub&gt;</pre><p></p>

<p>では、ユーザが文字を入力して送信ボタン( <pre class="crayon-plain-tag">&lt;paper-fab&gt;</pre> )をタップした時に、そのメッセージをサーバに送るコードを書きましょう。 Polymerは、<pre class="crayon-plain-tag">on-*</pre>イベントハンドラを使うので、この場合 <pre class="crayon-plain-tag">on-tap</pre>イベントを用いて<pre class="crayon-plain-tag">&lt;paper-fab&gt;</pre>がこのアクションを引き起こすことができるようにしてみます。</p>

<p></p><pre class="crayon-plain-tag">&lt;paper-fab icon="send" on-tap="{{sendMyMessage}}"&gt;&lt;/paper-fab&gt;</pre><p></p>

<p></p><pre class="crayon-plain-tag">template.sendMyMessage = function(e) {
  if(!template.input) return; // 入力フィールドが空の場合は何もしない

  template.$.pub.message = {
    uuid: uuid, 
    avatar: avatarUrl,
    color: color, 
    text: template.input  
  };
  template.$.pub.publish();
};</pre><p></p>

<p>これでユーザの情報とメッセージテキストが、サーバに送られました。次はすべてのユーザがこれを受信して、内容ををDOMに表示させてみましょう。</p>

<h3>3.4. 受信データのリアルタイムバインディング</h3>

<p>ネットワークに送られたメッセージは <pre class="crayon-plain-tag">&lt;core-pubnub-subscribe&gt;</pre>要素を使ってクライアント側で受信することができます。</p>

<p></p><pre class="crayon-plain-tag">&lt;core-pubnub-subscribe 
  channel="polymer-chat" 
  id="sub" 
  messages="{{messages}}" 
  on-callback="{{subscribeCallback}}"&gt;</pre><p></p>

<p>ここでの<pre class="crayon-plain-tag">messages</pre>属性は受信されたメッセージオブジェクトの配列が含まれています。ではここで受け取ったデータを先ほど作成した<pre class="crayon-plain-tag">&lt;x-chat-list&gt;</pre>カスタム要素を使って表示させましょう。 実は先のチャプター２で、既に <pre class="crayon-plain-tag">messages</pre> 配列のインスタンスが使われていることに気がついたでしょうか？ <pre class="crayon-plain-tag">messages="{{messages}}"</pre> 属性が&lt; <pre class="crayon-plain-tag">core-pubnub-subscribe&gt;</pre> と <pre class="crayon-plain-tag">&lt;x-chat-list&gt;</pre>の間で双方向バインディングがすでに行われているのです。なので、自動的にDOM生成を行ってチャットの内容を表示することができるのです！</p>

<p>ではもう一度、<pre class="crayon-plain-tag">&lt;x-chatlist&gt;</pre>を見てみましょう。</p>

<p></p><pre class="crayon-plain-tag">&lt;div flex class="chat-list"&gt;
  &lt;template repeat="{{message in messages}}"&gt;
    &lt;x-chat-list 
      color="{{message.color}}" 
      avatar="{{message.avatar}}" 
      username="{{message.uuid}}" 
      text="{{message.text}}"&gt;&lt;/x-chat-list&gt;
  &lt;/template&gt;
&lt;/div&gt;</pre><p></p>

<p>メッセージが受信された際には、<pre class="crayon-plain-tag">&lt;core-pubnub-subscribe&gt;</pre>のコールバック、<pre class="crayon-plain-tag">on-callback</pre>が発生します。 このチャットの配列は時間順に並べられているので、新しいメッセージはスクリーンの一番下に表示されることになります。これではユーザの使い勝手が悪いので、コールバック発生時に自動的に最新チャットまでスクロールさせることにしましょう。</p>

<p></p><pre class="crayon-plain-tag">template.subscribeCallback = function(e) {
  template.async(function(){
    var chatDiv = document.querySelector('.chat-list');
    chatDiv.scrollTop = chatDiv.scrollHeight; // scroll to bottom
  });
};</pre><p></p>

<p>これで、PolymerでMaterial Designの美しいデザインを使った簡単なチャットルームが完成しました！</p>

<p>このチュートリアルではわかりやすくするために、<a href="http://pubnub.github.io/paper-chat/index.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">デモ</a>で使われているすべてのフィーチャーについてや、Shadow DOMのスタイリングについての説明は省略してあるので、さらに知りたい方は是非、<a href="https://github.com/pubnub/paper-chat" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">GitHub のRepo</a>で確認してみてください。</p>

<p>デモとチュートリアル、楽しんでいただけたなら幸いです！Happy coding!</p>

<p><img src="/wp-content/uploads/2015/01/paper-chat.gif" alt="polymer pubnub chat app animated gif" width="280" height="280" class="aligncenter size-full wp-image-12364" /></p>
]]></content:encoded>
			</item>
		<item>
		<title>Web Componentsを簡単・便利にするライブラリ「Polymer」を使いこなそう</title>
		<link>/1000ch/11905/</link>
		<pubDate>Fri, 26 Dec 2014 00:00:37 +0000</pubDate>
		<dc:creator><![CDATA[泉水翔吾]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Polymer]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=11905</guid>
		<description><![CDATA[連載： 基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜 (3)Web Componentsを簡単・便利にするライブラリ「Polymer」を使いこなそう この記事は、連載「基礎からわか...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/web-components-2/" class="series-214" title="基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜" data-wpel-link="internal">基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜</a> (3)</div><h1>Web Componentsを簡単・便利にするライブラリ「Polymer」を使いこなそう</h1>

<p>この記事は、連載「<a href="https://html5experts.jp/series/web-components-2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜</a>」の第3回目になります。連載の第3回目となる今回は、Googleが中心となって開発を進めるPolymerというWeb Componentsのライブラリについて解説します。</p>

<h2>Web Componentsをより柔軟に、そして強力にするライブラリ</h2>

<p>Polymerは素のWeb Componentsにおいて、煩雑である部分を簡略化し、機能をより強力なものにし、基礎となるコンポーネントを提供します。<a href="http://ja.wikipedia.org/wiki/BSD%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">BSDライセンス</a>のもと、オープンソースで開発が行われており、ソースコードも<a href="https://github.com/Polymer" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">GitHub</a>にて公開されているので、Pull Requestを送るなどのかたちで私たちも開発に貢献することが可能です。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2014/12/polymer-project.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/12/polymer-project.png" alt="polymer-project" width="1136" height="885" class="alignnone size-full wp-image-11926" srcset="/wp-content/uploads/2014/12/polymer-project.png 640w, /wp-content/uploads/2014/12/polymer-project-300x233.png 300w, /wp-content/uploads/2014/12/polymer-project-1024x797.png 1024w, /wp-content/uploads/2014/12/polymer-project-207x161.png 207w" sizes="(max-width: 1136px) 100vw, 1136px" /></a></p>

<ul>
<li><a href="https://www.polymer-project.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Welcome Polymer</a></li>
</ul>

<p>Polymerが提供する機能は、主に3つのパートに分かれています。Web Componentsの作成を簡単に、そして強力なものにする <strong>Polymer Core</strong> 。次に、一般的なUIの基礎の他、アニメーションや通信機能等を抽象化した <strong>Core Elements</strong> 。最後に、Google I/O 2014で発表されたデザインコンセプト「Material Design」をWebで実現する <strong>Paper Elements</strong> です。また、その他にも同じくPolymerチームが開発する、Web Componentsが未実装のブラウザでもWeb Componentsを利用可能にする WebComponents.js というポリフィルも提供されています。</p>

<p>Core Elements及びPaper Elementsは、Polymer Coreをベースに作られているため次回紹介するものとし、今回はPolymerの機能の中心となる <strong>Polymer Core</strong> と、この <strong>WebComponents.js</strong> について解説します。</p>

<h2>Polymer Core</h2>

<p>Polymer Coreは、素のWeb Componentsでは煩雑とも言える作成の手順を簡略化し、テンプレート機能やデータバインディングといった、Web Componentsを作る上で土台となる強力な機能を提供します。Core ElementsやPaper ElementsはこのPolymer Coreをベースに構成されています。よって、Core ElementsやPaper Elementsの利用にはPolymer Coreが必要です。</p>

<h3>カスタム要素の作成をシンプルに書き換える</h3>

<p>まずは、Web Componentsを作る最もシンプルな例を比べてみましょう。</p>

<p></p><pre class="crayon-plain-tag">&lt;template id='sample-element-template'&gt;
  &lt;button&gt;Sample Element&lt;/button&gt;
&lt;/template&gt;
&lt;script&gt;
  var SampleElementPrototype = Object.create(HTMLElement.prototype);
 
  SampleElementPrototype.createdCallback = function () {
    var shadowRoot = this.createShadowRoot();
    var template = document.querySelector('#sample-element-template');
    var clone = document.importNode(template.content, true);
    shadowRoot.appendChild(clone);
  };

  document.registerElement('sample-element', {
    prototype: SampleElementPrototype
  });
&lt;/script&gt;</pre><p></p>

<p>これはPolymerを使うことで以下のようにシンプルに書き換えることができます。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="import" href="polymer.html"&gt;

&lt;polymer-element name="sample-element"&gt;
  &lt;template&gt;
    &lt;button&gt;Sample Element&lt;/button&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer({
      ready: function () {}
    });
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p><code>document.registerElement('sample-element')</code>によるカスタム要素の宣言は、Polymerの場合、&lt;polymer-element name=&#8221;sample-element&#8221;&gt;のように&lt;polymer-element&gt;の<code>name</code>属性によって行われます。</p>

<p>また、カスタム要素の雛形となる&lt;template&gt;からの要素のコピーとShadow Rootの作成を<code>createdCallback</code>で行っていた部分は、&lt;polymer-element&gt;が自動的に行うため省略できます。</p>

<p>このカスタム要素の定義のエントリポイントとなる&lt;polymer-element&gt;は、<code>polymer.html</code>をインポートすることで利用可能になります。</p>

<h3>&lt;polymer-element&gt;の属性値</h3>

<p>&lt;polymer-element&gt;固有の属性値として、次の4つがあります。</p>

<ul>
<li><code>name</code> 定義するカスタム要素名を指定する（必須）。</li>
<li><code>attributes</code> プロパティをスペース区切りで指定する（任意）</li>
<li><code>extends</code> 継承する他の要素名を指定する（任意）。<code>document.registerElement()</code>の第二引数に指定する<code>extends</code>と異なり、カスタム要素名を与えることが可能。</li>
<li><code>noscript</code> <code>Polymer()</code>をコールする必要がない場合に指定する（任意）</li>
<li><code>constructor</code> カスタム要素のコンストラクタ名を指定する（任意）。カスタム要素のコンストラクタは指定した名称でグローバル空間にエクスポートされる。<code>document.registerElement()</code>の返り値に指定する名称と同等。</li>
</ul>

<p>以下は<code>constructor</code>属性と<code>attributes</code>属性を指定する例です。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="import" href="polymer.html"&gt;

&lt;polymer-element name="sample-element"
  constructor="SampleElement"
  attributes="foo bar baz"&gt;
  &lt;template&gt;
    &lt;button&gt;Sample Element&lt;/button&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer({
      foo: 0,
      bar: 'Hello!'
    });
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p><code>constructor="SampleElement"</code>と指定することで、このHTMLが評価されると、<code>new SampleElement()</code>でインスタンスを作成することができます。</p>

<p>また、<code>attributes="foo bar baz"</code>でプロパティを3つ定義しました。これは<code>Polymer()</code>関数内で初期値を指定しており、この例において<code>foo</code>、<code>bar</code>、<code>baz</code>の初期値はそれぞれ<code>0</code>、<code>'Hello!'</code>、<code>undefined</code>ということになります。</p>

<p>プロパティの宣言については、他にも<code>published</code>を使った方法があります。こちらに関してはPolymer公式の<a href="https://www.polymer-project.org/docs/polymer/polymer.html#attributes" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Published properties &#8211; API developer guide</a>を参照してください。</p>

<h3>ライフサイクルコールバック</h3>

<p>カスタム要素のプロトタイプに指定していたライフライクルコールバックは、それぞれ&#8221;Callback&#8221;が省略され、<code>Polymer()</code>に引数として指定します。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="import" href="polymer.html"&gt;

&lt;polymer-element name="sample-element"&gt;
  &lt;template&gt;
    &lt;button&gt;Sample Element&lt;/button&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer({
      created: function () {},
      attached: function () {},
      detached: function () {},
      attributeChanged: function () {}
    });
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p>また、素のCustom Elementsでは提供されていないPolymer特有のコールバックとして<code>ready</code>と<code>domReady</code>があります。<code>ready</code>は&lt;sample-element&gt;内で行っているShadow DOMの構築やイベントへのリスナの定義といった様々な処理が完了したタイミングで発火し、<code>domReady</code>は、宣言するカスタム要素に内包されるコンテンツの生成が完了したタイミングで発火します。</p>

<h3>テンプレート機能とデータバインディング</h3>

<p><a href="https://html.spec.whatwg.org/multipage/scripting.html#the-template-element" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Template</a>の仕様は不活性なHTML要素を提供するという非常にシンプルなものですが、Polymerは、テンプレートエンジン<a href="http://mustache.github.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Mustache</a>でお馴染みのブラケット<code>{{}}</code>を使ったテンプレート機能を提供します。</p>

<p></p><pre class="crayon-plain-tag">&lt;template&gt;
  &lt;ul&gt;
    &lt;template repeat="{{item in items}}"&gt;
      &lt;li&gt;{{item.name}} - {{item.message}}&lt;/li&gt;
    &lt;/template&gt;
  &lt;/ul&gt;
&lt;/template&gt;
&lt;script&gt;
  Polymer({
    ready: function () {
      this.items = [{
        name: 't32k',
        message: 'In Canada.'
      }, {
        name: 'hiloki',
        message: 'So hungry.'
      }, {
        name: '1000ch',
        message: 'Feeling lucky.'
      }];
    }
  });
&lt;/script&gt;</pre><p></p>

<p><code>{{variable}}</code>のように変数名を記述することで値が展開されるほか、コード例の<code>{{item in array}}</code>のように<code>in</code>を挿入することで、配列の要素を列挙することも可能です。この変数のコンテキストは常に作成するカスタム要素(<code>this</code>)になります。</p>

<p>また、この<code>{{}}</code>による変数の挿入は、次の<code>on-click="{{onClick}}"</code>のような書式でイベントハンドラの設定をする他、そのままデータバインディングにもなります。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="import" href="bower_components/polymer/polymer.html"&gt;

&lt;polymer-element name="sample-element" attributes="message"&gt;
  &lt;template&gt;
    &lt;input type="text" value="{{message}}"&gt;
    &lt;button on-click="{{onClick}}"&gt;&lt;content&gt;&lt;/content&gt;&lt;/button&gt;
  &lt;/template&gt;
  &lt;script&gt;
    Polymer({
      message: '',
      onClick: function () {
        alert(this.message);
      }
    });
  &lt;/script&gt;
&lt;/polymer-element&gt;</pre><p></p>

<p>まず、<code>on-click="{{onClick}}"</code>によってボタンがクリックされた時の処理を指定し、この<code>onClick</code>で指定されるイベントハンドラは<code>Polymer()</code>コンストラクタを参照しています。もちろんここでも変数のコンテキストはカスタム要素自身（<code>this</code>）になっています。</p>

<p>次に&lt;input type=&#8221;text&#8221; value=&#8221;{{message}}&#8221;&gt;となっている部分に着目してください。&lt;input&gt;要素の入力値に対し<code>{{message}}</code>という変数を割り当てていますが、これはデータバインディングの力によって入力値が随時<code>message</code>変数に代入されるようになります。先ほどの<code>onClick</code>において、この<code>message</code>をアラートで表示するようにしていますが、<code>message</code>変数を介して`&lt;input&gt;要素への入力値が表示されることになります。</p>

<p>最後に、&lt;sample-element&gt;の属性値を宣言している<code>attributes</code>でも<code>message</code>という属性を定義しています。こちらも例外なくデータバインディングが適用され、&lt;sample-element message=&#8221;Input Value&#8221;&gt;Button&lt;/sample-element&gt;とすれば <strong>Input Value</strong> が初期値として表示されます。</p>

<h2>Web Componentsのポリフィルライブラリwebcomponents.js (旧platform.js)</h2>

<p>Web Componentsを実際のWebで使うには、Custom ElementsやHTML Importsといった機能が、仕様にそってブラウザに実装されている必要があります。各機能は2014年末の時点で、実装を先行して積極的に進めていたChrome(Version 39.0.2171.71)をはじめ、Opera(26.0.1656.32)、Firefox(34.0.5)はフラグを立てることでサポートされています。</p>

<p>しかしSafari、Internet Explorerは共に実装を見合わせている状態で、ユーザーの環境を考慮するとこれらのブラウザでもWeb Componentsが動くことが望ましいです。</p>

<p>こういった環境をサポートするのが、<code>webcomponents.js</code>というPolymerチームの開発するポリフィルライブラリです。これをロードすることで、Web Componentsに関する機能が未実装のブラウザでも利用することが可能になります。また、Mozillaが開発するWeb Componentsのライブラリである<a href="http://www.x-tags.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">X-Tag</a>やUIコンポーネント群である<a href="http://mozbrick.github.io/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Brick</a>もサブセットとして利用しています。</p>

<ul>
<li><a href="http://webcomponents.org/polyfills/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polyfills &#8211; WebComponents.org</a> <code>webcomponents.js</code>に関する解説</li>
<li><a href="https://github.com/WebComponents/webcomponentsjs" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">webcomponents/webcomponentsjs</a> GitHubのリポジトリ</li>
</ul>

<p>以前までは<code>platform.js</code>という名前で知られていましたが、<a href="https://blog.polymer-project.org/announcements/2014/10/16/platform-becomes-webcomponents/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymerの公式アナウンス</a>で<code>v0.5.0</code>から<code>webcomponents.js</code>への名称変更とGitHubのリポジトリが<a href="http://github.com/webcomponents" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Components</a>へ移管が発表されました。<a href="https://github.com/webcomponents/webcomponentsjs/commits/master" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">コミットログ</a>を見る限り開発体制も変わっていないように見えますので、役割に応じて分担を適切に図った結果と言えるでしょう。</p>

<h3>webcomponents.jsのインストールと利用方法</h3>

<p><code>webcomponents.js</code>はGitHubのリポジトリからダウンロードすることができます。</p>

<ul>
<li><a href="https://github.com/webcomponents/webcomponentsjs/releases" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Releases · webcomponents/webcomponentsjs</a></li>
</ul>

<p>Bowerもしくはnpmからもダウンロードすることが可能です。プロジェクトのパッケージ管理に合わせて選んでください。</p>

<p></p><pre class="crayon-plain-tag"># bowerでインストール
$ bower install --save webcomponentsjs

# npmでインストール
$ npm install --save webcomponents.js</pre><p></p>

<p>あとはダウンロードしてきた<code>webcomponents.js</code>をHTML内でロードするだけです。Web ComponentsのAPIを実行される前に評価されている必要があることに注意する必要があります。公式では、<a href="http://webcomponents.org/polyfills/#installation-usage" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">head要素で最初のscript要素としてロードすることを推奨しています</a>。</p>

<p></p><pre class="crayon-plain-tag">&lt;script src="bower_components/webcomponentsjs/webcomponents.js"&gt;&lt;/script&gt;</pre><p></p>

<p>また、<code>webcomponents.js</code>はWeb Componentsの仕様4つ全てをサポートしますが、Shadow DOMのポリフィルを除いた<code>webcomponents-lite.js</code>もあります。重いShadow DOMのサポートがない分、軽量化されているので、もしShadow DOMを必要としないのであれば<code>webcomponents-lite.js</code>を選択するのもよいでしょう。</p>

<h3>webcomponents.jsのカスタムビルド</h3>

<p>Web Componentsのポリフィルを提供する<code>webcomponents.js</code>ですが、<code>webcomponents-lite.js</code>のように補完する機能を選べるように、Custom Elements・HTML Imports・Shadow DOMそれぞれ個別のポリフィルを行うカスタムビルドが用意されています。先程の<code>bower</code>によるインストールで<code>CustomElements.js</code>、<code>HTMLImports.js</code>、<code>ShadowDOM.js</code>が同梱されているので、これらをロードすることで個別にポリフィルを行うことも可能です。</p>

<p>自身でカスタムビルドを行う場合はリポジトリをクローンし、<code>gulp</code>で用意されているカスタムビルドを実行します。</p>

<p></p><pre class="crayon-plain-tag"># リポジトリのクローン
$ git clone git@github.com:webcomponents/webcomponentsjs.git

# クローンしたリポジトリに移動
$ cd webcomponentsjs

# 依存モジュールのインストール
$ npm install

# gulpのbuildタスクを実行
$ gulp build</pre><p></p>

<p>実行後、<code>dist</code>フォルダにそれぞれのファイルが生成されます。ES6の機能であるWeakMapやMutationObserverもポリフィルとして用意され、Web Componentsに関する仕様であるCustom Elements、HTML Imports、Shadow DOMに、内部で使われているのは非常に興味深い点です。</p>

<h2>Polymerとwebcomponents.jsの取り扱い</h2>

<p>このように、Polymerはカスタム要素を構築する上での機能拡張であり、<code>webcomponents.js</code>はWeb Componentsの前提となる機能を提供します。よって、「Web Componentsを作る上でPolymerがなければ作れない」ということはありませんし、提供したいブラウザ環境にWeb Componentsの仕様が実装されていれば<code>webcomponents.js</code>は不要です。</p>

<p>説明した通りPolymerでは、素のWeb Componentsとは少々異なる方法論を強いられます。これは、Web Componentsの仕様が今後変わる場合に、PolymerがAPIのギャップを吸収してくれる可能性を示唆しています。ですが、Polymer自体のAPIの変更がある場合にそれに追従しなければならないですし、Web Componentsの仕様そのものに比べればサポートがいつまで行われるかという懸念もあります。これらを踏まえると、Web Componentsの機能をひと通り理解した上でPolymerを使うことが望ましいと言えるでしょう。</p>

<h2>まとめ</h2>

<p>Web Componentsの基礎仕様・実践的なコンポーネント作成に続き、今回はWeb Componentsを支えるPolymerについて解説しました。次回はPolymerを実際に使って作られた、便利な基礎コンポーネント群 <strong>Core Elements</strong> と、Material DesignをWebで実現する <strong>Paper Elements</strong> について扱います。</p>
]]></content:encoded>
		
		<series:name><![CDATA[基礎からわかる Web Components 徹底解説 〜仕様から実装まで理解する〜]]></series:name>
	</item>
		<item>
		<title>話題のMaterial DesignをWebで実現！Polymerで「Paper Elements」を試そう</title>
		<link>/ahomu/9307/</link>
		<pubDate>Tue, 05 Aug 2014 00:00:12 +0000</pubDate>
		<dc:creator><![CDATA[佐藤歩]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google I/O 2014]]></category>
		<category><![CDATA[Material Design]]></category>
		<category><![CDATA[Paper Elements]]></category>
		<category><![CDATA[Polymer]]></category>

		<guid isPermaLink="false">/?p=9307</guid>
		<description><![CDATA[連載： Google I/O 2014 特集 (9)この記事では2014年7月にGoogle I/Oで発表されたMaterial Designについて、どのようなコンセプトなのか、これまでのデザインガイドラインと何が違う...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google-io-2014-2/" class="series-191" title="Google I/O 2014 特集" data-wpel-link="internal">Google I/O 2014 特集</a> (9)</div><p>この記事では2014年7月にGoogle I/Oで発表されたMaterial Designについて、どのようなコンセプトなのか、これまでのデザインガイドラインと何が違うのか、ポイントをおさえて紹介します。記事の後半では、Material DesignをWebで実現するためのPolymerとPaper Elementsに関しても説明します。</p>

<h2>Material Designという視覚的言語</h2>

<p><a href="http://www.google.com/design/spec/material-design/introduction.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Material Design</a>の目的は、ひとつの視覚的な言語（Visual Language）によって、あらゆるプラットフォーム、あらゆるスクリーンサイズのデバイスで、一貫性のある体験を提供することです。</p>

<p>それを実現するため、伝統的なグラフィックデザインとテクノロジーによる可能性を引き出して開発に取り組み、ガイドラインは生きたドキュメントとして更新され続けるとしています。</p>

<h3>フラットな中に、自然な影や動きを取り入れた</h3>

<p>Material Designは、フラットデザインを取り入れた他のデザインガイドラインと同様に、伝統的なグラフィックデザイン、たとえばタイポグラフィーやレイアウトの原則を取り込んでいます。文字やグラフィックを中心に構成された現在のアプリやWebに、はるか昔から積み重ねられてきたノウハウを融和させることで、優れたビジュアルが得られます。</p>

<p>しかし、単なるビジュアルのルールだけでは、スクリーンサイズの多様性の中で、UIや体験の一貫性を保つのはどこかで限界があるのかもしれません。そこでMaterial Designは、「Material is the Metaphor」というコンセプトを取り込んでいます。</p>

<div id="attachment_9352" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2014/07/layering.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/layering.png" alt="Layering" width="640" height="360" class="size-full wp-image-9352" srcset="/wp-content/uploads/2014/07/layering.png 640w, /wp-content/uploads/2014/07/layering-300x168.png 300w, /wp-content/uploads/2014/07/layering-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">http://googledevelopers.blogspot.jp/2014/06/this-is-material-design.html</p></div>

<p>規則性のある影や、連続性のあるモーションなどを、現実世界のメタファとして細部に取り込むことで、深いレベルで一貫性をもった世界を構築しようとしています。これらの表現に、現実の物質世界と同じ物理的性質をもたせることで、認知的な負担を少なくし、より自然にアフォーダンスを受け取れるようにしています。</p>

<p>例えば、フラットな面に影の表現を加えることで、オブジェクトの重なりやヒエラルキーが表現できます。強く影をつけた大きなボタンは、ユーザーの目にひときわ浮き立つプライマリなアクションとして認識されます。</p>

<p>このような影について、Android Lではリアルタイムソフトシャドウとして、現実世界のメタファを通して、より自然な振る舞いになるようエンジニアリングが発揮されています。モーションについても、直線的な動きではなく、現実世界の慣性に従った動きになるようにガイドラインで定められています。</p>

<div id="attachment_9356" style="width: 650px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2014/07/14803538523_b7b20a90bd_z.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/14803538523_b7b20a90bd_z.jpg" alt="Material Design Paper" width="640" height="360" class="size-full wp-image-9356" srcset="/wp-content/uploads/2014/07/14803538523_b7b20a90bd_z.jpg 640w, /wp-content/uploads/2014/07/14803538523_b7b20a90bd_z-300x168.jpg 300w, /wp-content/uploads/2014/07/14803538523_b7b20a90bd_z-207x116.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">Material Design Paper</p></div>

<p>Material Designのコンセプトについて詳しくは、<a href="https://www.google.com/design/material-design.pdf" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PDF</a>で9つの特徴にまとまっています。Google I/Oのデザインブースでは、このPDFの図画が、実際の紙にインクで印刷されたものが頒布されていました。</p>

<h3>「具体的な」デザインガイドライン</h3>

<p>Material Designの<a href="http://www.google.com/design/spec/animation/authentic-motion.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ガイドライン</a>として、具体的にどのようなデザインを実現すれば良いかのドキュメントは、プレビュー版としてすでに公開されています。</p>

<p>以前の<a href="https://developer.android.com/design/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Android Design</a>においても詳細な項目が用意されていましたが、今回のガイドラインでは、そこにアニメーションや陰影の深度に関する項目をはじめとして、多岐にわたり詳細な情報が掲載されています。特徴的なのは、文字のレイアウト、アニメーション、陰影の表現、画像のフェード効果など細部に至るまで、具体的な数値とサンプルをもって表現していることです。</p>

<div id="attachment_9350" style="width: 1290px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2014/07/Authentic-Motion-Animation-Google-design-guidelines.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/Authentic-Motion-Animation-Google-design-guidelines.png" alt="ガイドラインの一例" width="1280" height="728" class="size-full wp-image-9350" srcset="/wp-content/uploads/2014/07/Authentic-Motion-Animation-Google-design-guidelines.png 640w, /wp-content/uploads/2014/07/Authentic-Motion-Animation-Google-design-guidelines-300x170.png 300w, /wp-content/uploads/2014/07/Authentic-Motion-Animation-Google-design-guidelines-1024x582.png 1024w, /wp-content/uploads/2014/07/Authentic-Motion-Animation-Google-design-guidelines-207x117.png 207w" sizes="(max-width: 1280px) 100vw, 1280px" /></a><p class="wp-caption-text">ガイドラインの一例</p></div>

<p>さらにAndroidの開発ライブラリはもちろん、後半で紹介するPaper Elementsが、ガイドラインを体現した実装として存在しています。具体的なガイドラインと、それを反映した実装の2つが揃うことによって、Material Designのガイドラインは、他のデザインガイドラインよりも確かで、強固なものになっています。</p>

<h3>Google I/O でのセッション</h3>

<ul>
<li><a href="https://www.youtube.com/watch?v=isYZXwaP3Q4" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google I/O 2014 &#8211; Material design principles &#8211; YouTube</a></li>
<li><a href="https://www.youtube.com/watch?v=dZqzz5lZFvo" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google I/O 2014 &#8211; Material design: Structure and components &#8211; YouTube</a></li>
<li><a href="https://www.youtube.com/watch?v=ctzWKRlTYHQ" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google I/O 2014 &#8211; Material design: Visual style and imagery &#8211; YouTube</a></li>
<li><a href="https://www.youtube.com/watch?v=FBD0VlcVS1E" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Google I/O 2014 &#8211; Material design: Motion &#8211; YouTube</a></li>
</ul>

<p>キーノートの中で紹介されたMaterial Designですが、その後のセッションでもテーマごとに、詳細な内容の紹介がありました。より深く理解したい方は、これらの動画もチェックしてみると面白い話が聞けるはずです。（YouTubeでは英語字幕が表示されるので、聞きやすいです）</p>

<h2>Webで実現するためのPolymerとPaper Elements</h2>

<p>ここまでMaterial Designについて紹介しましたが、いよいよこのデザイン原則をWebの世界に取り込むため、PolymerとPaper Elementsについて説明します。</p>

<p>はじめに<a href="http://www.polymer-project.org/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer</a>とは、<a href="https://html5experts.jp/1000ch/8906/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Componentsが変えるWeb開発の未来</a>で説明されたWeb Componentsをより強力に、より柔軟に使えるようにGoogleで開発されているラッパーライブラリです。Web Componentsが注目を集め始めたのと同時に、Polymerの話題も多く目にするようになっています。</p>

<p>Polymerには、そのラッパーとしての機能を活かして作成された、汎用コンポーネント群があります。それが<a href="http://www.polymer-project.org/docs/elements/core-elements.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Core Elements</a>と<a href="http://www.polymer-project.org/docs/elements/paper-elements.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Paper Elements</a>です。このうち、Paper ElementsがMaterial DesignをWebで表現するための鍵になりますが、実際に開発するにはPolymer本体に、これらCore ElementsとPaper Elementsを組み合わせて利用します。</p>

<p>ここでは、Rob Dodsonによる<a href="https://www.youtube.com/watch?v=HKrYfrAzqFA" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Unlock the next era of UI development with Polymer</a>というセッション（<a href="http://www.slideshare.net/rob_dodson/unlock-the-next-era-of-ui-design-with-polymer" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">SlideShare</a>）の内容を参考に紹介していきます。</p>

<h3>レイアウトを構築する</h3>

<p>はじめにCore Elementsを使ったアプリケーションのレイアウトについて紹介します。Core Elementsには、一般的なナビゲーションパターンのレイアウトを、手軽に制御できるコンポーネントが用意されています。</p>

<p>たとえば<a href="http://www.polymer-project.org/docs/elements/core-elements.html#core-header-panel" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-header-panel</code></a>を利用すると、よくある固定ヘッダーとコンテンツ部分の管理ができます。これまで、普通にHTMLとCSSでレイアウトして、インナースクロール用のJavaScriptライブラリを組み込んで実現していたUIが、ひとつのコンポーネントをHTML内に取り込むだけで作れるようになります。</p>

<div id="attachment_9347" style="width: 648px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-27-638.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-27-638.jpg" alt="core-drawer-panel (参考スライドP27から引用)" width="638" height="359" class="size-full wp-image-9347" srcset="/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-27-638.jpg 638w, /wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-27-638-300x168.jpg 300w, /wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-27-638-207x116.jpg 207w" sizes="(max-width: 638px) 100vw, 638px" /></a><p class="wp-caption-text">core-drawer-panel (参考スライドP27から引用)</p></div>

<p>上図のようなドロワーメニューを内包したレスポンシブなレイアウトも、<a href="http://www.polymer-project.org/docs/elements/core-elements.html#core-drawer-panel" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-drawer-panel</code></a>を利用すると、<code>drawer</code>と<code>main</code>という属性をそれぞれ持った要素を、子要素として追加すれば容易に制御できます。</p>

<p>もうひとつレイアウトするための強力な機能が存在します。それが<a href="http://www.polymer-project.org/docs/polymer/layout-attrs.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Layout attributes</a>です。これはPolymer本体に備えられた機能です。</p>

<div id="attachment_9348" style="width: 648px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-35-638.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-35-638.jpg" alt="layout属性 (参考スライドP35から引用)" width="638" height="359" class="size-full wp-image-9348" srcset="/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-35-638.jpg 638w, /wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-35-638-300x168.jpg 300w, /wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-35-638-207x116.jpg 207w" sizes="(max-width: 638px) 100vw, 638px" /></a><p class="wp-caption-text">layout属性 (参考スライドP35から引用)</p></div>

<p>このように、<code>layout</code>属性を付与して、要素を並べる方向（<code>vertical</code>, <code>horizontal</code>）や、子要素に<code>flex</code>などの指定を行うことで、CSSを使わずにHTML側で基本的なレイアウトを制御できます。ここでは一例を紹介しましたが、詳細はPolymerのドキュメントを確認してみてください。</p>

<h3>Material Designを使う</h3>

<p>いよいよPaper Elementsが登場します。Core Elementsが基本的な機能と素朴な見た目しか持たない汎用コンポーネント群であるのに対して、Paper Elementsは<a href="http://www.google.com/design/spec/components/bottom-sheets.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Material Designのガイドライン</a>におけるUIコンポーネントを、ビジュアルとインタラクションの両面において実装しています。</p>

<p>たとえば<code>paper-tabs</code>は、次の画像のようなマークアップでMaterial Designで表現されたタブのUIを組み込むことができます。</p>

<div id="attachment_9346" style="width: 648px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-44-638.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-44-638.jpg" alt="paper-tabs (参考スライドP44から引用)" width="638" height="359" class="size-full wp-image-9346" srcset="/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-44-638.jpg 638w, /wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-44-638-300x168.jpg 300w, /wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-44-638-207x116.jpg 207w" sizes="(max-width: 638px) 100vw, 638px" /></a><p class="wp-caption-text">paper-tabs (参考スライドP44から引用)</p></div>

<p>このようなPaper ElementsのUIコンポーネントは<a href="http://www.polymer-project.org/components/paper-elements/demo.html#paper-checkbox" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Paper Elements Sampler</a>で動作デモを確認できます。</p>

<p>Material Designは影や波紋のようなエフェクトといったインタラクションも重要です。Paper Elementsの中にはそのような、特定のUIを表現するものではなく、エフェクトを適用するための要素も用意されています。</p>

<div id="attachment_9345" style="width: 648px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-47-638.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-47-638.jpg" alt="paper-shadow (参考スライドP47から引用)" width="638" height="359" class="size-full wp-image-9345" srcset="/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-47-638.jpg 638w, /wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-47-638-300x168.jpg 300w, /wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-47-638-207x116.jpg 207w" sizes="(max-width: 638px) 100vw, 638px" /></a><p class="wp-caption-text">paper-shadow (参考スライドP47から引用)</p></div>

<p><a href="http://www.polymer-project.org/docs/elements/paper-elements.html#paper-shadow" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>paper-shadow</code></a>は親要素に、<code>z</code>属性で指定されたコンテンツの深度に応じて、適切な影の表現をつけられます。Material Designでは、影を表現するために、深さを表現するKey Shadowと、オブジェクトの形態を示すAmbient Shadowの2つが使われています。この<code>paper-shadow</code>もCSSの<code>box-shadow</code>で2種類の影をかさねて表現しています。</p>

<p>前半で説明したとおり、Material Designにおける影は、ただの装飾ではなく、オブジェクトの階層やユーザーのフォーカスを得るための、意図的な表現です。多くのオブジェクトに、このようなエフェクトを積極的に使っていくことになります。</p>

<div id="attachment_9344" style="width: 648px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-46-638.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-46-638.jpg" alt="paper-ripple (参考スライドP46から引用)" width="638" height="359" class="size-full wp-image-9344" srcset="/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-46-638.jpg 638w, /wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-46-638-300x168.jpg 300w, /wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-46-638-207x116.jpg 207w" sizes="(max-width: 638px) 100vw, 638px" /></a><p class="wp-caption-text">paper-ripple (参考スライドP46から引用)</p></div>

<p><a href="http://www.polymer-project.org/docs/elements/paper-elements.html#paper-ripple" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>paper-ripple</code></a>は親要素に、clickやtouchしたときのエフェクトを適用できます。<a href="http://www.polymer-project.org/components/paper-ripple/demo.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">デモ</a>を見ると、それがどのような効果か分かりやすいはずです。このエフェクトは、親の要素と同じサイズの<code>canvas</code>を展開して、その上で波紋のようなエフェクトを表現しています。</p>

<h3>スタイルを適用する</h3>

<p>Polymerの要素は、Shadow DOMが使われているため、従来どおりのCSSセレクタでは、内側の要素にスタイルを適用できません。ここでは<a href="http://dev.w3.org/csswg/css-scoping/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">CSS Scoping Module</a>として定義されている、<code>::shadow</code>と<code>/deep/</code>セレクタを紹介します。</p>

<p><code>::shadow</code>は、疑似要素としてShadow DOMのルートにアクセスできます。次の例では、Polymerで作られた<code>x-foo</code>が持つShadow DOM内の<code>span</code>にアクセスして、<code>color: red</code>を指定しています。</p>

<p></p><pre class="crayon-plain-tag">&lt;style&gt;
x-foo::shadow span {
  color: red;
}
&lt;/style&gt;

&lt;polymer-element name="x-foo" noscript&gt;
  &lt;template&gt;
    &lt;span&gt;Hi!&lt;/span&gt; &lt;!-- color: red --&gt;
  &lt;/template&gt;
&lt;/polymer-element&gt;

&lt;x-foo&gt;&lt;/x-foo&gt;</pre><p></p>

<p><code>/deep/</code>は、<code>::shadow</code>と同じくShadow DOM内へのアクセスを可能にしますが、より強力にネストしたShadow DOMの奥深くまで適用できます。次の例では、<code>x-hello</code>の中にあるすべての<code>span</code>に<code>color:blue</code>を適用しています。<code>::shadow</code>の場合だと、<code>x-world</code>の中の<code>span</code>にはネストしたShadow DOMの境界を越えられず適用されません。</p>

<p></p><pre class="crayon-plain-tag">&lt;style&gt;
x-hello /deep/ span {
  color: blue;
}
&lt;/style&gt;

&lt;polymer-element name="x-hello" noscript&gt;
  &lt;template&gt;
    &lt;span&gt;Hello&lt;/span&gt; &lt;!-- color: blue --&gt;
    &lt;x-world&gt;&lt;/x-world&gt;
  &lt;/template&gt;
&lt;/polymer-element&gt;

&lt;polymer-element name="x-world" noscript&gt;
  &lt;template&gt;
    &lt;span&gt;World&lt;/span&gt;  &lt;!-- color:blue --&gt;
  &lt;/template&gt;
&lt;/polymer-element&gt;

&lt;x-hello&gt;&lt;/x-hello&gt;</pre><p></p>

<p>一方、Core ElementsにはPolymerの要素間でスタイルを共有するために、<a href="http://www.polymer-project.org/docs/elements/core-elements.html#core-style" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-style</code></a>というコンポーネントが用意されています。</p>

<div id="attachment_9341" style="width: 648px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-58-638.jpg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-58-638.jpg" alt="core-style (参考スライドP58から引用)" width="638" height="359" class="size-full wp-image-9341" srcset="/wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-58-638.jpg 638w, /wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-58-638-300x168.jpg 300w, /wp-content/uploads/2014/07/unlock-the-next-era-of-ui-design-with-polymer-58-638-207x116.jpg 207w" sizes="(max-width: 638px) 100vw, 638px" /></a><p class="wp-caption-text">core-style (参考スライドP58から引用)</p></div>

<p><code>core-style</code>を使って<code>id</code>属性が指定されたStyle Producerで定義されたスタイルを、<code>ref</code>属性を指定してStyle Consumerから参照することで、コンポーネントをまたいで特定のスタイルを共有できます。</p>

<h3>トランジションを利用する</h3>

<p><a href="http://www.polymer-project.org/docs/elements/core-elements.html#core-animated-pages" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>core-animated-pages</code></a>を利用すると、Single Page Applicationのように、ひとつのHTMLで複数のコンテンツを切り替えて表示するときに、トランジションを適用できます。<code>core-animated-pages</code>も、対象の要素に属性を付与するだけで、トランジション効果を得られます。</p>

<p></p><pre class="crayon-plain-tag">&lt;polymer-element name="animated-sample" noscript&gt;
  &lt;template&gt;
    &lt;style&gt;
      section &gt; div { color:white; height: 500px; }
    &lt;/style&gt;

    &lt;!-- コンテンツ切り替え用のタブ --&gt;
    &lt;paper-tabs id="tabs" selected="0"&gt;
      &lt;paper-tab&gt;ONE&lt;/paper-tab&gt;
      &lt;paper-tab&gt;TWO&lt;/paper-tab&gt;
      &lt;paper-tab&gt;THREE&lt;/paper-tab&gt;
    &lt;/paper-tabs&gt;

    &lt;!-- コンテンツとトランジション付与 --&gt;
    &lt;core-animated-pages
      selected="{{$.tabs.selected}}"
      transitions="cross-fade-all"&gt;
      &lt;section&gt;
        &lt;div style="background:red"&gt;
          &lt;h1&gt;ONE&lt;/h1&gt;
        &lt;/div&gt;
      &lt;/section&gt;
      &lt;section&gt;
        &lt;div style="background:blue"&gt;
          &lt;h1&gt;TWO&lt;/h1&gt;
        &lt;/div&gt;
      &lt;/section&gt;
      &lt;section&gt;
        &lt;div style="background:orange"&gt;
          &lt;h1&gt;THREE&lt;/h1&gt;
        &lt;/div&gt;
      &lt;/section&gt;
    &lt;/core-animated-pages&gt;
  &lt;/template&gt;
&lt;/polymer-element&gt;

&lt;animated-sample&gt;&lt;/animated-sample&gt;</pre><p></p>

<p><code>core-aniamted-pages</code>の<code>transitions</code>属性で、使いたいトランジションの種類を宣言すると、中のコンテンツが切り替わるときにトランジションが適用されます。</p>

<h3>Paper Elementsのサンプルアプリ</h3>

<p>Paper Elementsを駆使することで、Material DesignがWebでどのように表現されるのかは、<a href="http://www.polymer-project.org/apps/topeka/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Topeka</a>というサンプルのクイズアプリが用意されています。スマートフォンにも対応しているので、モバイルデバイスでどの程度動いてくれるのかも、自分でさわって確かめてみると面白いはずです。</p>

<div id="attachment_9363" style="width: 1290px" class="wp-caption aligncenter"><a href="https://html5experts.jp/wp-content/uploads/2014/07/Quiz-App.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2014/07/Quiz-App.png" alt="http://www.polymer-project.org/apps/topeka/" width="1280" height="728" class="size-full wp-image-9363" srcset="/wp-content/uploads/2014/07/Quiz-App.png 640w, /wp-content/uploads/2014/07/Quiz-App-300x170.png 300w, /wp-content/uploads/2014/07/Quiz-App-1024x582.png 1024w, /wp-content/uploads/2014/07/Quiz-App-207x117.png 207w" sizes="(max-width: 1280px) 100vw, 1280px" /></a><p class="wp-caption-text">http://www.polymer-project.org/apps/topeka/</p></div>

<h2>さいごに</h2>

<p>今回はMaterial Designとそれを実現するPolymerとPaper Elementsについて、Google I/O 2014での情報をもとにご紹介しました。Material DesignもPolymerも、Preview版というステータスであり、まだ始まったばかりのプロジェクトです。これらが、今後どのように普及し、Webの世界にも影響を与えていくのか楽しみに思います。</p>

<p>先日開催された第49回HTML5とか勉強会でも「Material Design with Polymer」と題して、同じようなテーマについてご紹介しました。<a href="http://youtu.be/G7hIDm4aK5g?t=1h25m43s" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">YouTube</a>と<a href="https://speakerdeck.com/ahomu/material-design-with-polymer" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">SpeakerDeck</a>でそれぞれ当日の録画とスライドが公開されているので、こちらも合わせてご覧いただけると理解が深まるはずです。Material Designについて詳しく説明していたり、Paper Elementsを利用したオリジナルのデモを行っていたりもしますので、ぜひご覧ください。</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2014 特集]]></series:name>
	</item>
		<item>
		<title>Web Componentsが変えるWeb開発の未来</title>
		<link>/1000ch/8906/</link>
		<pubDate>Wed, 30 Jul 2014 00:00:21 +0000</pubDate>
		<dc:creator><![CDATA[泉水翔吾]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google I/O 2014]]></category>
		<category><![CDATA[Polymer]]></category>
		<category><![CDATA[Web Components]]></category>

		<guid isPermaLink="false">/?p=8906</guid>
		<description><![CDATA[連載： Google I/O 2014 特集 (7)Web Componentsが変えるWeb開発の未来 Google I/O 2014でEric BidelmanがPolymer and Web Components ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google-io-2014-2/" class="series-191" title="Google I/O 2014 特集" data-wpel-link="internal">Google I/O 2014 特集</a> (7)</div><h1>Web Componentsが変えるWeb開発の未来</h1>

<p>Google I/O 2014で<a href="https://google.com/+EricBidelman/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Eric Bidelman</a>が<a href="https://www.youtube.com/watch?v=8OJ7ih8EE7s" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer and Web Components change everything you know about Web development</a>というタイトルで、Web Componentsおよびその補完・拡張ライブラリであるPolymerについてセッションが行われました。</p>

<ul>
<li>「なぜWeb Componentsが生まれたのか」</li>
<li>「Web Componentsが何を解決してくれるか」</li>
</ul>

<p>この2点を上記セッションに沿って解説していきます。</p>

<h2>HTML/CSSが持つ弱点</h2>

<p>Webを構成していくパーツを作る際、今まではどのように行っていたでしょうか。<code>&lt;div&gt;</code>や<code>&lt;textarea&gt;</code>といったようなネイティブで用意されているタグに、CSSで見た目で装飾し、JavaScriptからDOMのAPIを操作してインタラクションを付与してきました。</p>

<p>しかし、このようにせっかく作った部品を再利用しようとすると、たちまちリスクを生んでいました。これはHTMLやCSSがスコープを持たず、既存のHTML/CSSを上書きし汚染してしまう可能性を持っていたためです。一般的なプログラム言語にはスコープが存在しますが、Cascading Style Sheetの名の通り、記述された内容は全て後勝ちで宣言されます。CSSのクラスはJavaScriptに例えるならば、全てグローバル変数のような存在であると言えるでしょう。</p>

<p>これに対して、開発者は様々な工夫を行ってきました。CSSに命名規則を設けてより強固な設計概念を作ったり、コンポーネント管理をJavaScript上で行うべくライブラリを作ったり…。しかしそれらは共通の構成を持っているわけでもなく、APIもバラバラです。つまりそのルールの元でしか通用せず、万人共通の解決策にはなりません。</p>

<h2>Web Componentsあらわる</h2>

<p>そこで生まれたのがWeb Componentsです。Web Componentsは以下の4つの仕様から構成されます。</p>

<ul>
<li><a href="http://www.w3.org/TR/components-intro/#custom-element-section" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Custom Elements</a> &#8211; Custom Elementsによってネイティブで実装されていない、新しいHTML要素を定義することが可能になりました。定義された要素はHTML中に書いたり、<code>document.createElement('new-element')</code>等、既存のタグと同じように使うことができます。</li>
<li><a href="http://www.w3.org/TR/components-intro/#template-section" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Templates</a> &#8211; Templatesは<code>template</code>タグを使った、DOMベースで利用可能なテンプレートの仕様です。HTMLをテンプレートとして利用したいケースは多々ありましたが、それを実現するには<code>script type='text/template'</code>等の、ハックアイデアを使うしかありませんでした。</li>
<li><a href="http://www.w3.org/TR/components-intro/#imports-section" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTMLImports</a> &#8211; HTMLImportsは<code>link</code>タグを使った、HTMLをロードするための新たな仕様で、これを使うことで断片化したHTMLのロードを容易に行うことができるようになります。HTMLにおいて、サブリソースのロードは珍しくありません。画像であれば<code>img</code>、音声であれば<code>audio</code>、スクリプトであれば<code>script</code>を使ってロードしますが、HTMLのロードは<code>iframe</code>を使う必要がありました。しかし、<code>iframe</code>を使ったロードは制限が多く、<code>XMLHttpRequest</code>を使う方法もコンポーネントのロードとしては利用し難いものです。</li>
<li><a href="http://www.w3.org/TR/components-intro/#shadow-dom-section" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Shadow DOM</a> &#8211; 前述の通りHTML/CSSにはスコープが存在しませんが、Shadow DOMがそれを解決します。DOMのAPIとして追加された<code>createShadowRoot()</code>を使うことで、Shadow Rootという他のDOMに干渉されないような新しいノードを生成します。</li>
</ul>

<p>Shadow DOMとTemplatesを使って新たな要素を構成し、Custom Elementsを使って定義します。それらを集約したHTMLファイルをHTMLImportsを使ってロードすることで、晴れて新しい要素を使うことが可能になります。これがWeb Componentsの考え方です。</p>

<h2>Web Componentsが解決してくれること</h2>

<p>セッション中にBidelmanも触れているとおり、既存のHTML+CSSによるWebページの構築は、混沌とした状態を生み出してしまうことは周知の事実です。
以下はGmailの例ですが、アプリケーションが複雑化すればするほどDOMのネストは深くなり、セマンティクス性は皆無です。</p>

<p><img src="/wp-content/uploads/2014/07/gmail.png" alt="gmail" width="100%"></p>

<p>でも、Web Componentsを使って要素を再定義して、もし以下のようにできたらクールではありませんか？</p>

<p></p><pre class="crayon-plain-tag">&lt;mail-label-list&gt;
  &lt;mail-label type='starred'&gt;スター付き&lt;/mail-label&gt;
  &lt;mail-label type='important'&gt;重要&lt;/mail-label&gt;
  &lt;mail-label type='sent'&gt;送信済みメール&lt;/mail-label&gt;
  &lt;mail-label type='draft'&gt;下書き&lt;/mail-label&gt;
&lt;/mail-label-list&gt;
&lt;mail-list&gt;
  &lt;mail-item title='...' to='...' from='...' datetime='...' label='...'&gt;&lt;/mail-item&gt;
  &lt;mail-item title='...' to='...' from='...' datetime='...' label='...'&gt;&lt;/mail-item&gt;
  &lt;mail-item title='...' to='...' from='...' datetime='...' label='...'&gt;&lt;/mail-item&gt;
&lt;/mail-list&gt;
...</pre><p></p>

<p>また、命名規則やJavaScriptのライブラリに頼ったコンポーネント化とは異なり、 <strong>標準化を目指したブラウザの仕様である</strong> ことも重要なポイントです。これは、仕様の策定が進み各ブラウザの実装が追いつけば、ライブラリや方法論に依存せずコンポーネントを再利用することができることを意味しています。</p>

<h2>Web Componentsが抱える課題等</h2>

<h3>ブラウザの対応状況</h3>

<ul>
<li><a href="http://youtu.be/8OJ7ih8EE7s?t=4m22s" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">2013年時のブラウザネイティブ対応状況</a></li>
<li><a href="http://youtu.be/8OJ7ih8EE7s?t=4m46s" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">2014年時のブラウザネイティブ対応状況</a></li>
<li><a href="http://youtu.be/8OJ7ih8EE7s?t=5m10s" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">PolymerのPlatform.jsのポリフィル利用時</a></li>
</ul>

<p>Web Componentsの過渡期であった2013年の段階では、ChromeとFirefoxが、Templates・Custom Elements・Shadow DOMをそれぞれ部分的にサポートしている状態でしたが、2014年のGoogle I/O時点ではChrome、Firefox、Operaが大半をサポートしているというところまで来ています。そして、Polymerチームが開発しているWeb Componentsのポリフィルライブラリである Platform.js を使うことでSafari、Internet Explorerを含めたほとんどのブラウザでWeb Componentsを利用することが可能になりました。</p>

<h3>パフォーマンス</h3>

<p>実行速度面についてはもちろん、実際に動作するPC・モバイルといったデバイスによって異なるので一概には言えませんが、プロセッサやメモリの進化はネットワーク等に比べて早いのと、ブラウザのJITコンパイル等の最適化が進むに連れて、気にならないレベルになるかと予想（期待）しています。</p>

<p>また、Webパフォーマンスの初歩としてHTTPリクエストを削減するというアプローチが広く浸透していますが、Web Componentsを使ったリソースの断片化は相反する関係にあると言えます。先程のブラウザの実装状況や仕様の策定状況を考慮しても、しばらくはPolymer等のポリフィルライブラリを利用するのが現実的かと思います。従ってWeb Components同士にHTMLImportに加えて、ネットワークを介して必要になるリソースが、今までより多くなるのは間違いないでしょう。</p>

<p><a href="https://github.com/Polymer/vulcanize" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer/vulcanize</a>という、事前にWeb Componentsを結合するビルドツールもありますが、ネットワーク越しにあるコンポーネントをロードしたいケースも多々あるでしょうから、今後更なる最適化アプローチが現れるかもしれません。</p>

<h2>Polymer Designerを使ったWeb Componentsの作成</h2>

<p>Polymerを使ったコンポーネントの作成は、ソースコードレベルでももちろん可能ですが、今回は<a href="http://www.polymer-project.org/tools/designer/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Polymer designer tool</a>を使ってみます。これはブラウザ上で、Polymerの要素を組み合わせて新たなコンポーネントをGUIで作ることが可能なサービスです。ちなみに、このサイト自体がPolymerを使ったWeb Componentsで構成されており、非常に興味深いです。</p>

<h3><code>yt-search-video</code> + <code>speech-mic</code></h3>

<p>今回は<a href="https://github.com/PolymerLabs/yt-video" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>yt-search-video</code></a>というYouTubeにある動画を検索し表示するコンポーネントと、<a href="https://github.com/PolymerLabs/speech-mic" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><code>speech-mic</code></a>というマイク入力を認識し扱うコンポーネントを組み合わせて、音声入力でYouTubeの動画を検索するコンポーネントを作成してみます。</p>

<h3>コンポーネントの選択</h3>

<p>画面右下の<strong>PALETTE</strong>にコンポーネントの一覧があります。使いたいものを選択し、画面左の方眼紙のようなキャンバスにドラッグアンドドロップします。今回は<code>yt-search-video</code>と<code>speech-mic</code>を配置します。</p>

<p><img src='/wp-content/uploads/2014/07/polymer-designer-palette.png' width='100%' alt="polymer-designer-palette"></p>

<p>配置されたコンポーネントは、<strong>TREE</strong>に一覧表示されます。 <strong>TREE</strong>中で選択している要素はキャンバス内でもハイライトされていたり、右上の<strong>PROPERTIES</strong> や <strong>STYLES</strong>の表示対象になったりと、直感的に使うことが可能です。</p>

<p><img src="/wp-content/uploads/2014/07/polymer-designer-tree.png" alt="polymer-designer-tree" width="100%"></p>

<h3>データバインディングの設定</h3>

<p>マイクの入力値をYouTubeの検索クエリと紐付けたいので、その設定を行います。マイクの入力値は<code>speech-mic</code>の<code>completeTranscript</code>なので、それを<code>yt-search-video</code>の<code>ImFeelingLucky</code>とバインディングします。</p>

<p><img src="/wp-content/uploads/2014/07/polymer-designer-property.png" alt="polymer-designer-property" width="100%"></p>

<h3>完成！</h3>

<p>これで完成です。画面左上の <strong>&lt;&gt;</strong> ボタンをクリックすると生成されたコードを見ることが可能で、実際の挙動もデザイナー上で確認することが可能です。生成されたコードや依存コンポーネントをインポートすれば、もちろん実際に<code>my-element</code>として使うことができます。簡単な手順で作成可能ですので、よかったら試してみてください。</p>

<p><img src="/wp-content/uploads/2014/07/polymer-designer-code.png" alt="polymer-designer-code" width="100%"></a></p>

<p>生成されたコードを見てみると、<code>completetranscript="{{ $.yt_search_video.ImFeelingLucky }}"</code>とPolymerのお作法通りにバインディングされています。このデータバインディングはWeb Componentsに備わっているわけではなく、Polymerが提供する強力な機能の1つです。</p>

<p></p><pre class="crayon-plain-tag">&lt;link rel="import" href="../components/polymer/polymer.html"&gt;

&lt;polymer-element name="my-element"&gt;

  &lt;template&gt;
    &lt;style&gt;    
      :host {
        position: absolute;
        width: 100%;
        height: 100%;
        box-sizing: border-box;
      }
      #yt_search_video {
        width: 300px;
        height: 300px;
        left: 280px;
        top: 160px;
        position: absolute;
      }
      #speech_mic {
        left: 640px;
        top: 290px;
        position: absolute;
      }
    &lt;/style&gt;
    &lt;yt-search-video id="yt_search_video"&gt;&lt;/yt-search-video&gt;
    &lt;speech-mic completetranscript="{{ $.yt_search_video.ImFeelingLucky }}" id="speech_mic"&gt;&lt;/speech-mic&gt;
  &lt;/template&gt;

  &lt;script&gt;

    Polymer('my-element', {
      
    });

  &lt;/script&gt;

&lt;/polymer-element&gt;</pre><p></p>

<h2>Web ComponentsおよびPolymerに関する資料</h2>

<h3>Polymer公式</h3>

<ul>
<li><a href="http://www.polymer-project.org/docs/start/getting-the-code.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Getting started</a> &#8211; Polymerの公式チュートリアルです。Web Componentsの基礎を抑えた後は、こちらをどうぞ。</li>
<li><a href="http://www.polymer-project.org/docs/polymer/polymer.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">API developer guide</a> &#8211; いざPolymerのデバッグをする時は、こちらを見ることになるかもしれません。</li>
</ul>

<h3>HTML5Rocks</h3>

<p>　HTML5RocksにもWeb Componentsに関する記事がいくつもあります。えーじさんが日本語訳をしてくれてます。</p>

<ul>
<li><a href="http://www.html5rocks.com/ja/tutorials/webcomponents/shadowdom/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Shadow DOM 101</a> &#8211; Shadow DOMの記事</li>
<li><a href="http://www.html5rocks.com/ja/tutorials/webcomponents/template/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML で利用可能になった Template タグ &#8211; クライアントサイドのテンプレートの標準化</a> &#8211; Templatesの記事</li>
<li><a href="http://www.html5rocks.com/ja/tutorials/webcomponents/customelements/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Custom Elements &#8211; HTMLに新しい要素を定義する</a> Custom Elementsの記事</li>
<li><a href="http://www.html5rocks.com/ja/tutorials/webcomponents/imports/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">HTML Imports &#8211; ウェブのための#include</a>HTML Importsの記事</li>
</ul>

<h3>Others</h3>

<p>ほかにも参考になるリソースがありますので紹介します。</p>

<ul>
<li><a href="http://blog.agektmr.com/2014/05/web-components.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">なぜ Web Components はウェブ開発に革命を起こすのか</a> &#8211; えーじさんの記事です。Web Componentsの歴史やコンセプトおよび、仕様策定の現状などがわかりやすく書かれているので、一読することをオススメします。</li>
<li><a href="http://ameblo.jp/ca-1pixel/entry-11815188808.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Componentsで行うHTMLのコンポーネント化</a> &#8211; こちらは私が以前会社のブログに寄稿したものです。Web Componentsの概要と利用方法を、コードまで落としこんで詳細に解説しています。</li>
<li><a href="http://developer.telerik.com/featured/web-components-arent-ready-production-yet/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Why Web Components Aren’t Ready for Production… Yet</a> &#8211; 英語です。ブラウザの対応状況、Polymerが行っているポリフィルの仕組み、パフォーマンスについての言及など、様々な考察がされています。</li>
</ul>

<h2>まとめ</h2>

<p>以上、簡単ではありますが、Web ComponentsとPolymerについて紹介しました。</p>

<p>Web Componentsが普及すれば、今までHTML/CSSが備えていなかったパーツの可搬性は解決され、コンポーネント（機能を含めたUIパーツ等）の流用は容易になり、今まで行っていた機能の再開発をする必要がなくなることも期待できます。</p>

<p>デザイナーがデザインし、ディベロッパーがHTML/CSSを組み、インタラクションをつける人がJavaScriptを書いているような分断されがちであったワークフローも徐々に境がなくなり、1つの機能単位でコンポーネントを実装するようなフローになっていくかもしれません。</p>

<p>今後もWeb Components/Polymerの動向に注目です。Web Components及びPolymerのより詳細な実装については、次回以降の記事で解説します。</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2014 特集]]></series:name>
	</item>
	</channel>
</rss>
