Fast, Reactive Web Components

André Gonçalves

Web Components

 

  • Natively-supported, standardized JavaScript components
  • Reusable and encapsulated away from the rest of your code
  • Run in every framework or on their own
  • Answer to the shared-component problem
  • Native browser support: Chrome, Safari, good polyfills

Web Components

  • Custom Elements
  • HTML Templates
  • Shadow DOM
  • HTML imports

Custom Element Example


<my-component size="large" theme="light"/></my-component>
					

Custom Element Example


class MyComponent extends HTMLElement {
	createdCallback() {
		// Standard DOM/fetch/etc. code...
	}
	attachedCallback() {}
	detachedCallback() {}
	attributeChangedCallback() {}
}

document.registerElement('my-component', MyComponent);
					

Making it easier to build Custom Elements

  • Framework features
  • Desire to manage bundles of components
  • Automatic Polyfilling when necessary

Stencil: A Compiler for Web Components

What is Stencil?

  • A compiler that generates Custom Elements, part of the Web Components spec
  • Not a framework: output is 100% standards-compliant Custom Elements
  • Adds powerful framework features to Web Components
  • Created and used heavily by the Ionic Framework team. Ionic 4+ is built on it!

Why?

  • Performance: Traditional frameworks proving too heavy for demanding mobile Progressive Web Applications
  • Stability: Desire to use web standards and avoid constant framework churn
  • Interoperability: Ability to create components that work across all major frameworks.
  • Familiarity: features from frameworks but in a leaner, standards-compliant package

Example Stencil Component

						
						import { Component, Prop } from '@stencil/core';

						@Component({
						  tag: 'my-name',
						  styleUrl: 'my-name.scss'
						})
						export class MyName {
						  @Prop() name: string;

						  render() {
						    return (
						      <p>
						        Hello, my name is {this.name}
						      </p>
						    );
						  }
						}
					

Stencil-compiled Components have

  • Virtual DOM: fast DOM updates without common DOM performance pitfalls
  • Lazy Loading: By default components load asyncronously and can be bundled with related components
  • Reactivity: Efficient updates based on property and state changes

Stencil-compiled Components have (cont.)

  • High-performance Rendering: async rendering system, similar to React Fiber
  • JSX: Popular and familiar markup system pioneered by React
  • Server Side Rendering: Hydrate pre-compiled components on the server without a headless browser

Stencil API

  • @Component(): set tag name and associated stylesheet (Sass or plain CSS)
  • @Prop(): Create a property on the component
  • @State(): local state that should be watched during change detection
  • @Event(): Trigger events on a component
  • @Listen(): listen for events fired from children
  • @Element(): grab the DOM element for this component

Example Stencil Component

							
									import { State } from '@stencil/core';

									...
									export class TodoList {
									  @State() completedTodos: Todo[];
									
									  completeTodo(todo: Todo) {
										this.completedTodos.push(todo);
									  }

									  render() {
									    return (
									      <div>
									        {this.todos.map((todo) =>
									          <div>
									            <div>{todo.taskName}</div>
									            <div>{todo.isCompleted}</div>
									          </div>
									        )}
									      </div>
									    )
									  }
									}
						

How is Stencil different from X?

  • Angular/React/Vue/etc.: Stencil builds standards-based web components that run natively in the browser.
  • Polymer: Stencil works primarily at build rather than runtime. Outputs vanilla web components. Opinionated around JSX, Virtual DOM, and other framework features.
  • Vanilla Web Components: Stencil provides complicated framework features as if you wrote them yourself in vanilla Web Components.

Questions?

  • Andre
  • @andregoncalves
  • github.com/andregoncalves