Publié le 3 juillet 2026
Si vous avez déjà utilisé un éditeur de documents, une application de feuille de calcul ou toute autre application dans laquelle le collage de contenu à partir du presse-papiers est une interaction principale, vous connaissez l'attente de l'utilisateur : le collage doit être instantané.
Malheureusement, dans de nombreux cas, les applications Web lisent plus de données du presse-papiers que nécessaire, ce qui peut rendre le collage de contenu plus lent qu'il ne devrait l'être, gaspiller des cycles de processeur et utiliser de la mémoire pour des données dont l'application n'a jamais besoin.
La lecture sélective du format résout ce problème de performances en modifiant l' API Async Clipboard pour mieux répondre aux attentes des utilisateurs et fournir aux développeurs ce dont ils ont besoin : ne lire que les formats dont l'application a réellement besoin.
Problème : lire tous les formats de données à l'avance
Lorsqu'un utilisateur copie des données à partir d'une application (par exemple, Excel, Google Docs ou Photoshop), l'application écrit généralement plusieurs représentations des mêmes données dans le presse-papiers du système : texte brut, HTML, image et parfois formats personnalisés. L'application Web qui lit les données (lorsque l'utilisateur colle le contenu du presse-papiers) a rarement besoin de toutes ces représentations. Un éditeur de feuilles de calcul peut vouloir du code HTML. Un éditeur de texte peut vouloir exposer une commande "Coller comme texte brut". Un éditeur de code ne peut vouloir que le texte et rien d'autre.
Jusqu'à présent,
navigator.clipboard.read()
récupérait toutes les représentations disponibles des données à partir du presse-papiers du système,
exécutait l'assainissement (ce qui peut prendre du temps, en particulier avec des charges utiles HTML ou
d'image volumineuses) et conservait les octets en mémoire, même pour les formats que l'application
n'utiliserait jamais. Plus la charge utile inutilisée était importante, plus l'utilisateur devait attendre et plus l'onglet consommait de mémoire, au moment où la réactivité du collage était la plus importante.
Solution : énumérer uniquement, puis lire à la demande
À partir de Chrome et Edge 149,
ClipboardItem
objets renvoyés par la méthode navigator.clipboard.read() ne décrivent que
le contenu du presse-papiers, au lieu de donner accès aux données immédiatement. Les
octets réels d'un format donné ne sont lus à partir du presse-papiers que lorsque vous appelez
ClipboardItem.getType(mimeType).
La surface de l'API reste inchangée. Le même code que celui que vous avez écrit hier fonctionne toujours aujourd'hui, ce qui vous offre des avantages immédiats en termes de performances :
// Enumerate the available MIME types.
// No payload is fetched yet.
const items = await navigator.clipboard.read();
for (const item of items) {
if (item.types.includes('text/html')) {
// Only read the HTML data.
// The data is fetched (and sanitized) here only.
const blob = await item.getType('text/html');
useThePastedHtml(await blob.text());
break;
}
// text/plain, image/png, or any other custom formats
// stored in the clipboard are never read.
}
Un autre avantage en termes de performances est que la mise en cache est automatique. L'appel de
getType('text/html') deux fois sur le même ClipboardItem ne lit qu'une seule fois le presse-papiers du système
et renvoie le Blob mis en cache lors du deuxième appel.
Avantages
Latence. Le travail qui devait être effectué lorsque navigator.clipboard.read() était appelé, comme la copie d'octets entre les processus, l'assainissement du code HTML ou le décodage d'images, ne se produit désormais que pour les formats dont votre application a réellement besoin. Les applications qui ne lisent qu'un seul format bénéficient de la plus grande partie de l'économie. Plus les formats que vous ignorez sont volumineux, plus le gain est important. Le code HTML est le plus avantageux, car son assainissement est coûteux.
Mémoire. Auparavant, l'appel de navigator.clipboard.read() lorsque le presse-papiers contenait une image de 50 Mo signifiait que 50 Mo devaient être utilisés dans la mémoire du moteur de rendu de la page Web jusqu'à ce que le ClipboardItem soit libéré, même si l'application n'avait besoin que de la représentation text/plain des données. Désormais, seuls les formats que votre application lit lors de l'appel de ClipboardItem.getType() utilisent de la mémoire dans le processus de rendu. Pour les applications où le collage est courant, comme les éditeurs de documents, les outils de création de messages ou les outils de conception, cela réduit considérablement l'utilisation de la mémoire lors du collage, en particulier dans les sessions à plusieurs onglets où plusieurs éditeurs peuvent lire le presse-papiers en parallèle.
Aucune activation requise. Tous les sites Web bénéficient automatiquement de ces avantages. Vous n'avez pas besoin de migrer de code ni de code de passerelle derrière une logique de détection de fonctionnalités.
Un changement de comportement à connaître
La lecture ultérieure des données introduit un léger changement de comportement : un objet ClipboardItem n'est plus un instantané figé du presse-papiers au moment où l'appel à navigator.clipboard.read() a été résolu.
Lorsque read() est appelé et renvoie un ClipboardItem, cet élément n'est qu'un handle différé des données dans le presse-papiers du système.
Si le contenu du presse-papiers change entre l'appel à read() et un appel ultérieur à getType(), cet appel sera rejeté avec une InvalidStateError. Cela est vrai même pour un format que vous avez déjà lu avec succès sur le même ClipboardItem.
// Read from the clipboard.
const items = await navigator.clipboard.read();
// Get the first ClipboardItem.
const item = items[0];
// Actually fetch the data now, which works fine.
const text = await item.getType('text/plain');
// The user writes something new to the clipboard
// by copying from another app, or your own code writes to
// the clipboard again.
await navigator.clipboard.writeText('something new');
// Fetching the data from the earlier ClipboardItem
// rejects with InvalidStateError, because the contents
// of the clipboard changed.
const html = await item.getType('text/html');
En effet, le renvoi de données qui ne reflètent plus le presse-papiers serait déroutant et entraînerait des problèmes difficiles à déboguer.
En pratique, la modification est invisible pour la plupart du code, car les applications appellent généralement read() et getType() dos à dos dans le même gestionnaire de collage. Toutefois, vous pouvez surveiller les cas où vous disposez d'un code qui conserve un ClipboardItem sur des limites asynchrones.
Voici un exemple où cette modification peut devenir un problème : mise en cache des objets ClipboardItem sur window, affichage dans une interface utilisateur d'historique du presse-papiers ou attente de l'interaction de l'utilisateur avant d'appeler getType(). Pour éviter les problèmes liés à un scénario de ce type :
- Encapsulez les appels
getType()dans des blocstry / catchet traitezInvalidStateErrorcomme un signal indiquant que le presse-papiers a été déplacé et que le code doit être relu. - Si vous devez conserver les données du presse-papiers, copiez le
Blobdans votre propre structure dès que vous l'avezgetType(). Ne traitez pas leClipboardItemcomme un stockage à long terme. - Utilisez l'
clipboardChangeévénement pour invalider de manière proactive les handles obsolètes.
Normes et compatibilité avec les navigateurs
La lecture sélective du format est une modification de la spécification des API Clipboard pilotée par le groupe de travail Web Editing et l’équipe de la plate-forme Web Microsoft Edge.
Safari est également compatible avec ce comportement, et Firefox a indiqué une position et une intention positives en matière de normes pour s'aligner.
Une amélioration discrète, mais significative des performances et de l'interopérabilité de l'API Clipboard, Chromium convergeant désormais vers le même modèle.