Template elemento html. Contenido disponible sin penalizar la carga de la web 15.9.15
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
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()
oquerySelector()
en la página principal no devolverá los nodos hijos de untemplate
. - Los elementos
template
se pueden colocar en cualquier lugar dentro dehead
,body
oframeset
y pueden contener cualquier tipo de contenido que se permite en esos elementos. Ten en cuenta queen cualquier lugar
significa quetemplate
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 deselect
:
<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:
- Si utilizas modpagespeed, ten cuidado con este error: 'Template'´s que contiene
<style scoped>
, son movidos alhead
. - No hay manera de
prerenderizar
untemplate
, 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". - Hay que tener cuidado con el anidamiento de
template
´s. No se comportan como cabría esperar. Por ejemplo, si tienes untemplate
dentro de otro, al activar el padre no se activatemplate
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:
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
Template reutilizado por 0 vez
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.
HTML's New Template Tag
de Eric BidelmanQuick trick: using template to delay loading of images
de Christian HeilmannIntroduction to the template elements
de Eiji Kitamura- El elemento Template en MDN
- El elemento Template en la especificación Html5
Kseso
the obCSServer ᛯ 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 Kseso
Según lo que encontre este polyfill funciona para esto pero no lo he probado: http://webcomponents.org/polyfills/
ResponderEliminarhola, 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...
ResponderEliminarPese 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.
EliminarUn saludo