Data di pubblicazione: 19 maggio 2026
Il web ha da tempo superato il mezzo statico e basato su documenti con cui ha iniziato. Le app web moderne e ricche vengono utilizzate da tutti per molti motivi, dalla comunicazione, all'acquisto, al 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, con poca attenzione a quando i contenuti sono pronti o quando l'utente li consuma. Il CSS consente di modificare l'ordine dei contenuti, ma spesso con effetti collaterali significativi sull'accessibilità. JavaScript consente di manipolare il DOM tramite varie API per liberarsi in qualche modo da questo, ma spesso richiedono una sintassi dettagliata o la costruzione di alberi DOM da collegare all'HTML.
Il rendimento è incredibilmente importante per il web, data la natura client-server del mezzo, ma spesso vengono fatte scelte non ottimali per aggirare questa natura in ordine dell'HTML, che rallenta il rendimento. Ciò include l'attesa che l'intera pagina sia pronta o l'utilizzo di un framework pesante per fornire i componenti in modo asincrono. La popolarità dei framework JavaScript dimostra che gli sviluppatori web preferiscono un modello basato su componenti anziché il modello mentale rigido dei documenti delle origini del web.
Il team di Chrome ha preso in considerazione questo problema e ha sviluppato nuove aggiunte alla piattaforma web con il nome di aggiornamenti parziali dichiarativi.
Due nuovi set di API semplificano la fornitura di HTML in modo meno lineare, sia fuori ordine nel documento HTML stesso sia tramite modi più semplici per inserire dinamicamente HTML nei documenti esistenti utilizzando nuove API JavaScript. Questi sono pronti per i test degli sviluppatori da Chrome 148 utilizzando il flag chrome://flags/#enable-experimental-web-platform-features. Sono disponibili anche polyfill per consentirti di utilizzare subito queste nuove API, anche nei browser che non le supportano ancora.
Queste aggiunte alla piattaforma web sono in fase di standardizzazione con feedback positivi da parte di altri fornitori di browser e percorsi di standardizzazione. Gli standard pertinenti sono in fase di aggiornamento per includere queste nuove API.
Streaming fuori ordine
Il primo set di modifiche riguarda le nuove API di streaming fuori ordine che utilizzano l'elemento HTML <template> e i segnaposto delle istruzioni di elaborazione. 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 questa situazione e porta le istruzioni di elaborazione in HTML. Quando il browser vede le istruzioni di elaborazione <?marker name="placeholder">, non fa nulla subito, proprio come prima, ma è possibile farvi riferimento in un secondo momento.
L'elemento <template> cerca le istruzioni di elaborazione corrispondenti con un attributo name e sostituisce i contenuti. In questo caso, dopo l'analisi, il DOM diventa:
<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 visualizzato Loading… finché non viene visualizzato <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, l'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 in un secondo momento vengano aggiunti altri elementi <template for="results"> al documento.
Demo
In questo video viene implementata un'applicazione di album di foto di base con HTML di streaming:
Sia lo stato sia le foto vengono trasmessi in streaming nell'HTML dopo il layout iniziale.
Casi d'uso
Esistono molti casi d'uso per questo HTML di applicazione di patch fuori ordine se abbinato all'HTML di streaming:
- Architettura a isole. 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 anche utilizzare questa API per isole più interattive o per gestire i componenti. - Fornire 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 manipolazioni DOM JavaScript complesse. Ora puoi fornire i contenuti statici durante l'attesa e poi inserire i contenuti più costosi alla fine del flusso HTML.
- L'HTML può essere fornito nell'ordine ottimale per il rendimento del caricamento pagina. Facendo un passo in più, puoi modificare l'ordine anche quando è pronto. Ad esempio, i mega menu sono una funzionalità di navigazione comune che contiene molto HTML che l'utente non vedrà finché la pagina non diventa interattiva. Questo grande blocco di HTML può essere fornito in un secondo momento nel documento HTML per dare la priorità all'HTML più importante necessario per il caricamento iniziale della pagina. L'ordine non è più un ostacolo con l'HTML.
Questi sono solo alcuni casi d'uso ed è entusiasmante vedere per cosa gli sviluppatori utilizzano questa nuova API.
Restrizioni e sottigliezze
L'API include alcune restrizioni e sottigliezze di cui è necessario essere a conoscenza:
<template for>può aggiornare solo le istruzioni di elaborazione all'interno dello stesso elemento principale per motivi di sicurezza. 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 manca, i contenuti tra l'elemento<?start>e la fine dell'elemento contenitore verranno sostituiti. - Lo spostamento delle istruzioni di elaborazione dopo l'avvio dello streaming di
<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>dinamicamente con metodi comesetHTMLoinnerHTML, l'"elemento principale" del modello durante l'analisi è un frammento di documento intermedio. Ciò significa che l'inserimento di HTML utilizzando questi metodi non può modificare il DOM esistente e l'applicazione di patch avviene "in loco" all'interno del frammento. Tuttavia, quando si esegue lo streaming utilizzando metodi comestreamHTMLUnsafe(di cui parleremo a breve), non esiste un frammento intermedio, quindi i modelli possono sostituire i contenuti esistenti.
Potenziali aggiunte future
Alcune potenziali aggiunte future in fase di valutazione includono:
- Inclusioni lato client. Ad esempio,
<template for="footer" patchsrc="/partials/footer.html">. - Raggruppamento. Le inclusioni di frammenti lato client potrebbero anche essere estese per gestire il raggruppamento per garantire che più aggiornamenti avvengano contemporaneamente.
- Impedire la sovrascrittura dei contenuti che non cambieranno. Questo potrebbe essere ottenuto con un numero di revisione dei contenuti o il controllo delle versioni. In questo modo, lo stato verrebbe mantenuto tra le modifiche di route 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 che è disponibile su npm per consentire ai siti di utilizzare subito questa nuova funzionalità, anche prima che venga implementata in altri browser.
Esistono alcune limitazioni in quanto non è possibile aggiornare direttamente gli analizzatori HTML del browser, ma i casi d'uso più comuni sono coperti. I siti devono comunque eseguire test in altri browser.
Metodi di inserimento e streaming HTML rinnovati
Non tutti i contenuti possono essere forniti in HTML. Una seconda parte del lavoro che Chrome sta svolgendo in questo ambito riguarda la semplificazione dell'aggiornamento dei contenuti tramite JavaScript.
Esistono già diversi modi per inserire dinamicamente HTML in un documento esistente utilizzando JavaScript:
setHTMLsetHTMLUnsafe- Setter
innerHTMLeouterHTML createContextualFragmentinsertAdjacentHTML
Tuttavia, tutti funzionano in modi leggermente diversi, con sottigliezze e differenze che gli sviluppatori potrebbero non sempre prendere in considerazione:
- I nuovi contenuti sovrascrivono o vengono aggiunti?
- Sanitizzano l'HTML potenzialmente pericoloso, ad esempio eseguendo l'escape dei tag
<script>? - In caso contrario, gli
<script>'s devono essere eseguiti? - Come funzionano con Trusted Types?
Pochi sviluppatori potrebbero onestamente esaminare queste API e rispondere con sicurezza a queste domande per ognuna di esse.
Una limitazione importante è che possono essere utilizzati solo per un set completo di HTML noto in anticipo, quando sono state effettuate chiamate per consentire lo streaming 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 trasmettere subito i contenuti in streaming. Questo può essere aggirato in modo limitato dividendo i payload o utilizzando metodi non standard e ritirati come document.write, ma questi introducono i propri problemi.
Un nuovo set di API statiche e di streaming
Chrome ha proposto una suite di nuove API ed estensioni per le API setHTML e setHTMLUnsafe esistenti che semplificano questa operazione, oltre a introdurre la funzionalità di streaming:
Esistono metodi per impostare o sostituire, nonché metodi per inserire contenuti prima o dopo l'HTML esistente. Ogni metodo ha equivalenti di streaming:
| Azione | Statica | Streaming |
|---|---|---|
| Imposta i contenuti HTML dell'elemento | setHTML(html, options); |
streamHTML(options); |
| Sostituisci l'intero elemento con questo 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 l'HTML dopo l'elemento | afterHTML(html, options); |
streamAfterHTML(options); |
Esistono anche versioni Unsafe di cui parleremo a breve. Sebbene possano sembrare molte (soprattutto se aggiungi gli equivalenti Unsafe), la convenzione di denominazione coerente rende più ovvio ciò che fa ciascuna rispetto ai metodi non correlati menzionati in precedenza.
Le versioni statiche accettano il nuovo HTML come argomento DOM String, 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, con le catene di pipe:
const contentElement = document.querySelector('#content-to-update');
const response = await fetch('/api/content.html');
response.body
.pipeThrough(new TextDecoderStream())
.pipeTo(contentElement.streamHTMLUnsafe());
Stiamo anche pianificando di aggiungere un metodo pratico in cui puoi eseguire lo streaming direttamente senza il passaggio intermedio TextDecoderStream() step.
L'argomento options consente di specificare un sanitizer personalizzato, il cui valore predefinito è default, ovvero la configurazione predefinita del sanificatore. Viene utilizzato come segue:
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 "Unsafe"
Esistono anche versioni "unsafe" di ciascuna delle API:
| Azione | Statica | Streaming |
|---|---|---|
| Imposta i contenuti HTML dell'elemento | setHTMLUnsafe(html,options); |
streamHTMLUnsafe(options); |
| Sostituisci l'intero elemento con questo 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 l'HTML dopo l'elemento | afterHTMLUnsafe(html, options); |
streamAfterHTMLUnsafe(options); |
Questi metodi "unsafe" disattivano il sanificatore per impostazione predefinita (se vuoi, puoi specificare un sanificatore personalizzato) e consentono anche l'esecuzione degli script con un'opzione runScripts facoltativa (il cui valore predefinito è 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});
La parola "unsafe" nel metodo serve a ricordare agli sviluppatori il potenziale rischio e il modo in cui potrebbero voler sanificare o limitare gli script, non a dire che questi metodi non devono essere utilizzati.
Il livello di "unsafe" dipende dall'affidabilità degli input. I metodi statici Unsafe funzionano tutti sia con DOM String 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 sanificatore.
Casi d'uso
Queste nuove API semplificano l'aggiunta di HTML alle pagine esistenti, aggiungendo nuove API con nomi e opzioni coerenti. Le API di streaming offrono i vantaggi in termini di rendimento di non dover attendere che tutti i nuovi contenuti siano disponibili per la 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 delle SPA attuali è che non potevano usufruire della natura di streaming dei caricamenti HTML iniziali, fino ad ora.
- Inserimento di contenuti comuni come i piè di pagina HTML. L'utilizzo delle API JavaScript consente di recuperare i parziali e inserirli nella pagina, sfruttando la memorizzazione nella cache, anziché ripeterli in ogni pagina inviata. Tuttavia, data la dipendenza da JavaScript per l'esecuzione, questa operazione deve essere utilizzata solo per i contenuti che non saranno visibili nel caricamento iniziale.
Di nuovo, questi sono solo alcuni esempi e non vediamo l'ora di scoprire cosa inventerete.
Restrizioni e sottigliezze
Queste nuove API includono anche alcune restrizioni e sottigliezze di cui è necessario essere a conoscenza:
- L'integrazione dello streaming con l'API Trusted Types richiede l'utilizzo di un nuovo metodo
createParserOptionsche consente di inserire un sanificatore in qualsiasi operazione di impostazione HTML. Per maggiori dettagli sull'integrazione dei tipi attendibili, consulta la spiegazione - Analogamente a
<template for>, lo spostamento degli elementi in cui viene eseguito lo streaming può creare conseguenze impreviste o errori di streaming. streamHTMLUnsafefunziona in molti modi in modo più simile all'analizzatore principale, inclusa l'elaborazione delle istruzioni<template for>man mano che vengono aggiunte al documento principale e il rinvio degli scriptdeferfino alla fine dello stream.
Polyfill
Il team di Chrome ha rilasciato un html-setters-polyfill che è disponibile su npm per consentire ai siti di utilizzare subito questa nuova funzionalità, anche prima che venga implementata in altri browser.
Tieni presente che questo polyfill non esegue lo streaming, ma memorizza nel buffer e applica al termine. È più 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 entrambi insieme
Sebbene si tratti 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 indirizzare direttamente con riferimenti JavaScript separati al DOM.
Il 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, entrambe queste API hanno un potenziale e casi d'uso maggiori, quindi non lasciarti limitare dalla nostra immaginazione (limitata). Semplificando la gestione degli aggiornamenti parziali, puoi ridurre parte del codice boilerplate, semplificare gli aggiornamenti e sbloccare un nuovo potenziale per il web.