HTML Web Components – The future of web development? – How we'll get there



HTML Web Components – The future of web development? – How we'll get there

0 2


web-component-presentation


On Github thedeeno / web-component-presentation

HTML Web Components

The future of web development?

Created by Dane O'Connor / @thedeeno

Survey

Goal

Understand the tech driving a more composable web

How we'll get there

The Big Picture

  • What are web components?
  • What is google polymer?

Practical Example

Refactor a well-written traditional component

Adoption Challenges

What's in the way?

The Big Picture

Web Components

  • Are not a Silver bullet
  • Are not just for UI
  • Are not an application framework

Web Components

are a suite of standards

  • HTML Imports
  • Templates
  • Shadow DOM
  • Custom Elements

that increase our application's

  • expressiveness
  • reusability
  • indepedence

Polymer

The WC Standards + Declarative Sugar + Data-Binding

An opinionated way to create web components

and also Polyfills for browser support

That's all there is too it

Bye Bye Theory Land

Practical Example

progressive refactoring

To the Code!

the tuner component

First Smell?

HTML Imports: Abstract

include and reuse HTML documents in other HTML documents.

HTML Imports: Usage

<link rel="import" href="path/to/resource.html">

OR

var link = document.createElement('link');
link.rel = 'import';
link.href = 'path/to/resource.html'
link.onload = function(e) {...};
link.onerror = function(e) {...};
document.head.appendChild(link);

// you can work with the imported document
var content = document.querySelector('link[rel="import"]').import;

Refactor 1

results

Next Smell?

Custom Elements: Abstract

define and register new DOM elements

Custom Elements: Registration

default prototype

document.registerElement('x-foo');

custom prototype

var myProto = Object.create(HTMLElement.prototype);
myProto.awesome = function() { alert('yeah!') };
document.registerElement('x-foo', { prototype: myProto });

Custom Elements: Instantiation

Declare

<x-foo></x-foo>

DOM manipulation

var xFoo = document.createElement('x-foo');

`new` Operator

var xFoo = new XFoo();
document.body.appendChild(xFoo);

Refactor 2

results

Next Smell?

Templates: Abstract

Inert HTML

Templates: Usage

declaration

<template id="mytemplate">
  <div>my content</div>
</template>

activation

// clone and append the template
var t = document.querySelector('mytemplate');
var clone = document.importNode(t, true);
document.body.appendChild(clone);

Templates: Notes

<template id="mytemplate">
  <div>my content</div>
</template>
  • Content is parsed but stays inert until activated
  • Script tags don't run, images don't load, etc
  • Content is NOT considered part of the document
  • Can be placed anywhere

No more hacks!

Refactor 3

results

Next Smell?

ShadowDOM: Abstract

Create and layout isolated DOM trees

ShadowDOM: Usage

initial DOM

<style>my-foo { background: red; }</style>
<my-foo>
  <my-bar></my-bar>
</my-foo>

create and inject shadow root

var host = document.querySelector('#my-bar');
var root = host.createShadowRoot();
root.innerHTML = [
  '<style>my-foo { background: red; }</style>'
  '<my-foo></my-foo>'
].join('\n');

result

<style>my-foo { background: red; }</style>

<my-foo><!-- red -->
  <my-bar>
    $shadowRoot$
      <style>my-foo { background: blue; }</style>
      <my-foo></my-foo><!-- blue -->
  </my-bar>
</my-foo>

Refactor 4

results

Next Smell?

Polymer: Abstract

An opinionated way to do everything we just did

Polymer: Usage

a convention to leverage

<link rel="import" href="polymer.html">

<polymer-element name="rapidsynapse-dial">
  <template>
    <!-- content -->
  </template>
  <script type="text/javascript">
    Polymer({
      <!-- prototype -->
    });
  </script>
</polymer-element>
  • Templates
  • ShadowDOM
  • CustomElements

Polymer: Usage Cont.

declarative sugar and databinding

<polymer-element name="rapidsynapse-dial">
  <template>
    <div on-click="{{ increment }}">{{ formattedMessage }}</div>
  </template>
  <script type="text/javascript">
    Polymer({
      // read-write (bindable)
      publish: {
        'message': 'hello world'
      },
      // read-only (bindable)
      computed: {
        'formattedMessage': 'format(message)'
      },
      // private
      count: 0,
      // methods
      formatMessage: function(message) {
        return 'foo bar' + this.count;
      },
      increment: function() {
        this.count = this.count + 1;
      }
    });
  </script>
</polymer-element>

Refactor 5

results

Review

Challenges

debug issues

tooling (like testing)

browser support

performance

Conclusion

Thanks!

Questions?

Created by Dane O'Connor / @thedeeno

Contact: dane@rapidsynapse.com