HTML templates: tag <template>
Il tag <template> permette di definire markup HTML inattivo che il browser non renderizza ma che JavaScript può clonare e inserire dinamicamente. È uno strumento fondamentale per Web Components, rendering condizionale e ottimizzazione delle performance. A differenza di display:none, il contenuto interno non viene parsato fino al clone, evitando esecuzione di script e caricamento di risorse.
Cos'è template
<template> è un contenitore HTML5 il cui contenuto è inerte: non viene renderizzato, gli script non eseguono, le immagini non si caricano, gli iframe non si attivano. Il contenuto è accessibile via template.content (un DocumentFragment) che puoi clonare con cloneNode(true) e inserire dove serve. È perfetto per definire markup riusabile lato client, evitando di costruire stringhe HTML concatenate.
Differenza con hidden
Un'elemento con attributo hidden o display:none è comunque parsato: script eseguono, immagini si caricano. Template invece sospende completamente l'elaborazione del suo contenuto. Inoltre il contenuto di template è in un DocumentFragment, non nel DOM principale, quindi non occupa memoria fino al clone. È la soluzione corretta per "stamp" di markup da istanziare al bisogno senza costi nascosti.
Template e slot per Web Components
In Web Components, template è spesso il meccanismo per definire il markup interno del componente. Pattern classico: const tpl = document.createElement('template'); tpl.innerHTML = '<style>...</style><slot></slot>'; e nel constructor del componente fai this.shadowRoot.appendChild(tpl.content.cloneNode(true)). Il template viene parsato una sola volta a livello modulo, ogni istanza del componente ne clona il contenuto. Approccio efficiente sia in memoria che in tempo di esecuzione, ideale per componenti riusati molte volte sulla stessa pagina.
Template e librerie reattive
Librerie come lit-html non usano direttamente template HTML ma sfruttano template literals tagged JavaScript con un meccanismo simile concettualmente. Il vantaggio è binding reattivo: cambi una variabile e il DOM si aggiorna. Per casi semplici il tag template nativo basta; per UI dinamiche complesse con stato preferisci librerie dedicate. La scelta dipende dalla complessità: per design system con componenti relativamente statici, template nativo funziona benissimo e mantiene zero dipendenze esterne nel progetto finale.
Template e performance
Template offre benefici di performance significativi: parsing once-only del markup, riuso del DocumentFragment per istanze multiple, no caricamento di risorse interne fino al clone. Rispetto a innerHTML ripetuto, template+clone è 5-10x più veloce per markup complesso. Per liste lunghe (es. tabella con 1000 righe), il pattern Template + DocumentFragment + appendChild a fine ciclo (no incrementale) minimizza reflow. Combinazione vincente per UI ad alte performance senza framework. Lit-html sfrutta questo internamente, ottenendo aggiornamenti DOM molto efficienti.
Conditional templates
Per template con sezioni condizionali, usa data attributes nel template e logica di rimozione/visibilità nel clone. Esempio: template di card con sezione <div data-section="premium">...</div>, dopo il clone rimuovi il div se l'utente non è premium. Alternativa: avere multiple template, scegliere quello giusto in base al contesto. Per logica complessa, librerie come Lit-html offrono direttive di rendering condizionale dichiarative più ergonomiche del DOM manipulation manuale. Template HTML resta utile come fondamento, le librerie aggiungono ergonomia ma il principio sottostante è lo stesso.
Template e librerie moderne
Librerie moderne come Lit-html, hyperHTML, Solid.js usano template tagged literals JavaScript con un meccanismo concettualmente simile a template HTML, ma con binding reattivo: cambi una variabile e il DOM si aggiorna automaticamente. Senza framework, template nativo richiede aggiornamento manuale. Compromesso: template nativo è zero dipendenze ma più verboso; lit-html aggiunge ~5KB ma riduce drasticamente il codice. Per progetti piccoli template nativo basta; per UI complesse reactive lit-html è investment che paga. Pattern intermedio: template nativo per markup statico, lit-html per parti dinamiche. Hybrid approach pragmatico, comune in design system enterprise.
Procedura passo-passo
- Definisci nel body: <template id="cardTpl">...markup card...</template>.
- In JavaScript: const tpl = document.getElementById('cardTpl').
- Clona il contenuto: const clone = tpl.content.cloneNode(true).
- Modifica i nodi del clone con querySelector e textContent.
- Inserisci nel DOM: container.appendChild(clone).
- Ripeti per creare più istanze del template senza re-parsare HTML.
- Per Web Components, attacca il clone allo shadow root del componente.
Errori comuni e come risolverli
- Modificare template originale: tutte le copie successive erediteranno le modifiche; lavora sul clone.
- Dimenticare cloneNode(true): senza il true cloni solo il nodo radice, non i figli.
- Template fuori dal body: deve stare nel body o nel head (con limitazioni); rispetta le regole di posizionamento.
- Script dentro template: non eseguono finché non clonati e inseriti; comportamento by design.
- Aspettarsi reactivity: template è statico; per binding usa Lit, lit-html o framework.
Domande frequenti
D: Template è supportato ovunque?
R: Sì, tutti i browser moderni lo supportano nativamente da anni.
D: Posso annidare template?
R: Sì, perfettamente. È utile per layout complessi con sezioni opzionali.
D: Performance del clone?
R: Molto veloce: il template è già parsato, il clone è solo una copia di nodi DOM.
D: Template è SEO-friendly?
R: Il contenuto interno non è renderizzato; i crawler lo vedono come testo nel sorgente ma non come contenuto effettivo della pagina.
Hai bisogno di aiuto?
Se vuoi sviluppo web con il team di G Tech Group, scrivici tramite il modulo di contatto.