Mises à jour partielles déclaratives

Publié le : 19 mai 2026

Le Web a depuis longtemps évolué par rapport au support statique axé sur les documents qu'il était à ses débuts. Les applications Web modernes et riches sont utilisées par tous pour de nombreuses raisons : communiquer, faire des achats, consommer du contenu riche ou gérer nos vies complexes.

Malgré toutes ses avancées, le HTML est toujours fourni dans l'ordre, de haut en bas, sans tenir compte du moment où le contenu est prêt ni du moment où l'utilisateur le consomme. Le CSS vous permet de modifier l'ordre du contenu, mais souvent avec des effets secondaires importants en termes d'accessibilité. JavaScript vous permet de manipuler le DOM via différentes API pour vous libérer quelque peu de cette contrainte, mais celles-ci nécessitent souvent une syntaxe détaillée ou la construction d'arbres DOM pour s'intégrer à HTML.

Les performances sont extrêmement importantes pour le Web, étant donné la nature client-serveur du support. Cependant, des choix sous-optimaux sont souvent faits pour contourner cette nature ordonnée du HTML, ce qui ralentit les performances. Cela inclut l'attente jusqu'à ce que la page entière soit prête ou l'utilisation d'un framework lourd pour fournir des composants de manière asynchrone. La popularité des frameworks JavaScript montre que les développeurs Web préfèrent un modèle basé sur des composants plutôt que le modèle mental rigide de document des origines du Web.

L'équipe Chrome s'est penchée sur ce problème et a développé de nouveaux ajouts à la plate-forme Web sous le nom de mises à jour partielles déclaratives.

Deux nouveaux ensembles d'API permettent de fournir du code HTML de manière moins linéaire, que ce soit dans le document HTML lui-même ou en insérant plus facilement du code HTML de manière dynamique dans des documents existants à l'aide de nouvelles API JavaScript. Ces fonctionnalités sont prêtes pour les tests des développeurs à partir de Chrome 148 à l'aide du flag chrome://flags/#enable-experimental-web-platform-features. Des polyfills sont également disponibles pour vous permettre d'utiliser ces nouvelles API immédiatement, même dans les navigateurs qui ne les prennent pas encore en charge.

Ces ajouts à la plate-forme Web sont en cours de normalisation, avec des commentaires positifs d'autres fournisseurs de navigateurs et des pistes de normalisation. Les normes concernées sont en cours de mise à jour pour inclure ces nouvelles API.

Streaming dans le désordre

Le premier ensemble de modifications concerne les nouvelles API de streaming hors séquence utilisant l'élément HTML <template> et les espaces réservés pour les instructions de traitement. Exemple :

<div>
  <?marker name="placeholder">
</div>

...

<template for="placeholder">
  Here is some <em>HTML content</em>!
</template>

Les instructions de traitement existent depuis longtemps dans XML, mais ont été traitées comme des commentaires dans HTML et ignorées. Cette nouvelle API modifie cela et ajoute des instructions de traitement au code HTML. Lorsque le navigateur voit les instructions de traitement <?marker name="placeholder">, il ne fait rien tout de suite, comme avant, mais elles peuvent être référencées ultérieurement.

L'élément <template> recherche les instructions de traitement correspondantes avec un attribut name et remplace le contenu. Dans ce cas, après l'analyse, le DOM se présente comme suit :

<div>
  Here is some <em>HTML content</em>!
</div>

En plus de l'attribut <?marker> pour les remplacements, il existe également des marqueurs de plage <?start> et <?end> qui permettent d'afficher un contenu d'espace réservé temporaire avant le traitement du modèle :

<div>
  <?start name="another-placeholder">
  Loading…
  <?end>
</div>

...

<template for="another-placeholder">
  Here is some <em>HTML content</em>!
</template>

Dans ce cas, Loading… s'affiche jusqu'à ce que <template> soit vu, puis est remplacé par le nouveau contenu.

Il est également possible d'inclure des instructions de traitement dans les modèles pour autoriser plusieurs mises à jour :

<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>
...

Après l'analyse, le code HTML suivant est généré :

<ul id="results">
  <li>Result One</li>
  <li>Result Two</li>
  <?marker name="results">
</ul>

Avec l'instruction de traitement finale à la fin, au cas où d'autres <template for="results"> seraient ajoutés au document ultérieurement.

Démo

Dans cette vidéo, une application d'album photo de base est implémentée avec le streaming HTML :

Démonstration d'un album photo implémentée avec le streaming hors séquence (source)

L'état et les photos sont diffusés dans le code HTML après la mise en page initiale.

Cas d'utilisation

Il existe de nombreux cas d'utilisation pour ce correctif HTML hors séquence lorsqu'il est associé au streaming HTML :

  • Architecture en îlots Un modèle courant popularisé par des frameworks comme Astro est l'architecture en îlots, où les composants sont hydratés indépendamment au-dessus du HTML statique. L'API <template for> permet de gérer le contenu statique de manière similaire directement en HTML. Les frameworks JavaScript peuvent également l'utiliser pour des îles plus interactives ou pour gérer des composants.
  • Fournissez le contenu lorsqu'il est prêt. Grâce à cette architecture en îlots, le contenu peut être diffusé en streaming dès qu'il est prêt, plutôt que d'être retenu pour le contenu qui nécessite un traitement supplémentaire, par exemple une recherche dans une base de données. Bien que de nombreuses plates-formes autorisent le streaming HTML, la nature ordonnée du HTML signifie que le contenu est souvent retenu ou nécessite des manipulations complexes du DOM JavaScript. Vous pouvez désormais diffuser le contenu statique en attendant, puis insérer le contenu plus coûteux à la fin du flux HTML.
  • Le code HTML peut être fourni dans l'ordre optimal pour les performances de chargement de page. Vous pouvez également modifier la commande lorsqu'elle est prête. Par exemple, les méga menus sont une fonctionnalité de navigation courante qui contient beaucoup de code HTML que l'utilisateur ne verra que lorsque la page deviendra interactive. Ce grand bloc de code HTML peut être fourni plus tard dans le document HTML pour donner la priorité au code HTML plus important nécessaire au chargement initial de la page. L'ordre n'est plus un obstacle avec HTML.

Il ne s'agit là que de quelques cas d'utilisation. Nous avons hâte de découvrir ce que les développeurs feront avec cette nouvelle API.

Restrictions et subtilités

L'API comporte quelques restrictions et subtilités à connaître :

  • Pour des raisons de sécurité, <template for> ne peut mettre à jour les instructions de traitement que dans le même élément parent. Si vous ajoutez <template for> directement à l'élément <body>, il aura accès à l'ensemble du document (y compris <head>).
  • L'instruction de traitement <?end> est facultative. Si elle est manquante, le contenu entre l'élément <?start> et la fin de l'élément conteneur sera remplacé.
  • Déplacer les instructions de traitement après le début du streaming d'un <template for> peut également avoir des conséquences inattendues, le nouveau contenu continuant à être diffusé à l'ancien emplacement.
  • Notez que lorsque vous insérez <template for> de manière dynamique avec une méthode telle que setHTML ou innerHTML, le "parent" du modèle lors de son analyse est un fragment de document intermédiaire. Cela signifie que l'insertion de code HTML à l'aide de ces méthodes ne peut pas modifier le DOM existant, et que le correctif est appliqué "sur place" à l'intérieur du fragment. Cependant, lors du streaming à l'aide de méthodes telles que streamHTMLUnsafe (que nous allons aborder), il n'y a pas de fragment intermédiaire. Les modèles peuvent donc remplacer le contenu existant.

Ajouts potentiels futurs

Voici quelques ajouts potentiels à l'étude :

  • Le côté client inclut : Exemple :<template for="footer" patchsrc="/partials/footer.html">
  • Traitement par lot : Côté client, les inclusions de fragments pourraient également être étendues pour gérer le traitement par lot afin de garantir que plusieurs mises à jour se produisent en même temps.
  • Éviter d'écraser le contenu qui ne changera pas Cela peut être réalisé avec un numéro de révision ou une gestion des versions du contenu. Cela permettrait de conserver l'état entre les changements de route ou d'autres mises à jour au lieu de réinitialiser le contenu.
  • Assainissement lors de l'application de correctifs. Par exemple, <template for=icon safe><svg id="from-untrusted-source">...</svg></template>.

Rembourrage

L'équipe Chrome a publié un template-for-polyfill disponible sur npm pour permettre aux sites d'utiliser cette nouvelle fonctionnalité immédiatement, avant même qu'elle ne soit disponible dans d'autres navigateurs.

Il existe certaines limites, car il ne peut pas mettre à jour directement les analyseurs HTML du navigateur, mais les cas d'utilisation les plus courants sont couverts. Les sites doivent toujours être testés dans d'autres navigateurs.

Méthodes de streaming et d'insertion HTML renouvelées

Tous les contenus ne peuvent pas être diffusés au format HTML. La deuxième partie du travail de Chrome dans ce domaine consiste à faciliter la mise à jour du contenu via JavaScript.

Il existe déjà plusieurs façons d'injecter dynamiquement du code HTML dans un document existant à l'aide de JavaScript :

  • setHTML
  • setHTMLUnsafe
  • Setters innerHTML et outerHTML
  • createContextualFragment
  • insertAdjacentHTML

Toutefois, ils fonctionnent tous de manière légèrement différente, avec des subtilités et des différences que les développeurs ne prennent pas toujours en compte :

  • Le nouveau contenu écrase-t-il le contenu existant ou s'y ajoute-t-il ?
  • Par exemple, le contenu HTML potentiellement dangereux est-il nettoyé en échappant les balises <script> ?
  • Sinon, <script> doit-il s'exécuter ?
  • Comment fonctionnent-ils avec TrustedTypes ?

Peu de développeurs pourraient honnêtement examiner ces API et répondre à ces questions pour chacune d'elles.

Une limite importante est qu'ils ne peuvent être utilisés que pour un ensemble complet de code HTML connu à l'avance, lorsque des appels ont été effectués pour autoriser le streaming HTML. En pratique, cela signifie que vous devez télécharger l'intégralité du contenu avant de l'insérer, alors que l'un des points forts du HTML est la possibilité de diffuser du contenu en streaming immédiatement. Il est possible de contourner ce problème de manière limitée en divisant les charges utiles ou en utilisant des méthodes obsolètes et peu pratiques comme document.write, mais cela introduit ses propres problèmes.

Nouvel ensemble d'API statiques et de flux

Chrome a proposé une suite de nouvelles API et d'extensions aux setHTML et setHTMLUnsafe existants qui permettent de résoudre ce problème et d'introduire des fonctionnalités de streaming :

Il existe des méthodes pour définir ou remplacer du contenu, ainsi que pour insérer du contenu avant ou après le code HTML existant. Chaque méthode a un équivalent dans les flux :

Action Statique Streaming
Définir le contenu HTML de l'élément setHTML(html, options); streamHTML(options);
Remplacez l'intégralité de l'élément par ce code HTML. replaceWithHTML(html, options); streamReplaceWithHTML(options);
Ajouter le code HTML avant l'élément beforeHTML(html, options); streamBeforeHTML(options);
Ajoutez le code HTML en tant que premier enfant de l'élément. prependHTML(html, options); streamPrependHTML(options);
Ajoutez le code HTML en tant que dernier enfant de l'élément. appendHTML(html, options); streamAppendHTML(options);
Ajouter le code HTML après l'élément afterHTML(html, options); streamAfterHTML(options);
Nouvelles méthodes d'insertion et de streaming

Il existe également des versions Unsafe dont nous parlerons bientôt. Bien qu'il puisse sembler y en avoir beaucoup (surtout si vous ajoutez les équivalents Unsafe), la convention de dénomination cohérente permet de mieux comprendre ce que fait chacun d'eux par rapport aux méthodes sans rapport mentionnées précédemment.

Les versions statiques acceptent le nouveau code HTML en tant qu'argument de chaîne DOM, ainsi que des options facultatives :

const newHTML = "<p>This is a new paragraph</p>";
const contentElement = document.querySelector('#content-to-update');

contentElement.setHTML(newHTML);

Les versions de streaming fonctionnent avec l'API Streams, par exemple avec 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();

Vous pouvez également utiliser une réponse fetch avec des chaînes de pipe :

const contentElement = document.querySelector('#content-to-update');

const response = await fetch('/api/content.html');

response.body
  .pipeThrough(new TextDecoderStream())
  .pipeTo(contentElement.streamHTMLUnsafe());

Nous prévoyons également d'ajouter une méthode pratique qui vous permettra de diffuser directement du contenu sans avoir à passer par l'étape intermédiaire TextDecoderStream().

L'argument options vous permet de spécifier un sanitizer personnalisé, qui est défini par défaut sur default, ce qui signifie la configuration de désinfection par défaut. Voici comment l'utiliser :

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});

Méthodes "non sécurisées"

Il existe également des versions "non sécurisées" de chacune des API :

Action Statique Streaming
Définir le contenu HTML de l'élément setHTMLUnsafe(html,options); streamHTMLUnsafe(options);
Remplacez l'intégralité de l'élément par ce code HTML. replaceWithHTMLUnsafe(html, options); streamReplaceWithHTMLUnsafe(options);
Ajouter le code HTML avant l'élément beforeHTMLUnsafe(html, options); streamBeforeHTMLUnsafe(options);
Ajoutez le code HTML en tant que premier enfant de l'élément. prependHTMLUnsafe(html, options); streamPrependHTMLUnsafe(options);
Ajoutez le code HTML en tant que dernier enfant de l'élément. appendHTMLUnsafe(html, options); streamAppendHTMLUnsafe(options);
Ajouter le code HTML après l'élément afterHTMLUnsafe(html, options); streamAfterHTMLUnsafe(options);
Méthodes d'insertion et de streaming "non sécurisées"

Ces méthodes "non sécurisées" désactivent le module de désinfection par défaut (vous pouvez spécifier un module de désinfection personnalisé si vous le souhaitez) et permettent également d'exécuter des scripts avec une option runScripts facultative (qui est définie sur false par défaut).

Comme setHTML, setHTMLUnsafe est une méthode existante, mais le paramètre d'options runScripts lui a été ajouté pour permettre son utilisation avec l'exécution de 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});

Le terme "non sécurisé" dans la méthode vise à rappeler aux développeurs le risque potentiel et la manière dont ils peuvent assainir ou limiter les scripts, et non à indiquer que ces méthodes ne doivent pas être utilisées.

Le degré de dangerosité dépend de la fiabilité des entrées. Les méthodes statiques Unsafe fonctionnent toutes avec la chaîne DOM ou TrustedHTML comme arguments html et permettent également d'utiliser des outils de désinfection. Toutefois, l'objectif de runScript est d'autoriser les scripts. C'est pourquoi aucun outil de nettoyage n'est utilisé par défaut.

Cas d'utilisation

Ces nouvelles API permettent aux développeurs d'ajouter plus facilement du code HTML aux pages existantes, en ajoutant de nouvelles API avec des noms et des options cohérents. Les API de streaming offrent l'avantage de ne pas avoir à attendre que tous les nouveaux contenus soient disponibles sur la plate-forme.

Voici quelques cas d'utilisation :

  • Streaming dynamique des mises à jour de contenu volumineuses dans les applications monopages. Comme mentionné précédemment, un inconvénient majeur des SPA actuelles est qu'elles ne pouvaient pas bénéficier de la nature de streaming des chargements HTML initiaux, mais ce n'est plus le cas.
  • Insérer du contenu courant, comme des pieds de page HTML L'utilisation des API JavaScript vous permet d'extraire des partiels et de les insérer dans la page, en bénéficiant de la mise en cache, plutôt que de les répéter dans chaque page envoyée. Toutefois, étant donné la dépendance à JavaScript pour l'exécution, cette méthode ne doit être utilisée que pour le contenu qui ne sera pas visible lors du chargement initial.

Ce ne sont là que quelques exemples. Nous avons hâte de découvrir ce que vous allez imaginer !

Restrictions et subtilités

Ces nouvelles API incluent également quelques restrictions et subtilités à connaître :

  • L'intégration du streaming à l'API Trusted Types nécessite l'utilisation d'une nouvelle méthode createParserOptions qui permet d'injecter un outil de nettoyage dans n'importe quelle opération de paramètre HTML. Pour en savoir plus sur l'intégration des types approuvés, consultez l'explication.
  • Comme pour <template for>, le déplacement d'éléments diffusés peut entraîner des conséquences inattendues ou des erreurs de diffusion.
  • streamHTMLUnsafe fonctionne de manière plus similaire à l'analyseur principal à plusieurs égards, y compris en traitant les instructions <template for> à mesure qu'elles sont ajoutées au document principal et en différant les scripts defer jusqu'à la fin du flux.

Rembourrage

L'équipe Chrome a publié un html-setters-polyfill disponible sur npm pour permettre aux sites d'utiliser cette nouvelle fonctionnalité immédiatement, avant même qu'elle ne soit disponible dans d'autres navigateurs.

Notez que ce polyfill ne diffuse pas de flux, mais met en mémoire tampon et applique le style une fois terminé. Il s'agit davantage d'un polyfill pour la forme de l'API que pour la fonctionnalité.

De plus, la définition de contenu sécurisé dépend de setHTML et de l'API Sanitizer, qui n'est pas compatible avec Safari.

Utiliser les deux ensemble

Bien qu'il s'agisse de deux API distinctes, leur combinaison est très puissante. En diffusant de nouveaux éléments <template for> dans le code HTML, vous pouvez mettre à jour dynamiquement différentes parties du contenu sans avoir à cibler directement chacune d'elles avec des références JavaScript distinctes au DOM.

Un chargement de page de style SPA de base peut être implémenté en chargeant une page de plan avec des instructions de traitement, puis en diffusant en streaming les modèles de chaque nouvelle page en bas du code HTML pour les insérer dans ces instructions de traitement.

Il existe sans aucun doute d'autres cas d'utilisation et d'autres possibilités pour ces deux API. Ne laissez donc pas notre imagination (limitée !) vous freiner. En facilitant la gestion des mises à jour partielles, vous pouvez réduire une partie du code récurrent, simplifier les mises à jour et débloquer de nouvelles possibilités pour le Web.