Web Components, el futuro de la web

Web

HTML5 ha traído la revolución al desarrollo frontend, desde los bloques semánticos hasta la renderización de objetos 3D en canvas, pasando por la reproducción de contenido multimedia. Cualquier cosa que antes necesitaba pesados archivos flash (y cuyo resultado final era cuestionable), ahora es posible hacerse de manera sencilla y ligera con HTML5 y CSS3.

Pero hablemos de una importante y reciente incorporación que ha tenido HTML5, los web components. Esto supone una revolución, la solución a varios problemas históricos de HTML.

¿Qué son los web components? El estándar se compone de 4 subelementos complementarios, pero independientes entre si:

La idea tras los web components es poner en manos de los desarrolladores las mismas herramientas que usan los responsables de los navegadores para implementar nuevos elementos. Las posibilidades que esto nos abre son, como bien se puede atisbar, impresionantes.

Custom Elements (Elementos Personalizados)

Con HTML5 se han incluido una serie de nuevas etiquetas para hacer la web más semántica. Un ejemplo de estas etiquetas pueden ser: header, footer, nav, section,... Lo que nos permiten los elementos personalizados es crear nuestra propia etiqueta, con la funcionalidad que le queramos dar.

Por ejemplo

Actualmente, si queremos incluir en nuestra web un botón para que nos sigan en Twitter habría que copiar el siguiente código:

<a class="twitter-follow-button"
  href="https://twitter.com/twitterdev"
  data-show-count="false"
  data-lang="en">
Follow @twitterdev
</a>
<script>window.twttr=(function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return;js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);t._e=[];t.ready=function(f){t._e.push(f);};return t;}(document,"script","twitter-wjs"));</script>

Con web components, bien se podría reducir a lo siguiente:

<follow-button account="twitterdev" show-cound="false" lang="en"></follow-button>

Lo mejor de esto es que será la propia comunidad la que creará y mejorará nuevos elementos, que podrán ser añadidos al estándar si ganan popularidad. Para ver los custom elements que hay ya creados por la comunidad puedes visitar el siguiente enlace http://customelements.io/.

Si te interesa crear tus propios elementos puedes encontrar más información en Polymer y X-Tag.

Templates (Plantillas)

Imaginemos que hacemos una llamada AJAX que nos devuelve un JSON con información, y que en base a este JSON queremos construir una lista. Actualmente podemos crear nuestra lista HTML con esos datos usando JavaScript de una manera un tanto engorrosa, o simplemente devolviendo en la llamada el fragmento HTML en lugar del JSON (lo que da lugar a un response más lento y pesado).

Con los web components podremos tener una plantilla HTML con la que fácilmente maquetaremos los datos recibidos en JSON. AngularJS y otros frameworks de frontend ya nos dan la posibilidad de utilizar esta funcionalidad, pero no de manera estándar (y a veces penalizando el rendimiento de nuestra aplicación web).

<template>
  <dl>
    <template repeat="{{actor in actores}}">
      <dt>{{actor.nombre}}</dt><dd>{{actor.personaje}}</dd>
    </template>
  </dl>
</template>

Shadow DOM (DOM Oculto)

Con Shadow DOM los elementos pueden tener un nuevo tipo de nodo asociado a ellos. A este nuevo tipo de nodo se le llama shadow root. Un elemento que tiene un shadow root asociado a él se le llama un shadow host. El contenido de un shadow host no es representado, se renderiza en su lugar el del shadow root.

Estos elementos son muy útiles para separar contenido de presentación, y así poder ocultar los detalles de ésta. Así conseguimos una estructura fácil de mantener, ya que si en algún momento queremos cambiar el código de la presentación, no tendremos que cambiar el del contenido.

Ejemplo

<button>Hello, world!</button>
<script>
    var host = document.querySelector('button');
    var root = host.createShadowRoot();
    root.textContent = 'Bye, World!';
</script>

En este caso, el botón mostrará "Bye, World!" en lugar de "Hello, World!".

Hagamos ahora un sencillo ejercicio: con el siguiente código vamos a mostrar un hello + name, y separaremos la presentación del contenido.

Presentación

<style>
    .outer { border: 2px solid brown; border-radius: 1em; background: red; font-size: 20pt; width: 12em; height: 7em; text-align: center; }
    .boilerplate { color: white; font-family: sans-serif; padding: 0.5em; }
    .name { color: black; background: white; font-family: "Marker Felt", cursive; font-size: 45pt; padding-top: 0.2em; }
</style>
<div class="outer">
    <div class="boilerplate"> Hi! My name is </div>
    <div class="name"> <content></content> </div>
</div>

Contenido

<div id="nameTag">Bob</div>

Ejemplo extraído de HTML5 ROCKS.

HTML Imports

Ahora podremos cargar otros archivos HTML dentro de un propio archivo HTML, creando frontends modulares. Para hacerlo simplemente hay que incluir este código (aunque luego hay que hacer una llamada JavaScript para ejecutar la importación, además podremos manejar los errores y otros eventos de ésta):

<link rel="import" href="file.html" onload="handleLoad(event)" onerror="handleError(event)">

Para más información sobre HTML Imports en HTML5 ROCKS hay un artículo más extendido.

Bonus

Vídeo para conocer Web Components de la comunidad española de HTML5: