Why you should
(and shouldn't)
use web components
ABOUT ME
name Jeremias Menichelli
from Argentina
now in Barcelona
work as a front end developer
twitter jeremenichelli
github jeremenichelli
MOTIVATIONS
web components? LOL
They're not React components, that means they suck. End of the conversation.
JUST use web components
Throw your React components away and #useThePlatform.
strong takes are
usually
WRONG
SUMMARY
- Specifications
- Declaration
- Encapsulation
- Templating
- Data initialization and flow
- The good things and the bad things
- The future of web components
CUSTOM ELEMENTS
// <movie-box></movie-box>
class MovieBox extends HTMLElement {
constructor() {
super();
}
connectedCallback() { }
disconnectedCallback() { }
adoptedCallback() { }
attributeChangedCallback() { }
}
customElements.define('movie-box', MovieBox);
- powered by the browser
- class, extends
- life cycle hooks
- global elements store
SHADOW DOM
// <movie-box title="Batman Begins (2005)"></movie-box>
class MovieBox extends HTMLElement {
constructor() {
super();
this._root = this.attachShadow({ mode: 'closed' });
this._root.innerHTML = `
<style>
.title { background: #f9aaac; }
</style>
<h2 class="title">
${ this.getAttribute('title') }
</h2>
<slot></slot>
`;
}
}
- styles encapsulation
- content encapsulation
- slots
- parsing cost
TEMPLATE TAG
const template = document.createElement('template');
template.innerHTML = `
<style>
.title { background: #f9aaac; }
</style>
<h2 class="title"></h2>
<slot></slot>
`;
class MovieBox extends HTMLElement {
constructor() {
super();
this._root = this.attachShadow({ mode: 'closed' });
this._root.appendChild(template.content.cloneNode(true));
}
}
- one time parsing cost
- no data interpolation
INITIAL DATA FLOW
// <movie-box title="Batman Begins (2005)"></movie-box>
class MovieBox extends HTMLElement {
connectedCallback() {
const title = this._root.querySelector('.title');
title.textContent = this.getAttribute('title');
}
}
static, no reactive
REACTIVE DATA FLOW
with attributes
class MovieBox extends HTMLElement {
static get observedAttributes() {
return [ 'title' ];
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'title') {
const title = this._root.querySelector('.title');
title.textContent = this.getAttribute('title');
}
}
}
- initial declarative data
- reactive
- limited to strings
// const movie = document.createElement('movie-box');
// movie.title = "Batman Begins (2005)"
class MovieBox extends HTMLElement {
set title(value) {
const title = this._root.querySelector('.title');
title.textContent = value;
}
}
- non data type limit
- reactive
- non declarative
REACTIVE DATA FLOW
with properties
THE GOOD STUFF
- browser element factory in our hands
- no parsing cost ahead
- styles encapsulation
- content encapsulation and allocation
- reactive to data changes
THE BAD STUFF
- global elements store
- no data interpolation
- internal data management boilerplate
- browser support
developer experience
"Unfortunately the developer experience of building an application with web components today is quite painful"
Sam Saccone, Developer Advocate at Google
Developer experience can be solved by us
SOLVING some OF THE DOM MANIPULATION FRICTION
import collectRefs from 'web-component-refs';
const template = document.createElement('template');
template.innerHTML = `
<h2 class="title" ref="title"></h2>
`;
class MovieBox extends HTMLElement {
connectedCallback() {
collectRefs();
// this.refs.title -> <h2 class="title"></h2>
}
}
- works the same as ref strings in Vue and React
- tracks updates using MutationObserver
web components
solution for DOM manipulation
solution for data management
solution for elements definition
polyfill
framework
WHEN?
NOW
- Polymer (https://www.polymer-project.org/)
- skateJS (https://github.com/skatejs/skatejs)
- StencilJS (https://stenciljs.com)
- VueJS is working on it
RESOURCES
web components are not here to wipe frameworks out, they are here to empower them.
Why you should (and shouldn't use) web components
By Jeremias Menichelli
Why you should (and shouldn't use) web components
- 972