Une nouvelle bibliothèque est apparue sur npm le 29 mars avec zéro annonce et déjà des centaines de téléchargements : Pretext (@chenglou/pretext), une bibliothèque JavaScript et TypeScript pure pour la mesure et la disposition de texte multiligne — sans jamais toucher au DOM.
L'auteur est Cheng Lou, auparavant connu pour son travail sur React et ReasonML. Le concept est simple : mesurer le texte comme le font les navigateurs, en utilisant le propre moteur de police du navigateur comme vérité terrain, mais entièrement via canvas — pas de getBoundingClientRect, pas de offsetHeight, pas de reflow de layout.
Pourquoi c'est important : le problème du reflow
Chaque développeur front-end a rencontré ce mur : vous devez savoir combien de hauteur un bloc de texte occupera avant de le rendre. La réponse traditionnelle est de le rendre, le mesurer, puis ajuster. Cela déclenche un reflow de layout — l'une des opérations les plus coûteuses du navigateur. Pour une seule étiquette, c'est acceptable. Pour une liste de 10 000 messages, un scroll virtualisé ou un agent IA générant de l'UI dynamiquement, c'est une catastrophe.
Pretext contourne complètement cela. Il mesure le texte en utilisant un canvas caché et l'API measureText() du navigateur, qui utilise le même moteur de police que le DOM. La mesure est précise car elle utilise la vraie typographie du navigateur — mais cela se passe hors écran, sans déclencher de layout du tout.
import { prepare, layout } from '@chenglou/pretext'
// Préparation unique (fait une fois par combinaison texte+police)
const prepared = prepare('IA le printemps arrive. 시작했다 🚀', '16px Inter')
// Chemin à chaud : arithmétique pure, pas de DOM impliqué
const { height, lineCount } = layout(prepared, textWidth, 20)
prepare() fait le travail unique : normalisation des espaces, segmentation du texte, application des règles de colle, mesure des segments avec canvas. layout() après cela est environ 0,09 ms pour 500 textes sur le benchmark actuel. C'est sous-milliseconde.
Deux cas d'usage, une bibliothèque
1. Mesurer sans toucher au DOM
Le cas d'usage principal : connaître la hauteur de votre texte avant de le rendre. Cela débloque :
- Virtualisation sans estimations : rendre uniquement ce qui correspond à la fenêtre d'affichage, mesurer le reste à l'avance
- Prévention CLS : pré-mesurer le texte avant qu'il se charge pour réserver l'espace adecuado et garder la position de défilement stable
- Détection de débordement au moment du développement : les agents de codage IA peuvent vérifier qu'une étiquette de bouton ne passera pas à deux lignes avant même que le code s'exécute
2. Layout de ligne manuel
Si vous avez besoin du contenu réel des lignes — pour le rendu canvas/SVG, pour le texte qui circule autour des flottants, ou pour construire des renderers personnalisés — Pretext fournit des API de bas niveau :
import { prepareWithSegments, layoutWithLines } from '@chenglou/pretext'
const prepared = prepareWithSegments('IA le printemps arrive. 시작했다 🚀', '18px "Helvetica Neue"')
const { lines } = layoutWithLines(prepared, 320, 26)
for (let i = 0; i < lines.length; i++) {
ctx.fillText(lines[i].text, 0, i * 26)
}
walkLineRanges() ne construit jamais de chaînes de lignes — il appelle un callback pour chaque ligne avec sa largeur et ses positions de curseur. Cela permet des recherches binaires sur les dimensions de layout.
Benchmarks
Du propre benchmark du projet sur un lot partagé de 500 textes :
prepare(): ~19 ms (unique, en cache)layout(): ~0,09 ms (chemin à chaud, arithmétique pure)
Pour contexte, un seul appel getBoundingClientRect() sur un sous-arbre DOM modérément complexe peut prendre 1-5 ms sur un appareil de milieu de gamme. Le chemin à chaud de Pretext est 10-50× plus rapide que la mesure DOM.
Support Unicode complet + Emoji + Texte bidirectionnel
Pretext gère correctement le rendu de texte dans toutes les langues. Le README souligne spécifiquement le support des emojis et du texte bidirectionnel (bidi) mixte.
Installation
npm install @chenglou/pretext
Les démos sont sur chenglou.me/pretext. Le code source est sur GitHub.