Polymer 2.0は、大くの主要ブラウザベンダーによって実装済みの新しいCustom Element v1とshadow DOM v1の仕様をサポートするように設計されています。また、Polymer 1.xユーザーに対してもスムーズな移行手段を提供しています。

Polymer 2.0はいくつかの面において改善がなされています。:

  • 相互運用性の向上:DOMの操作するのにPolymer.domがいらなくなったおかげで、Polymer製のコンポーネントを他のライブラリやフレームワークと併用することが簡単にできるようにしました。さらに、Shady DOMのコードは、Polymerに統合せず再利用可能なポリフィルに分離されています。

  • データシステムの改善:Polymer 2.0では、データシステムに対する改善も行いました。この変更により、エレメント内あるいはエレメント間におけるデータの伝播の流れが推測しやすくなりデバッグが容易になりました。

  • より標準に準拠:Polymer 2.0では、エレメントを定義するのにPolymerファクトリメソッドに替えて、標準ES6のクラスと標準のCustom Element v1のメソッド群を使用するようになっています。また、機能をミックスするには、Polymerのbehaviorではなく、標準のJavaScript(クラス式のmixin)を利用します。 (Polymerファクトリメソッドは互換レイヤを使用することで引き続きサポートされます)。

現時点ではいくつかのテストはChrome以外のブラウザでは失敗します。これらの問題はすぐに対処される予定ですが、当面はChrome Canaryを利用するのが最善の策です。

Polymer 2.0では、1.xとの互換性を破る変更がいくつも行われていますが、これらの多くは新しいCustom Elements v1とshadow DOM v1の仕様に準拠した結果です。仕様の新しいバージョンのリリースが近づけば、さらなる変更が見込まれます。

以下のセクションで、Polymer 2.0における主な変更点について解説します。Polymer 2.0へのエレメントのアップグレードに関する詳細は、Upgrade guideを参照してください。

Polymer 2.0のエレメントは、Custome Elements v1 APIに準拠することを目標としています。これによって、仕様v0に準拠するPolymer 1.xのいくつかの機能が変更されました。

主な変更点は:

  • Custome Elements v1仕様では、エレメントを定義にプロトタイプではなくES6のクラス構文を使用します。

Polymer 2.0では、エレメントを拡張するのにES6ベースの基底クラス(Polymer.Element)を提供することで、ネイティブのES6の様式を利用できるようにします。なお、Polymerファクトリメソッドを利用したレガシーなエレメントについても、Polymer 1.x互換レイヤーで引き続きサポートされています。

  • 新しい仕様では、ライフサイクルコールバックのいくつかに変更が加えられています。特に目立った変更点は、createdコールバックに代えてclassのconstructorを呼び出すようになった点です。また仕様では、constructor(Polymer 1.xのcreatedコールバックに相当)内において行われる処理に関して新たに制限も課されています。

  • なお、仕様でサポートされているエレメントのタイプ拡張(is =)は、Polymer 2.0では現時点においてはサポートしていません。

  • 複雑であることを理由に新しい仕様で定義されたdisable-upgradeに関して、Polymer 2.xはサポートしていません。今後、ミックスインやアドオンとして提供される可能でしはあります。

以降のセクションでは、これらの変更点について詳しく解説します。

Custom Elements v1仕様の一般的な情報に関しては、Web FundamentalsのCustom elements v1: reusable web componentsを参照してください。

クラスベースのエレメントを作成した場合には、新しいネイティブのライフサイクルメソッド(仕様ではCustom Elemnetsの「リアクション(reaction)」と呼ばれます)が利用されます。ファクトリメソッドPolymerを利用してレガシーなエレメントを作成する場合には、従来通りのPolymerのコールバック名が利用されます。

       
リアクション/コールバック名 説明
constructor (ネイティブ)

created (レガシー)

    Custom Elements v1仕様では、constructor内のDOM API(従来のAPIではcreatedコールバック)から属性、子、または親の情報を読み取ることを禁止しています。同様に、constructor内においては、属性や子は追加されないおそれがあります。そのような作業はすべて遅らせるようにしましょう(例えば、connectedCallbackまで)。     レガシーなcreatedコールバックは、propertiesのデフォルト値が設定される前に呼び出されることはなくなりました。そのため、createdの中で設定されたプロパティを、エレメントのデフォルト値を定義するvalueの関数から参照することがないようにしてください。

      その一方で、properties内のvalueで関数を定義する代わりに、createdコールバックの中であらゆるデフォルトのプロパティを設定できるようになりました。(Polymer 1.0では監視対象のプロパティ(observed properties)に対してこのような方法で設定を行うことが禁止されていました。)

connectedCallback (ネイティブ)

attached (レガシー)

Polymer 1.xでは、初回のレンダリングまでattachedコールバックの実行を遅延していたので、エレメントは自身やその子にアクセスすることができました。
disconnectedCallback (ネイティブ)

detached (レガシー)

attributeChangedCallback (ネイティブ)

attributeChanged (レガシー)

    属性を監視するには明示的に登録する必要があります。

      Polymer Elementの場合、propertiesオブジェクト内で明示的に宣言されたプロパティだけが属性の変更を追跡(tracking)できます。(つまり、属性の値を変更したとき、attribute changedコールバックが呼び出され、Polymerは属性からプロパティの値をセットします)。

      Custom Elemnets v0では、いかなる属性の変更に対してもattributeChangedCallbackを呼び出していました。

      Polymer 1.xでは、明示的に宣言されたプロパティと暗黙的に宣言されたプロパティの両方に対して属性のデシリアライズが行われていました。例えば、propertiesには宣言されてはいないが、バインディングで利用された場合やオブザーバーの依存部に使用された場合には、プロパティが暗黙的に宣言されたものと見なされます。

ready (Polymer独自の仕様) Polymerは、もはやreadyが呼び出される前に、最初のLight DOMの割り当て(distribution)が完了していることを保証しません。

コールバックの変更に加えて、lazyRegisterオプションが削除された点や、すべてのメタプログラミング(テンプレートの解析、プロトタイプ上のアクセサの作成など)は、エレメントの最初のインスタンスが生成されるまで遅延されるようになった点に注意してください。

Polymer 2.0は、タイプ拡張エレメントをサポートしていません(例:<input is="iron-input">)。Custom Elements v1の仕様では、タイプ拡張は、(「カスタマイズされたビルトインエレメント(customized build-in elements)」として)含引き続きサポートされておりまれ、Chromeでは実装が計画されています。しかし、Apple社は、isをサポートしないことを表明しており、不確定な仕様にCustom Elementsのポリフィルが依存するのを避けるため、我々は今後isを利用したタイプの拡張を推奨しません。代替的な手段として、ネイティブエレメントをラッパーのCustom Elementで囲むことでタイプの拡張ができるようになっています。

例えば:

<a is="my-anchor">...</a>

上記は次のように扱うようになります:

<my-anchor>
  <a>...</a>
</my-anchor>

ユーザーは、必要に応じて既存のタイプ拡張エレメントを置き換える必要があるかもしれません。

Polymerによって提供されるテンプレートのタイプ拡張(例えばdom-binddom-ifdom-repeat)はすべて、標準のCustom Elementsと同様に、Light DOM内に<template>を含めるようになりました。例えば:

1.xの場合、コードは次のようになります。:

<template is="dom-bind">...</template>

2.xでは、次のようになります。:

<dom-bind>
  <template>...</template>
</dom-bind>

Polymer Elementのテンプレート内部(つまり、dom-moduleの内部)でこれらが使用された場合、Polymerはテンプレートのタイプ拡張(例:dom-ifdom-repeatなど)をテンプレートを処理する際に自動的にラップします。つまり、Polymer Elementの内部にネストされたテンプレートや他のPolymerのテンプレート(例:dom-bind)においては、<template is="">を使い続けることができ、またそうすべきことを意味します。

index.htmlのようなメインドキュメントテンプレートを利用する場合には、手動でラップする必要があります。

custom-styleエレメントも標準仕様のCustom Elementのように、<style>エレメントをラップするように変更されました。

例えば:

<style is="custom-style">...</style>

上記は、以下のようになります:

<custom-style>
  <style>...</style>
</custom-style>

参照:

Polymer 2.0はShadow DOM v1をサポートしています。Polymerユーザーにとって、Polymer 1.0と2.0の主要な違いは、<content>エレメントが、v1仕様の<slot>エレメントに置き換えられたことです。

Polymer 1.xに含まれていたShady DOMとそれに関連するCSSカスタムプロパティのshimは、Polymerライブラリ本体からは取り除かれ、ポリフィルwebcomponents-lite.jsのバンドルに追加されました。新バージョンのShady DOMでは、代替のAPI(Polymer.dom)を公開せず、ネイティブDOM APIにパッチを当てることで、Polymer 2.0ユーザーはネイティブのDOM APIを直接利用できるようになりました。

ハイブリッドエレメントの場合、Polymer 2.0にネイティブのAPIに直接振り向けるPolymer.domAPIの新たなバージョンが含まれています。2.0だけに依存するエレメントに対しては、ネイティブのDOM APIを選択することでPolymer.domを取り除くこともできます。

Web Fundamentalsで詳細を確認。Shadow DOMの概要については、Shadow DOM v1:self-contained web componentsを参照してください。

v1への仕様の変更に関する、簡潔で包括的な事例は、Hayato ItoのWhat's New in Shadow DOM v1 (by examples)を参照してください。

Polymer 2.0は、データシステムにいくつかの改善を導入しています。:

  • 配列操作がよりシンプルになりました。抽象レイヤPolymer.Collectionや配列アイテムへのキーベース(key-based)のパスがなくなりました。(訳注:Collectionオブジェクトについては、Polymer 1.0ドキュメントのObservers and computed propertiesのObserve array mutationsを参照してください。)

  • データの変更をバッチで処理することで、パフォーマンスと正確性が向上しました。

  • オブザーバー、算出バインディング、および算出プロパティにおいて未定義(undefined)の依存部のチェックがなくなりました。これらはすべて初期化の際に一度だけチェックが行われます。

  • エレメントにオプションとしてミックスインを加えることで、オブジェクトや配列のダーティチェック(dirty check)を抑制することができます。これによって、オブジェクトや配列として宣言されたプロパティに監視可能((obsevable)な変更を加えた際、Polymerはそのプロパティ以下すべて(サブプロパティ、配列のアイテム)を再評価します。これは、Polymerの提供するsetメソッドや配列変更メソッドが使用できないアプリケーションや、不変データ(immutable data)パターンを使用しない場合に役立ちます。(訳注:ダーティーチェックとはエレメントがオブジェクトや配列の変更をチェックして、無駄なプロパティエフェクトが生じないようにする仕組みです。詳細は、データシステムのコンセプトのセクション内の可変データのミックスインに関する説明を参照してください。)

  • プロパティエフェクト(property effect)の順序が変更されました。

  • propertiesで明示的に列挙されたプロパティに限り、属性から設定を行うことができるようになりました。

  • エレメントの初期化(テンプレートのスタンプ処理やデータシステムの初期化を含む)は、エレメントがメインドキュメントにコネクトされるまで遅延されます。(これはCustom Elements v1の仕様変更を受けた結果です)。

  • その他小さな変更がいくつかの行われています。

以降のセクションでは、これらの変更点について詳しく解説していきます。

Polymer 1.xでは、ダーティチェックメカニズムを使用して、データシステムが余分な作業をするのを抑制していました。

Polymer 2.xにおいても、デフォルトでこのメカニズムの利用し続けてますが、エレメント自身がオブジェクトや配列のダーティチェックを行うかどうかオプトアウト(ユーザー自身がデフォルトの機能を利用しないことを選択)できるようになっています。

デフォルトのダーティチェックメカニズムを使用した場合には、次のコードにおいてプロパティエフェクトが生じることはありません。:

this.property.subproperty = 'new value!';
this.notifyPath('property');

propertyが参照するのは同一のオブジェクトでありダーティチェックは失敗します。そのためサブプロパティに対する変更がプロパティエフェクトによって伝播するありません。そこで代わりに、Polymerの提供するsetメソッドや配列変更メソッドを使用するか、変更された正確なパスに対してnotifyPathを呼び出す必要があります。:

this.set('property.subproperty', 'new value!');
// または
this.property.subproperty = 'new value!';
this.notifyPath('property.subproperty');

一般的に、ダーティチェックメカニズムの利用はパフォーマンス上好ましい手段です。そのため以下の要件が一つでも当てはまるアプリケーションにおいてはうまく機能します。:

  • 不変データを使用する。
  • ちょっとした変更に対しても常にPolymerの提供するデータ変更メソッドを利用する。

一方で、不変データを使用しなかったり、Polymerの提供するデータ変更メソッドを利用できないシュチュエーションに対して、Polymer 2.0はオプションとしてMutableDataミックスインを提供しています。MutableDataミックスインはダーティチェックを回避し、上記のコードは意図した通り動作します。また、プロパティエフェクトの発生前にいくつかの変更をまとめてバッチ処理することも可能です。:

this.property.arrayProperty.push({ name: 'Alice' });

this.property.stringProperty = 'new value!';
this.property.counter++;
this.notifyPath('property');

setメソッドを用いることもできますし、単にトップレベル(top-level)のプロパティを設定することでプロパティエフェクトを発生させることもできます:

this.set('property', this.property);
// または
this.property = this.property;

特定のサブプロパティを変更するのにsetメソッドを使用するのが多くの場合最も効率的な方法です。しかし、MutableDataを利用するエレメントは、このAPIを利用する必要はありません。そうすることで、データバインディングや状態管理を行うライブラリとの互換性が向上するからです。

トップレベルでプロパティを設定し直すと、プロパティやそのサブプロパティ、あるいは配列アイテムなどに対するすべてのプロパティエフェクトが再度実行さるので注意が必要です。ワイルドカードパスを指定したオブザーバー(例:prop.*)には、トップレベルの変更だけが通知されます。

// 'property.*'に設定されたオブザーバーは、パス`prperty`に変更があった場合に実行されます。
this.property.deep.path = 'another new value';
this.notifyPath('property'); // トップレベルのプロパティへ変更を通知する必要があります。

setメソッドを使って特定のパスを設定すると、細かな通知も生成されます。:

// 'property.*'に設定されたオブザーバーは、パス`prperty.deep.path`に変更があった場合にも実行されます。
this.set('property.deep.path', 'new value');

Polymer.CollectionAPIとそれに関連した、配列でのキー(key)ベースのパス指定やspliceによる通知は削除されました。

この仕様変更には他にもいくつか利点があります。:

  • プリミティブな値による配列がサポートされます。
  • 配列アイテムはユニーク(一意)である必要はありません。

キー(key)によるパスが削除されたので、配列のsplice通知にkeySplicesは利用できず、indexSplicesプロパティだけが使えます。

バインディングシステムにおいてデータの伝播をバッチで処理するようになりました。それによって、コンプレックスオブザーバーや算出(computing)関数は、複数のまとまった(coherent)変更に対して実行されます。変更をまとめるには、2つの方法があります。:

  • エレメントがプロパティを初期化する際は、まとめられた変更のセットが自動的に生成されます。

  • 新たに導入されたsetPropertiesメソッドを使用することで、まとまりのある変更のセットをプログラムで生成することもできます。

this.setProperties({ item: 'Orange', count: 12 });

単一プロパティのアクセサ(accessors)については、なおもデータの伝搬は同期的に行われます。例えば、abの二つのプロパティを監視するオブザーバーがあるとします。:

// オブザーバーは二度実行されます
this.a = 10;
this.b = 20;

// オブザーバーは一度だけ実行されます
this.setProperties({a: 10, b: 20});

2.0では、オブザーバーはプロパティ変更通知の前に実行されます。 2.0におけるプロパティエフェクトの順序は次の通りです。:

  • 算出プロパティを再計算する。
  • データバインディングに値を伝播します。
  • プロパティを属性に反映します。
  • オブザーバーを実行する。
  • プロパティ変更通知を発行する。

1.xでは、オブザーバーはプロパティ変更通知に続けて最後に実行されていました。

2.0では、オブザーバーが未定義(undefined)の依存部をもったまま実行されるのを防ぐためのチェック機構が削除されました。

詳細に説明すると:

  • 一つでも依存部が定義されている場合、マルチプロパティオブザーバー、算出プロパティ、算出バインディングが、初期化時に一度実行されます。

  • オブザーバーまたは算出関数は、引数としてundefinedを受け取る可能性が生じてくるので、これを正しく扱う処理が必要です。

2.xでは、オブザーバーや算出プロパティをインスタンスごとに動的に定義する機能も追加されています。 詳細は以下のセクションを参照してください。

Add observers and computed properties dynamically.

  • 算出バインディングで使用される関数を設定または変更すると、バインディングシステムは新しい関数と最新のプロパティ値を用いて再度計算を実行します。例えば、以下のようにバインディングを指定したとします。:

    some-property="{{_computeValue(a, b)}}"
    

以下のように_computeValue関数を変更すると、abが変化しなくてもバインディングは再評価されます。:

```js
  this._computeValue = function(a, b) { ... }
```
  • ホストからのバインディングによって値が変化する場合には、プロパティ変更通知(property-changed events)が発行されることはありません。
  • プロパティから属性へデシリアライズする際は、その属性をproperties内のメタデータオブジェクトとして宣言する必要があります。Polymer 1.xでは、暗黙的に(implicitly)宣言されたプロパティ(例えば、バインディングの対象やオブザーバーの依存部として記述されたプロパティ)であってもデシリアライズが行われていました。

Polymer 2.0は、現在のPolymer 1.0ユーザーが引き続きインポートできるようにpolymer/ polymer.htmlを残したままにしています。このインポートには、エレメントを定義するためのレガシーなPolymer関数が含まれ、Polymer 1.0のAPIで書かれたコードとの互換性の破綻を招く変更を最小限に抑えるよう配慮がなされています。

ほとんどの場合、既存のユーザーがPolymer 2.0にアップグレード際に求められるのは、contentの割り当てやスタイリングに関連したShadow DOM v1 APIに準拠させることと、Custom Elements v1 APIの仕様改訂に伴うわずかな変更を既存のコードに加えることだけです。

不必要なコードを減らすという目的に従い、ES6ベースの新たなエレメントPolymer.Elementにおいては、様々なメソッドやプロパティが取り除かれています。削除されたAPIはいくつかのカテゴリに分類できます。:

  • ネイティブDOM APIに付加されていたシンプルな機能(例:firetrasform)
  • まれにしか使用されない属性やプロパティ(例:attributeFollowsclassFollowsなど)
  • インスタンスに関連しないメソッドやプロパティ(例:1.xでは、importHrefはインスタンスメソッドでしたが、コールバックのバインディング以外にインスタンス固有の処理を行うことはありませんでした。)

削除または移管されたAPIの包括的なリストは、Polymer.ElementAPIの最終的な仕様が確定した後に公開する予定です。

リリース時点においてPolymer 2.0は、Polymer 1.xと同様に次のブラウザをサポートします。Polymer 1.xーIE 11、Edge、Safari(9+)、Chrome、Opera、Firefox

Polymer 2.0はCustom ElementsとShadow DOMの新しい仕様(v1)に互換のあるポリフィルと一緒に開発されテストされてきました。Polymer 2.0をテストするには、1.0.0-rc.7より上位バージョンのwebcomponentsjsを使用します。webcomponentsjsは、bowerのdependenciesにおいてPoymer 2.xを指定することでバンドルされてきます。

ポリフィルを読み込む方法はいくつか存在します。:

  • webcomponents-lite.jsには、上記サポート対象の全ブラウザで動作するのに必要な全てのポリフィルが含まれています。
  • webcomponents-loader.jsは、実行時に機能検出(feature-detection)を行い、必要な場合にはポリフィルが読み込まれます。

上記以外の方法を選択した場合とそのトレードオフについて解説を読む:

Polymer 2.xや2.xのクラススタイルのエレメントは、次世代の標準JavaScriptであるEcmaScript 2015(一般的にはES6として知られています)を使って記述されています。これは、Custom Elementの新たな仕様が要求するものです。ES6に馴染みがない場合、Polymerで使用されているES6の基本の理解が参考になります。特に、以下の機能はコード例で広く使用されています。:

ウェブ上には、以下のような様々な学習用の情報が用意されています。:

最新のChrome、Safari 10、Safari Technology Preview、Firefox、およびEdgeでは、ES6をコンパイルすることなく実行できます。IE11とSafari 9でPolymer 2.xを実行するにはコンパイルが必要です。

Polymer CLIやpolymer-buildライブラリは、ビルド時にES6からES5へのトランスパイルをサポートしています。さらに、ブラウザが必要とする場合には、polymer servepolymer testといったコマンドも実行時にトランスパイルを行います。

より詳細な情報は、Browser compatibilityを参照してください。

bowerを使って、最新のPolymer 2.xリリースをインストールできます。

bower install --save Polymer/polymer#^2.0.0

bowerを使って、現時点で利用可能なハイブリッドエレメントをインストールすることもできます。:

bower install --save PolymerElements/paper-button#^2.0.0

既存のコードをPolymer 2.0上で動作させる方法については、Upgrade guideを参照してください。

開発チームは、Polymer 1.7+と2.xの双方に互換性のある、新しい「ハイブリッド」フォーマットを利用できるようにPolymer Elementをアップデート中です。

以下のエレメントはすでにPolymer 2.0をサポートするようにアップデートが完了しており、アップデート処理は不要です。: