A Guide to Upgrading to Polymer 1.0
At the recently concluded Google IO 2015, Google released the much awaited 1.0 version of Polymer and declared it production-ready. For those of you who have been using the Polymer library while it was still in developer preview, this article will serve as a guide to migrate your existing application to the latest version of Polymer.
A few important things to note about v1.0:
- It is incompatible with version 0.5, the previous version and the longest surviving so far.
- The new release is focused on performance and efficiency while dramatically reducing the overall size of the library.
- It has been completely rebuilt from the ground-up to make it easier and faster for developers to design custom elements that work more like standard DOM elements.
- Internal benchmark tests reveal that v1.0 is about 3x faster on Chrome and 4x faster on Safari compared to the previous version.
The steps to install the latest version of Polymer remain exactly the same as described in this article. To update an existing installation of Polymer, navigate to the app directory and run the following command in your terminal:
$ bower update
It’s important to be aware that this will certainly break your existing app, since, as mentioned, the two versions are incompatible. Hence, installing a fresh copy in a separate folder is recommended instead. To illustrate the changes since v0.5, we’ll use the credit card custom element from one of my previous articles on SitePoint as a reference to draw comparisons between the two versions.
Polyfilling non-supporting browsers
The new version of Polymer no longer needs the shadow DOM polyfill included in the webcomponents.js
library. Instead use the much smaller webcomponents-lite.js
library to polyfill older browsers.
Version 0.5:
<script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>
Version 1.0:
<script src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
The “lite” version offers a size gain of approximately 80kb
over its predecessor, which could be significant when performance is a key factor.
Defining custom elements
The <polymer-element>
tag has been replaced by the <dom-module>
tag that holds the definition of a custom element. The custom element is now identified by the id
attribute of the <dom-module>
tag. The rules to name the custom element still remain the same.
Version 0.5:
<polymer-element name="credit-card">
...
</polymer-element>
Version 1.0:
<dom-module id="credit-card">
...
</dom-module>
Register custom elements
Previously, we could register the custom element by simply invoking the Polymer()
constructor. Specifying the custom element name was optional if the <script>
tag was inside the <polymer-element>
tag. In this release, the custom element is now registered by using the is
property on the prototype.
Version 0.5:
Polymer('credit-card', {});
Version 1.0:
Polymer({
is: 'credit-card'
});
The value of the is
property must match the id
attribute of the <dom-module>
tag of the custom element and, unlike the previous release, this is not optional.
The <script>
tag can be inside or outside of the <dom-module>
element, but the element’s template must be parsed before the call to the Polymer constructor.
Custom element attributes
Any attribute that is part of the <polymer-element>
tag should now be declared on the properties
object along with the data type.
Version 0.5:
<polymer-element name='credit-card' attributes='amount'>
Version 1.0:
Polymer({
is: 'credit-card',
properties: {
amount: {
type: Number
}
}
Custom element styles
The element styles are now defined outside the <template>
tag.
Version 0.5:
<polymer-element name="credit-card" attributes="amount">
<template>
<style>
...
</style>
</template>
</polymer-element>
Version 1.0:
<dom-module id="credit-card">
<style>
...
</style>
<template>
...
</template>
</dom-module>
External stylesheets are supported using HTML Imports.
Data binding
Polymer 1.0 offers two types of data bindings:
- Square brackets
[[]]
create one-way bindings. Data flow is downward, host-to-child, and the binding never modifies the host property. - Curly brackets
{{}}
create automatic bindings. Data flow is one-way or two-way, depending whether the target property is configured for two-way binding or not.
In this release, a binding must replace the entire text content of a node, or the entire value of an attribute. So string concatenation is not supported. For attribute values, it is recommended to use computed bindings instead of string concatenation.
Version 0.5:
<input type="submit" value="Donate {{amount}}">
Version 1.0:
<template>
<input type="submit" value="[[computeValue(amount)]]">
</template>
Polymer({
is: "inline-compute",
computeValue: function(amount) {
return 'Donate ' + amount;
}
});
Note that this means a node can’t include any white space around the binding annotation.
The new shady DOM
Polymer v0.5 used shadow DOM to provide a simpler element interface to the developer and abstracts all the complexities by hiding the subtrees behind a shadow root. This forms the basis of encapsulation, which works well in browsers that supports shadow DOM.
For browsers that do not yet support shadow DOM, implementing a polyfill that works exactly like native shadow DOM is difficult, often slower than the native implementation, and needs a lot of code. For these reasons, the Polymer team decided to do away with the shadow DOM polyfill and instead built a much lighter version of the local DOM that offers encapsulation similar to shadow DOM.
It’s important to note that shady DOM and shadow DOM are compatible with each other, which means that the shady DOM API uses the native shadow DOM in browsers when it’s available and falls back to the shady DOM in non-supporting browsers.
Conclusion
Upgrading your app to Polymer v1.0 could be a painfully slow process depending on the complexity of your app, but offers great benefits in terms of faster load time and significantly smaller payload. The official migration guide available on the Polymer project website covers a bunch of the other changes to the internal APIs in greater depth so be sure to check that out.
Additionally, Chuck Horton has set up a Github repository called Road to Polymer 1.0 that offers a code convert tool to update your code to v1.0 from v0.5. This could serve as a starting point for your migration if you’re not up to making some of the cosmetic changes manually.