Template elemento html. Contenido disponible sin penalizar la carga de la web

El elemento Html 'Template'. Qué es. Cómo utilizarlo, sus ventajas y advertencias en su uso, soporte por los navegadores actuales y casos y demos de uso.

Template elemento html. Contenido disponible sin penalizar la carga de la web

Por Kseso ✎ 3
El elemento html Template: disponer de contenido sin penalizar el renderizado de la web

El elemento HTML template es un mecanismo para alojar contenido del lado del cliente que no será renderizado cuando se cargue una página, pero posteriormente podrá serlo usando JavaScript.

Se podría decir que el elemento html template lo que hace es forzar al navegador a verificar la existencia y disponibilidad de su contenido, pero sin procesarlo. Esto es, el elemento template no generará nodos en el DOM, ni él ni su contenido.

Así que es ideal para meter en él cualquier cosa que se necesitará posteriormente (una o varias veces) pero que no hace falta en el momento de cargar la página.

Dentro de él se puede poner casi cualquier otro elemento, desde metadatos a cualquiera de los llamados flow content (los que pueden ir en el body de un documento).

Podríamos hacer la analogía de que el elemento template sería un equivalente en el aspecto visual a cualquier otro que es ocultado mediante Css display: none o a un elemento defs o symbol del SVG en lo que se refiere a su (re)utilización.

Método de declarar una parte de marcado Html reutilizable que se analiza pero que no se procesa hasta que es clonado.

Beneficios del uso de 'template'

Eric Bidelman en su artículo HTML's New Template Tag en html5rocks.com ofrece una serie de beneficios del elemento template, entre los que están:

  • Su contenido es efectivamente ignorado hasta que se activa.
  • Cualquier contenido dentro de él no tendrá efectos secundarios. Los script no se ejecutan, las imágenes no se cargan, el audio no se reproduce, ... hasta que se utilice.
  • Su contenido se considera que no está en el documento. Usando document.getElementById() o querySelector() en la página principal no devolverá los nodos hijos de un template.
  • Los elementos template se pueden colocar en cualquier lugar dentro de head, body o frameset y pueden contener cualquier tipo de contenido que se permite en esos elementos. Ten en cuenta que en cualquier lugar significa que template puede ser utilizado con seguridad en los lugares que el analizador HTML no lo permitiría. También se puede colocar como un hijo de una tabla o de select:
<ol> <template id='id'> <li>Cualquier contenido</li> </template> <li>... </ol> <table> <tr> <template id="cells-to-repeat"> <td>some content</td> </template> </tr> </table>

Precauciones en el uso de 'template'

En el mismo artículo de Eric Bidelman pone de manifiesto algunas cuestiones críticas o advertencias a tener presentes en su uso:

  1. Si utilizas modpagespeed, ten cuidado con este error: 'Template'´s que contiene <style scoped>, son movidos al head.
  2. No hay manera de prerenderizar un template, lo que significa que no se pueden precargar recursos, como procesar js o descargar CSS crítico. Eso sirve para el servidor y el cliente. Su contenido sólo será efectivo cuando se "active".
  3. Hay que tener cuidado con el anidamiento de template´s. No se comportan como cabría esperar. Por ejemplo, si tienes un template dentro de otro, al activar el padre no se activa template hijo.

Soporte actual al elemento 'template'

A estas alturas todos los principales navegadores tanto en su versión escritorio como móvil lo soportan, excepto los IE (incluido el Edge) y el Opera Mini:

Soporte del elemento template por los navegadores
Soporte a template según caniuse

Inclusión y activación del 'template'

En el mismo artículo de Eric Bidelman describe diversar formas de incluir, ocultar y activar al elemento template. También adjunta alguna demostración.

Entre otras la siguiente:

Para utilizar un template es necesario activarlo. De lo contrario, su contenido nunca se renderizará. La forma más sencilla de hacerlo es mediante la creación de una copia de .content usando document.importNode().

La propiedad .content es un DocumentFragment de sólo lectura (read-only) de los contenidos del elemento template

var t = document.querySelector('#mytemplate'); // Populate the src at runtime. t.content.querySelector('img').src = 'logo.png'; var clone = document.importNode(t.content, true); document.body.appendChild(clone);

Después de estampar un template, su contenido cobra vida. En este ejemplo en particular, el contenido es clonado, se hace la petición de la imagen y el resto de sus elementos html se renderizan.

Otros ejemplo de uso y activación (en un artículo dedicado al elemento Html template) los encontrarás en el post de Eiji Kitamura Introduction to the template elements.

En la demo Eiji Kitamura el 'template' lo incluye en el head del documento, incluyendo los estilos que le aplican:

<head> ... <template id="template"> <style> @keyframes roll { 0% {transform: rotateY(0deg)} 100% {transform: rotateY(360deg)} } .webcomponents { transform-style: preserve-3d; animation: roll 2s infinite linear; } #container { perspective: 800px; } </style> <div id="container"> <img class="webcomponents" src="http://webcomponents.org/img/logo.svg"> </div> </template> </head> <body> <div id="host"></div>

Para a continuación clonar el 'template' en el <div id='host'> mediante un script:

<script> var template = document.querySelector('#template'); var clone = document.importNode(template.content, true); var host = document.querySelector('#host'); host.appendChild(clone); </script>

Ejemplo de uso de 'template': carga diferida de imágenes

Sin embargo para una mejor comprensión de su funcionamiento y potencial, en este momento mejor que pase al artículo de Christian Heilmann Quick trick: using template to delay loading of images y a la demo en él incluida.

En él crea una lista (code>ul) conteniendo un gran número de imágenes. Como no es necesario que todas estén disponibles con la carga inicial del documento las aloja, excepto las primeras, en un template:

<ul class="cardlist"> <li class="card current"><img src="images/a-push-please.jpg" alt=""></li> <li class="card"><img src="images/amazing-dog.jpg" alt=""></li> <li class="card"><img src="images/awesome-mix-dog.jpg" alt=""></li> <li class="card"><img src="images/baby-amardillo.jpg" alt=""></li> <li class="card"><img src="images/baby-hippo-nom.jpg" alt=""></li> <template> <li class="card"><img src="images/baby-rhino.jpg" alt=""></li> <li class="card"><img src="images/barbie-frenchie.jpg" alt=""></li> <li class="card"><img src="images/basset-helmet.jpg" alt=""></li> <li class="card"><img src="images/bear-dog.jpg" alt=""></li> <li class="card"><img src="images/bear-puppy-fluff.jpg" alt=""></li> <li class="card"><img src="images/best-day-ever-puppy.jpg" alt=""></li> <li class="card"><img src="images/bleh-puppy.jpg" alt=""></li> <li class="card"><img src="images/bleh-tapir.jpg" alt=""></li> <li class="card"><img src="images/cat-on-stairs.jpg" alt=""></li> <li class="card"><img... <:!-- Otras muchas más imágenes --> ...alt=""></li> </template> </ul>

Con este marcado sólo serán procesadas y mostradas las 5 primeras.

Para agregar el resto, sólo tiene que utilizar un evento onload, que toma el contenido del code>template y lo agrega al elemento padre (la lista).

window.addEventListener('load', function(ev) { // check if template is supported // browsers without it wouldn't need to // do the content shifting if ('content' in document.createElement('template')) { // get the template var t = document.querySelector('template'); // get its parent element var list = t.parentNode; // cache the template content var contents = t.innerHTML; // kill the template list.removeChild(t); // add the cached content to the parent list.innerHTML += contents; } all = document.body.querySelectorAll('.card').length + 1; updatecounter(); });

Las diferencias son notables y significativas. Sin usar el elemento template le supuso una transferencia de 542KB con 26 peticiones y 6.43 segundos en una conexión 3G. Utilizando template le llevó 2.08 segundos la carga del documento.

Lógicamente nada obliga a que el elemento template genere en cada reutilización el mismo contenido. Con un poco más de imaginación y código puede variar de copia a copia. Pulsa reiteradas veces el siguiente button



Créditos y documentos base de este artículo

Aunque ya los he mencionado y enlazado, no está mal terminar este post relacionando de nuevo aquellos trabajos de los que es deudor. Mi recomendación: visita los originales ya que éste no es como otras veces una traducción más o menos completa de ellos.

  1. HTML's New Template Tag de Eric Bidelman
  2. Quick trick: using template to delay loading of images de Christian Heilmann
  3. Introduction to the template elements de Eiji Kitamura
  4. El elemento Template en MDN
  5. El elemento Template en la especificación Html5

Ramajero Argonauta, Enredique Amanuense de CSS.
#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Don Kseso Kseso

Comentarios: 3

  1. Según lo que encontre este polyfill funciona para esto pero no lo he probado: http://webcomponents.org/polyfills/

    ResponderEliminar
  2. hola, tengo un template video background, Seria posible hacer un "script media queries" que active el template video en screen. Pero en mobiles continué sin activar (y no genere la descarga de video)? agradezco inmensamente a sí sea un link...

    ResponderEliminar
    Respuestas
    1. Pese a las dudas que me asaltan sobre qué es exáctamente tu template video background, Dick, y suponiendo que te refieras al elemento html template del que hablo en el artículo, creo que sí podrías optar por esa vía y uso: detectar tamaño del viewport y en función del mismo actuar sobre el elemento template y su contenido.

      Un saludo

      Eliminar

EsCss RSS del Blog RSSS Comentarios Humans.txt ᛯ Diseno por Kseso SiteMap