Mises à jour partielles déclaratives

Publié le 19 mai 2026, dernière mise à jour le 8 septembre 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 encore 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 de celui 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 verbeuse ou la construction d'arbres DOM à insérer dans le HTML.

Les performances sont extrêmement importantes pour le Web, étant donné la nature client-serveur du support. Toutefois, des choix non 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 Declarative Partial Updates (Mises à jour partielles déclaratives).

Les deux premiers ensembles d'API facilitent la diffusion de contenu HTML de manière moins linéaire, que ce soit dans le document HTML lui-même ou en insérant plus facilement du contenu HTML de manière dynamique dans des documents existants à l'aide de nouvelles API JavaScript. 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.

Streaming dans le désordre

Browser Support

  • Chrome: 150.
  • Edge: 150.
  • Firefox: not supported.
  • Safari: not supported.

Source

Le premier ensemble de modifications concerne les nouvelles API de streaming hors séquence qui utilisent des espaces réservés pour les instructions de traitement et l'élément HTML <template> avec l'attribut for. 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 elles 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. Par exemple, lorsque le navigateur voit l'instruction de traitement <?marker name="placeholder">, il ne fait rien tout de suite, comme avant, mais il peut y faire référence plus tard.

L'élément <template> avec l'attribut for 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 (en ignorant certaines différences d'espaces) :

<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, une chaîne Loading… s'affiche jusqu'à ce que <template> soit détecté, puis est remplacée 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 analyse et traitement, le code HTML suivant est obtenu :

<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 espaces réservés <template for="results"> seraient ajoutés au document ultérieurement.

Pourquoi utiliser des instructions de traitement plutôt que des éléments HTML standards ?

Il s'agit d'une question courante pour ceux qui utilisent cette API pour la première fois, avec des suggestions d'utiliser des éléments <slot> ou même <template>. Une version initiale de cette proposition fonctionnait avec des éléments HTML standards, mais les instructions de traitement ont été remplacées au fur et à mesure de l'itération de la conception. Les instructions de traitement permettent d'appliquer des correctifs sans affecter le DOM. Cela permet de l'utiliser dans <head> (pour les mises à jour <title>, par exemple) ou même à l'intérieur d'autres éléments comme <table> (pour ajouter des lignes supplémentaires facultatives, par exemple).

Bien que la syntaxe soit inconnue de nombreux développeurs Web, les instructions de traitement offrent une flexibilité bien supérieure et moins de risques de problèmes de compatibilité descendante. Elles sont déjà utilisées dans XML et font désormais partie de la norme HTML grâce à cette proposition.

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

L'application de correctifs HTML hors séquence associée au streaming HTML présente de nombreux cas d'utilisation :

  • 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 dans le code HTML. Les frameworks JavaScript peuvent également l'utiliser pour des îles plus interactives ou pour gérer des composants.
  • Fournir 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 du contenu plus coûteux et dynamique à 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 l'ordre même lorsqu'il est prêt. 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 que de quelques cas d'utilisation. Nous sommes impatients de découvrir comment les développeurs utiliseront 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 de la diffusion 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 la propriété 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 avec ces méthodes ne peut pas modifier le DOM existant, et que le correctif est appliqué "sur place" à l'intérieur du fragment. Toutefois, lors de la diffusion en flux continu à l'aide de méthodes telles que streamHTMLUnsafe (qui sera abordée prochainement), il n'y a pas de fragment intermédiaire. Les modèles peuvent donc remplacer le contenu existant.

État de la standardisation

L'attribut <template for> fait partie de la norme HTML, mais n'est pas encore compatible avec tous les navigateurs.

Ajouts potentiels futurs

Voici quelques ajouts potentiels à l'étude :

  • Le côté client inclut : Par exemple, <template for="footer" src="/partials/footer.html"> ou même sans correctif <template src="/partials/footer.html">. Pour en savoir plus, consultez la vidéo explicative. Cette fonctionnalité est disponible avec l'indicateur chrome://flags/#enable-experimental-web-platform-features.
  • Éviter d'écraser le contenu qui ne changera pas Cela peut être réalisé avec un numéro de révision ou un système de gestion des versions. Cela permettrait de conserver l'état entre les changements de route ou d'autres mises à jour au lieu de réinitialiser le contenu.
  • Nettoyage lors de l'application de correctifs. Par exemple, <template for=icon safe><svg id="from-untrusted-source">...</svg></template>.

Polyfill

L'équipe Chrome a publié une 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. Une deuxième partie du travail effectué par Chrome dans ce domaine vise à faciliter la mise à jour du contenu avec JavaScript.

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

  • setHTML
  • setHTMLUnsafe
  • 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 ?
  • Nettoient-ils le code HTML potentiellement dangereux, par exemple en échappant les balises <script> ?
  • Sinon, <script> doit-il s'exécuter ?
  • Comment fonctionnent-ils avec les types fiables ?

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.

Un nouvel ensemble d'API statiques et de flux

Browser Support

  • Chrome: behind a flag.
  • Edge: behind a flag.
  • Firefox: not supported.
  • Safari: not supported.

Chrome a travaillé sur une suite de nouvelles API et d'extensions aux setHTML et setHTMLUnsafe existants qui permettent de résoudre ce problème et d'introduire une fonctionnalité de streaming.

Ces API sont prêtes pour les tests des développeurs à partir de Chrome 148 à l'aide du flag chrome://flags/#enable-experimental-web-platform-features et devraient être lancées dans Chrome 155.

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

Nous aborderons également les versions Unsafe dans un instant. Bien qu'il puisse sembler y en avoir beaucoup (surtout si vous ajoutez les équivalents Unsafe), la convention d'attribution de noms cohérente permet de mieux comprendre le rôle de chacun par rapport aux méthodes non liées 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 des chaînes de pipes à partir d'une réponse de récupération :

const contentElement = document.querySelector('#content-to-update');
const response = await fetch('/api/content.html');

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

Méthode pratique textStream()

Browser Support

  • Chrome: 151.
  • Edge: 151.
  • Firefox: not supported.
  • Safari: not supported.

Une méthode pratique textStream a également été ajoutée. Elle vous permet de diffuser directement du contenu sans avoir besoin de l'étape intermédiaire TextDecoderStream() :

const contentElement = document.querySelector('#content-to-update');
const response = await fetch('/api/content.html');

response.textStream().pipeTo(contentElement.streamHTMLUnsafe());

options

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. Elle s'utilise comme suit :

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. Ces méthodes permettent également d'exécuter des scripts avec une option runScripts facultative, qui est définie par défaut sur false.

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 scripts :

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 souhaiter 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 de l'architecture SPA actuelle est qu'elle ne bénéficie pas 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 fiables, consultez la vidéo explicative.
  • Comme pour <template for>, le déplacement d'éléments en cours de diffusion peut entraîner des conséquences inattendues ou des erreurs de diffusion.
  • streamHTMLUnsafe fonctionne de manière plus similaire au parser principal à de nombreux é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.

État de la standardisation

Les nouvelles méthodes d'insertion et de streaming sont en cours d'ajout à la norme HTML, mais ne sont pas encore compatibles avec tous les navigateurs.

Polyfill

L'équipe Chrome a publié une 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, c'est en les combinant que vous obtiendrez les meilleurs résultats. 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.

Chrome travaille sur d'autres API dans le cadre du projet de mise à jour partielle déclarative, mais nous sommes ravis de vous proposer ces deux premières. Nous vous tiendrons informé et vous indiquerons quand d'autres informations seront disponibles.