Pubblicato: 19 maggio 2026, ultimo aggiornamento: 8 settembre 2026
Il web ha da tempo abbandonato il mezzo statico e basato sui documenti con cui è nato. Le app web moderne e ricche vengono utilizzate da tutti per molti motivi, dalla comunicazione agli acquisti, dal consumo di contenuti avanzati alla gestione delle nostre vite complesse.
L'HTML, nonostante tutti i suoi progressi, viene ancora fornito in ordine dall'alto verso il basso, senza tenere conto di quando i contenuti sono pronti o di quando l'utente li consuma. CSS ti consente di modificare l'ordine dei contenuti, ma spesso con effetti collaterali significativi sull'accessibilità. JavaScript ti consente di manipolare il DOM tramite varie API per superare in parte questo limite, ma spesso richiedono una sintassi dettagliata o la costruzione di alberi DOM da collegare all'HTML.
Le prestazioni sono incredibilmente importanti per il web, data la natura client-server del mezzo. Tuttavia, spesso vengono fatte scelte non ottimali per aggirare questa natura in ordine dell'HTML, il che rallenta le prestazioni. Ciò include l'attesa che l'intera pagina sia pronta o l'utilizzo di un framework pesante per pubblicare i componenti in modo asincrono. La popolarità dei framework JavaScript dimostra che gli sviluppatori web preferiscono un modello basato su componenti piuttosto che il modello mentale rigido dei documenti delle origini del web.
Il team di Chrome sta prendendo in considerazione questo problema e sta sviluppando nuove aggiunte alla piattaforma web con il nome di Aggiornamenti parziali dichiarativi.
I primi due nuovi set di API semplificano la pubblicazione di HTML in modo meno lineare, sia in ordine sparso nel documento HTML stesso, sia tramite modi più semplici per inserire dinamicamente HTML in documenti esistenti utilizzando nuove API JavaScript. Sono disponibili anche polyfill che ti consentono di utilizzare subito queste nuove API, anche nei browser che non le supportano ancora.
Streaming fuori ordine
Il primo insieme di modifiche riguarda le nuove API di streaming fuori ordine che utilizzano segnaposto per le istruzioni di elaborazione e l'elemento HTML <template> con l'attributo for. Ad esempio:
<div>
<?marker name="placeholder">
</div>
...
<template for="placeholder">
Here is some <em>HTML content</em>!
</template>
Le istruzioni di elaborazione esistono in XML da molto tempo, ma sono state trattate come commenti in HTML e ignorate. Questa nuova API cambia la situazione e porta le istruzioni di elaborazione in HTML. Ad esempio, quando il browser vede l'istruzione di elaborazione <?marker name="placeholder">, non fa nulla immediatamente, proprio come prima, ma può essere referenziata in un secondo momento.
L'elemento <template> con l'attributo for cerca le istruzioni di elaborazione corrispondenti con un attributo name e sostituisce il contenuto. In questo caso, dopo l'analisi, il DOM risulta il seguente (ignorando alcune differenze di spazi bianchi):
<div>
Here is some <em>HTML content</em>!
</div>
Oltre all'attributo <?marker> per le sostituzioni, esistono anche i marcatori di intervallo <?start> e <?end>, che consentono di visualizzare contenuti segnaposto temporanei prima dell'elaborazione del modello:
<div>
<?start name="another-placeholder">
Loading…
<?end>
</div>
...
<template for="another-placeholder">
Here is some <em>HTML content</em>!
</template>
In questo caso, viene visualizzata una stringa Loading… fino a quando non viene visualizzato il <template>, che viene poi sostituito con i nuovi contenuti.
È anche possibile includere istruzioni di elaborazione nei modelli per consentire più aggiornamenti:
<ul id="results">
<?start name="results">
Loading…
<?end>
</ul>
...
<template for="results">
<li>Result One</li>
<?marker name="results">
</template>
...
<template for="results">
<li>Result Two</li>
<?marker name="results">
</template>
...
Dopo l'analisi e l'elaborazione, il codice HTML risultante è il seguente:
<ul id="results">
<li>Result One</li>
<li>Result Two</li>
<?marker name="results">
</ul>
Con l'istruzione di elaborazione finale alla fine, nel caso in cui vengano aggiunti altri segnaposto <template for="results"> al documento in un secondo momento.
Perché istruzioni di elaborazione anziché elementi HTML standard?
Si tratta di una domanda comune per chi utilizza questa API per la prima volta, con suggerimenti per utilizzare gli elementi <slot> o anche <template>. Una versione iniziale di questa proposta funzionava con elementi HTML standard, ma le istruzioni di elaborazione sono state sostituite man mano che il design veniva perfezionato. Le istruzioni di elaborazione consentono l'applicazione di patch senza influire sul DOM. Ciò consente di utilizzarlo in <head>, ad esempio per gli aggiornamenti di <title>, o anche all'interno di altri elementi come <table> (per aggiungere righe aggiuntive facoltative, ad esempio).
Nonostante la sintassi non sia familiare a molti sviluppatori web, le istruzioni di elaborazione offrono una flessibilità molto maggiore con meno possibilità di problemi di compatibilità con le versioni precedenti. Sono già utilizzati in XML e, grazie a questa proposta, ora fanno parte dello standard HTML.
Demo
In questo video viene implementata un'applicazione di album fotografico di base con HTML in streaming:
Sia lo stato che le foto vengono trasmessi in streaming nell'HTML dopo il layout iniziale.
Casi d'uso
Esistono molti casi d'uso per questa applicazione di patch HTML fuori ordine se combinata con lo streaming HTML:
- Architettura a isola. Un pattern comune reso popolare da framework come Astro, l'architettura a isole, in cui i componenti vengono idratati in modo indipendente sopra l'HTML statico. L'API
<template for>consente di gestire i contenuti statici in modo simile direttamente in HTML. I framework JavaScript possono utilizzare questo elemento anche per isole più interattive o per gestire i componenti. - Pubblica i contenuti quando sono pronti. Grazie a questa architettura a isole, i contenuti possono essere trasmessi in streaming quando sono pronti, anziché essere trattenuti per i contenuti che richiedono un'elaborazione aggiuntiva, ad esempio una ricerca nel database. Sebbene molte piattaforme consentano lo streaming HTML, la natura in ordine dell'HTML fa sì che i contenuti vengano spesso trattenuti o che si ricorra a complesse manipolazioni del DOM JavaScript. Ora puoi pubblicare i contenuti statici durante l'attesa e poi inserire contenuti più costosi e dinamici alla fine del flusso HTML.
- Il codice HTML può essere pubblicato nell'ordine ottimale per il rendimento del caricamento pagina. Se vuoi fare un passo avanti, puoi modificare l'ordine anche quando è pronto. Ad esempio, i mega menu sono una funzionalità di navigazione comune che contiene molto codice HTML che l'utente non vedrà finché la pagina non diventa interattiva. Questo blocco di codice HTML può essere inserito in un secondo momento nel documento HTML per dare la priorità al codice HTML più importante necessario per il caricamento iniziale della pagina. L'ordine non è più un ostacolo con HTML.
Questi sono solo alcuni casi d'uso e siamo entusiasti di vedere per cosa gli sviluppatori utilizzeranno questa nuova API.
Restrizioni e sfumature
L'API include alcune restrizioni e sfumature di cui è bene essere a conoscenza:
- Per motivi di sicurezza,
<template for>può aggiornare le istruzioni di elaborazione solo all'interno dello stesso elemento principale. L'aggiunta di<template for>direttamente all'elemento<body>gli consente di accedere all'intero documento (incluso<head>). - L'istruzione di elaborazione
<?end>è facoltativa e, se mancante, i contenuti tra l'elemento<?start>e la fine dell'elemento contenitore verranno sostituiti. - Lo spostamento delle istruzioni di elaborazione dopo l'inizio dello streaming di un
<template for>può anche avere conseguenze impreviste, con i nuovi contenuti che continuano a essere trasmessi in streaming nella vecchia posizione. - Tieni presente che quando inserisci
<template for>in modo dinamico con un metodo comesetHTMLo la proprietàinnerHTML, l'"elemento principale" del modello durante l'analisi è un frammento di documento intermedio. Ciò significa che l'inserimento di HTML con questi metodi non può modificare il DOM esistente e l'applicazione delle patch avviene "in loco" all'interno del frammento. Tuttavia, quando lo streaming viene eseguito utilizzando metodi comestreamHTMLUnsafe(che vedremo a breve), non esiste un frammento intermedio, quindi i modelli possono sostituire i contenuti esistenti.
Stato della standardizzazione
L'attributo <template for> fa parte dello standard HTML, ma non è ancora supportato in tutti i browser.
Potenziali aggiunte future
Alcuni potenziali futuri contenuti aggiuntivi in fase di valutazione includono:
- Inclusioni lato client. Ad esempio,
<template for="footer" src="/partials/footer.html">o anche senza patch<template src="/partials/footer.html">. Per maggiori dettagli, consulta il video esplicativo. Questa opzione è disponibile dietro il flagchrome://flags/#enable-experimental-web-platform-features. - Impedire la sovrascrittura dei contenuti che non cambieranno. Ciò potrebbe essere ottenuto con un numero di revisione o un controllo delle versioni dei contenuti. In questo modo, lo stato viene mantenuto tra le modifiche del percorso o altri aggiornamenti anziché reimpostare i contenuti.
- Sanitizzazione durante l'applicazione di patch. Ad esempio,
<template for=icon safe><svg id="from-untrusted-source">...</svg></template>
Polyfill
Il team di Chrome ha rilasciato un template-for-polyfill disponibile su npm per consentire ai siti di utilizzare subito questa nuova funzionalità prima ancora che venga implementata in altri browser.
Esistono alcune limitazioni, in quanto non è possibile aggiornare direttamente i parser HTML del browser, ma i casi d'uso più comuni sono coperti. I siti devono comunque essere testati in altri browser.
Metodi di inserimento e streaming HTML rinnovati
Non tutti i contenuti possono essere pubblicati in formato HTML. Una seconda parte del lavoro svolto da Chrome in questo ambito mira a semplificare l'aggiornamento dei contenuti con JavaScript.
Esistono già diversi modi per inserire dinamicamente HTML in un documento esistente utilizzando JavaScript:
setHTMLsetHTMLUnsafeinnerHTMLeouterHTMLcreateContextualFragmentinsertAdjacentHTML
Tuttavia, funzionano tutti in modo leggermente diverso, con sottigliezze e differenze che gli sviluppatori potrebbero non considerare sempre:
- I nuovi contenuti sovrascrivono o vengono aggiunti?
- Sanitizzano l'HTML potenzialmente pericoloso, ad esempio eseguendo l'escape dei tag
<script>? - In caso contrario,
<script>deve essere eseguito? - Come funzionano con Trusted Types?
Pochi sviluppatori potrebbero esaminare onestamente queste API e rispondere con sicurezza a queste domande per ciascuna di esse.
Un limite importante è che possono essere utilizzati solo per un insieme completo di HTML noto in anticipo, quando sono state effettuate chiamate per consentire lo streaming di HTML. In pratica, ciò significa che devi scaricare l'intero contenuto prima di inserirlo, mentre uno dei punti di forza dell'HTML è la possibilità di riprodurre in streaming i contenuti immediatamente. Questo problema può essere aggirato in modo limitato dividendo i payload o utilizzando metodi obsoleti e non ortodossi come document.write, ma questi introducono altri problemi.
Un nuovo insieme di API statiche e di streaming
Browser Support
Chrome ha lavorato a una suite di nuove API ed estensioni per le esistenti setHTML e setHTMLUnsafe che semplificano questa procedura, oltre a introdurre la funzionalità di streaming.
Queste funzionalità sono pronte per i test degli sviluppatori a partire da Chrome 148 utilizzando il flag chrome://flags/#enable-experimental-web-platform-features e il lancio è previsto in Chrome 155.
Esistono metodi per impostare o sostituire i contenuti, nonché metodi per inserirli prima o dopo l'HTML esistente. Ogni metodo ha equivalenti di flusso:
| Azione | Statico | Streaming |
|---|---|---|
| Imposta i contenuti HTML dell'elemento | setHTML(html, options); |
streamHTML(options); |
| Sostituisci l'intero elemento con questo codice HTML | replaceWithHTML(html, options); |
streamReplaceWithHTML(options); |
| Aggiungi l'HTML prima dell'elemento | beforeHTML(html, options); |
streamBeforeHTML(options); |
| Aggiungi l'HTML come primo elemento secondario dell'elemento | prependHTML(html, options); |
streamPrependHTML(options); |
| Aggiungi l'HTML come ultimo elemento secondario dell'elemento | appendHTML(html, options); |
streamAppendHTML(options); |
| Aggiungi il codice HTML dopo l'elemento | afterHTML(html, options); |
streamAfterHTML(options); |
A breve verranno trattate anche le versioni di Unsafe. Anche se potrebbero sembrare molti, soprattutto se aggiungi gli equivalenti Unsafe, la convenzione di denominazione coerente rende più ovvio cosa fa ciascuno rispetto ai metodi non correlati menzionati in precedenza.
Le versioni statiche accettano il nuovo HTML come argomento stringa DOM, insieme a opzioni facoltative:
const newHTML = "<p>This is a new paragraph</p>";
const contentElement = document.querySelector('#content-to-update');
contentElement.setHTML(newHTML);
Le versioni di streaming funzionano con l'API Streams, ad esempio con un getWriter():
const contentElement = document.querySelector('#content-to-update');
const writer = contentElement.streamHTMLUnsafe().getWriter();
// Example stream of updating content
while (true) {
await writer.write(`<p>${++i}</p>`);
await new Promise((resolve) => setTimeout(resolve, 1000));
}
writer.close();
In alternativa, da una risposta di recupero utilizzando pipe chain:
const contentElement = document.querySelector('#content-to-update');
const response = await fetch('/api/content.html');
response.body
.pipeThrough(new TextDecoderStream())
.pipeTo(contentElement.streamHTMLUnsafe());
textStream() metodo di convenienza
Browser Support
È stato aggiunto anche un metodo pratico textStream, in cui puoi eseguire lo streaming direttamente senza la necessità del passaggio intermedio TextDecoderStream():
const contentElement = document.querySelector('#content-to-update');
const response = await fetch('/api/content.html');
response.textStream().pipeTo(contentElement.streamHTMLUnsafe());
options
L'argomento options ti consente di specificare un sanitizer personalizzato, il cui valore predefinito è default, ovvero la configurazione predefinita di Sanitizer. Viene utilizzata in questo modo:
const newHTML = '<p>This is a new paragraph</p>';
const contentElement = document.querySelector('#content-to-update');
// Only allows basic formatting
const basicFormattingSanitzer = new Sanitizer({ elements: ['em', 'i', 'b', 'strong'] });
contentElement.setHTML(newHTML, {sanitizer: basicFormattingSanitzer});
Metodi "non sicuri"
Esistono anche versioni "non sicure" di ciascuna API:
| Azione | Statico | Streaming |
|---|---|---|
| Imposta i contenuti HTML dell'elemento | setHTMLUnsafe(html,options); |
streamHTMLUnsafe(options); |
| Sostituisci l'intero elemento con questo codice HTML | replaceWithHTMLUnsafe(html, options); |
streamReplaceWithHTMLUnsafe(options); |
| Aggiungi l'HTML prima dell'elemento | beforeHTMLUnsafe(html, options); |
streamBeforeHTMLUnsafe(options); |
| Aggiungi l'HTML come primo elemento secondario dell'elemento | prependHTMLUnsafe(html, options); |
streamPrependHTMLUnsafe(options); |
| Aggiungi l'HTML come ultimo elemento secondario dell'elemento | appendHTMLUnsafe(html, options); |
streamAppendHTMLUnsafe(options); |
| Aggiungi il codice HTML dopo l'elemento | afterHTMLUnsafe(html, options); |
streamAfterHTMLUnsafe(options); |
Questi metodi "non sicuri" disattivano il sanificatore per impostazione predefinita e, se vuoi, puoi specificarne uno personalizzato. Questi metodi consentono anche di eseguire script con un'opzione runScripts facoltativa, che per impostazione predefinita è false.
Come setHTML, setHTMLUnsafe è un metodo esistente, ma è stato aggiunto il parametro delle opzioni runScripts per consentirne l'utilizzo con l'esecuzione di script:
const newHTML = `<p>This is a new paragraph</p>
<script src=script.js></script>`;
const contentElement = document.querySelector('#content-to-update');
contentElement.setHTMLUnsafe(newHTML, {runScripts: true});
Il termine "non sicuro" nel metodo serve a ricordare agli sviluppatori il potenziale rischio e come potrebbero voler sanificare o limitare gli script, non a dire che questi metodi non devono essere utilizzati.
Il livello di "insicurezza" dipende dall'affidabilità degli input. Tutti i metodi statici Unsafe funzionano sia con la stringa DOM sia con TrustedHTML come argomenti html e consentono anche l'utilizzo di sanificatori. Tuttavia, con runScript l'intento è quello di consentire gli script, motivo per cui per impostazione predefinita non viene utilizzato alcun sanitizer.
Casi d'uso
Queste nuove API consentono agli sviluppatori di aggiungere più facilmente HTML alle pagine esistenti, aggiungendo nuove API con nomi e opzioni coerenti. Le API di streaming offrono il vantaggio di non dover attendere che tutti i nuovi contenuti siano disponibili sulla piattaforma.
I casi d'uso includono:
- Streaming dinamico di aggiornamenti di contenuti di grandi dimensioni nelle app a pagina singola. Come accennato in precedenza, un grande svantaggio dell'attuale architettura SPA è che non beneficia della natura di streaming dei caricamenti HTML iniziali, ma ora non è più così.
- Inserimento di contenuti comuni come i piè di pagina HTML. L'utilizzo delle API JavaScript consente di inserire i parziali nella pagina, sfruttando la memorizzazione nella cache, anziché ripeterli in ogni pagina inviata. Tuttavia, data la dipendenza da JavaScript per l'esecuzione, questo metodo deve essere utilizzato solo per i contenuti che non saranno visibili nel caricamento iniziale.
Questi sono solo un paio di esempi e non vediamo l'ora di scoprire cosa inventerete.
Restrizioni e sfumature
Queste nuove API includono anche alcune limitazioni e sfumature da tenere presenti:
- L'integrazione dello streaming con l'API Trusted Types richiede l'utilizzo di un nuovo metodo
createParserOptionsche consente di inserire un sanitizer in qualsiasi operazione di impostazione HTML. Per ulteriori dettagli sull'integrazione dei tipi attendibili, consulta il video esplicativo. - Analogamente a
<template for>, lo spostamento di elementi in streaming può creare conseguenze impreviste o errori di streaming. streamHTMLUnsafefunziona in molti modi come il parser principale, tra cui l'elaborazione delle istruzioni<template for>man mano che vengono aggiunte al documento principale e il rinvio degli scriptdeferfino alla fine dello stream.
Stato della standardizzazione
I metodi di inserimento e streaming più recenti sono in fase di aggiunta allo standard HTML, ma non sono ancora supportati in tutti i browser.
Polyfill
Il team di Chrome ha rilasciato un html-setters-polyfill disponibile su npm per consentire ai siti di utilizzare subito questa nuova funzionalità prima ancora che venga implementata in altri browser.
Tieni presente che questo polyfill non esegue lo streaming, ma memorizza nel buffer e applica al termine. Si tratta più di un polyfill per la forma dell'API che per la funzionalità.
Inoltre, l'impostazione di contenuti sicuri dipende da setHTML e dall'API Sanitizer, che non è supportata in Safari.
Utilizzali insieme
Anche se si tratta di due API separate, la vera potenza deriva dalla loro combinazione. Trasmettendo in streaming nuovi elementi <template for> nell'HTML, puoi aggiornare dinamicamente diverse parti dei contenuti senza doverle scegliere come target direttamente con riferimenti JavaScript separati al DOM.
Un caricamento pagina di base in stile SPA potrebbe essere implementato caricando una pagina di struttura con istruzioni di elaborazione e poi trasmettendo in streaming i modelli di ogni nuova pagina nella parte inferiore dell'HTML per inserirli in queste istruzioni di elaborazione.
Indubbiamente, queste API hanno un potenziale e casi d'uso maggiori, quindi non lasciare che la nostra immaginazione (limitata) ti trattenga. Semplificando la gestione degli aggiornamenti parziali, puoi ridurre parte del codice boilerplate, semplificare gli aggiornamenti e sbloccare nuove potenzialità per il web.
Chrome sta lavorando ad altre API nell'ambito del progetto di aggiornamenti parziali dichiarativi, ma siamo felici di mettere a tua disposizione queste prime due. Ti terremo aggiornato e ti avviseremo quando saranno disponibili ulteriori informazioni in merito.