Reines JS · Null DOM-Zugriffe · TypeScript-first

Pretext.js

Textmessung, die niemals das DOM berührt.

Pretext misst und positioniert mehrzeiligen Text vollständig durch Arithmetik — kein getBoundingClientRect, kein Reflow, kein Thrashing. Schnell beim ersten Aufruf. Sofort bei jedem weiteren.

Editorial EngineDrag orbs · Click to pause · Zero DOM reads
14k+
GitHub-Sterne für Pretext
0
DOM-Zugriffe in Pretext layout()
~2ms
Pretext layoutet 1.000 Blöcke
12+
Schriftsysteme, die Pretext unterstützt
// das Problem

Warum Pretext existiert: Jede DOM-Messung ist eine Performance-Falle.

Jedes Mal, wenn Ihr JavaScript getBoundingClientRect(), offsetHeight oder scrollHeight auf einem DOM-Knoten aufruft, muss der Browser die Skriptausführung pausieren, alle ausstehenden Stiländerungen verarbeiten und einen vollständigen Rendering-Durchlauf ausführen — nur um eine Frage zur Größe einer Box zu beantworten.

Dies wird Forced Synchronous Reflow genannt und ist eine der teuersten Operationen, die ein Browser ausführen kann. In einer engen Schleife — z.B. beim Messen von tausend Elementen in einer virtuellen Scrollliste — entsteht Thrashing: Der Browser wechselt hunderte Male pro Frame zwischen Rendering und JavaScript-Ausführung, was selbst moderne Hardware zum Stillstand bringt.

Die grausame Ironie ist, dass Sie meistens nur eine Zahl brauchen: Wie viele Pixel hoch wird dieser Text bei dieser Containerbreite sein? Es gibt keinen Grund, warum diese Frage den DOM überhaupt berühren sollte. Pretext existiert, um genau das zu beweisen.

traditional-approach.js
// Erzwingt Browser-Layout bei jeder Iteration
const heights = items.map((item) => {
  const el = createElement(item.text);
  document.body.appendChild(el);

  // ← erzwingt hier Layout-Reflow
  const h = el.getBoundingClientRect().height;
  Reflow!

  document.body.removeChild(el);
  return h;
});

// 1000 Elemente = 1000 Reflows = ~94ms ≈ 6 verlorene Frames
// so funktioniert Pretext

So funktioniert Pretext: Einmal messen, für immer layouten.

Ziehen Sie den Teiler, um den traditionellen DOM-Ansatz mit Pretext zu vergleichen. Einer löst bei jedem Aufruf Reflow aus. Pretext verwendet reine Arithmetik.

with-pretext.js
import { prepare, layout } from '@chenglou/pretext'

// prepare() wird einmal ausgeführt — nutzt Canvas
const prepared = prepare(
  'The quick brown fox jumped.',
  '16px Inter'
);

// layout() ist reine Arithmetik
const { height, lineCount } = layout(
  prepared,
  containerWidth,
  lineHeight
); kein Reflow

// 1000 Elemente = 0 Reflows = ~0.05ms
// 500x schneller, null DOM-Zugriffe
traditional-approach.js
// Erzwingt Browser-Layout bei jeder Iteration
const heights = items.map((item) => {
  const el = createElement(item.text);
  document.body.appendChild(el);

  // ← erzwingt hier Layout-Reflow
  const h = el.getBoundingClientRect().height;
  Reflow!

  document.body.removeChild(el);
  return h;
});

// 1000 Elemente = 1000 Reflows = ~94ms
// ≈ 6 verlorene Frames bei 60fps
Before
After
1

Text segmentieren

Leerzeichen normalisieren, Unicode-Umbruchregeln anwenden und den String mithilfe der browsereigenen Textsegmentierung in messbare Einheiten aufteilen.

2

Mit Canvas messen

Jedes Segment durch Canvas measureText() führen, um echte Glyphenbreiten von der Font-Engine zu erhalten. Ergebnisse werden gecacht.

3

Pretext verwendet reine Arithmetik

Bei gegebener Containerbreite werden Zeilenumbrüche durch Summierung der Segmentbreiten berechnet. Zeilenanzahl mal Zeilenhöhe. Höhe zurückgeben. Kein DOM, niemals.

// Funktionen

Pretext-Funktionen: Gebaut für performancekritische Anwendungen.

Pretext wurde für Entwickler konzipiert, die komplexe, textintensive UIs bauen, bei denen traditionelle DOM-Messung zum Engpass geworden ist. Diese Funktionen machen es produktionsreif.

Null DOM-Zugriffe

In Pretext ist nach prepare() jeder layout()-Aufruf reine Arithmetik. Kein getBoundingClientRect, kein offsetHeight, kein Forced Synchronous Reflow — niemals.

🔡

Echte Font-Metriken

Pretext misst Glyphenbreiten mit der browsereigenen Canvas-Font-Engine, nicht mit Heuristiken oder Lookup-Tabellen. Das Ergebnis stimmt mit dem überein, was der Browser tatsächlich rendern würde.

🌍

Mehrsprachig von Grund auf

Pretext unterstützt vollständig CJK, Arabisch, Hebräisch, Thai, Hindi und Koreanisch, einschließlich korrekter Unicode-Segmentierung und bidirektionaler Textverarbeitung.

📘

TypeScript-nativ

Von Grund auf in TypeScript geschrieben. Präzise Typen für jede Funktion, jeden Parameter und jeden Rückgabewert — keine @types-Pakete nötig, keine Type-Gymnastics.

♻️

Wiederverwendbare prepared Handles

Ein prepare()-Aufruf deckt jede Containerbreite ab. Berechnen Sie Höhen für Mobile, Tablet und Desktop in drei arithmetischen Operationen aus demselben Handle.

📦

Null Runtime-Abhängigkeiten

Keine externen Pakete, keine Polyfills, keine Überraschungen in Ihrem Bundle. Pretext nutzt ausschließlich Standard-Browser-APIs, die in jeder modernen Umgebung verfügbar sind.

// Demos

Pretext in realen Szenarien.

Pretext glänzt am meisten dort, wo traditionelle DOM-Messung an ihre Grenzen stößt. Diese Beispiele zeigen, wie Pretext echte Produktionsherausforderungen löst — von virtuellem Scrollen bis zu mehrsprachigen Chat-Interfaces.

Alle Beispiele →
// Community-Showcases

Gebaut mit Pretext.

Kreative Demos aus der Community — Text-Drum-Machines, Fluid-Simulationen, kollaborative Whiteboards und mehr. Sehen Sie, was Entwickler mit Pretext bauen.

Alle Showcases →
// loslegen

Pretext in drei Minuten installieren.

Pretext ist auf npm veröffentlicht und wird mit vollständigen TypeScript-Deklarationen ausgeliefert. Installieren Sie es mit Ihrem bevorzugten Paketmanager, importieren Sie die zwei benötigten Funktionen, und Sie können Text messen, ohne das DOM zu berühren.

$npm install @chenglou/pretext
$pnpm add @chenglou/pretext
$bun add @chenglou/pretext
quickstart.ts
import { prepare, layout } from '@chenglou/pretext'

// Schritt 1: Einmal prepare für ein Text+Font-Paar
const handle = prepare(
  'Hello, Pretext — no reflow needed.',
  '16px "Inter"'
);

// Schritt 2: Layout bei beliebiger Breite, sofort
const { height, lineCount } = layout(
  handle,
  400,  // Containerbreite in px
  24    // Zeilenhöhe in px
);

console.log(height);    // → 48
console.log(lineCount); // → 2

// Schritt 3: Handle für verschiedene Breiten wiederverwenden
const narrow = layout(handle, 240, 24); // → 3 Zeilen
// Blog

Pretext-Blog.

Tiefgehende Einblicke in Text-Rendering, Browser-Performance und wie Pretext Probleme löst, auf die Entwickler täglich stoßen — ob sie die Ursache kennen oder nicht.

Alle Beiträge →
// nächste Schritte

Probieren Sie Pretext noch heute aus.

Ob Sie eine virtuelle Scrollliste, einen Code-Editor, ein KI-Chat-Interface oder irgendetwas anderes bauen, bei dem Texthöhe wichtig ist — Pretext liefert präzise Messungen ohne Performance-Kosten.

Pretext.js - Textmessung, die niemals das DOM berührt.