순수 JS · DOM 읽기 제로 · TypeScript 우선

Pretext.js

DOM을 건드리지 않는 텍스트 측정.

Pretext는 멀티라인 텍스트를 순수 산술 연산으로 측정하고 배치합니다 — getBoundingClientRect 없이, 리플로우 없이, 스래싱 없이. 첫 번째 호출도 빠르고, 이후 호출은 즉시 완료됩니다.

14k+
Pretext GitHub 스타
0
Pretext layout()의 DOM 읽기 횟수
~2ms
Pretext로 1,000개 블록 레이아웃
12+
Pretext가 지원하는 문자 체계
// 문제점

Pretext가 존재하는 이유: 모든 DOM 측정은 성능 함정입니다.

JavaScript가 DOM 노드에서 getBoundingClientRect(), offsetHeight, 또는 scrollHeight를 호출할 때마다, 브라우저는 스크립트 실행을 일시 중지하고, 대기 중인 스타일 변경을 플러시하고, 전체 렌더링 패스를 수행해야 합니다 — 단지 박스 크기에 대한 질문에 답하기 위해서요.

이것을 강제 동기 리플로우라고 하며, 브라우저가 수행할 수 있는 가장 비용이 큰 작업 중 하나입니다. 반복문에서 — 예를 들어 가상 스크롤 목록의 1,000개 항목을 측정할 때 — 스래싱이 발생합니다: 브라우저가 프레임당 수백 번 렌더링과 JavaScript 실행을 번갈아 수행하며, 최신 하드웨어조차 멈추게 만듭니다.

안타까운 점은 대부분의 경우 숫자 하나만 필요하다는 것입니다: 이 컨테이너 너비에서 이 텍스트의 높이는 몇 픽셀인가? 이 질문에 답하기 위해 DOM을 건드릴 이유가 전혀 없습니다. Pretext는 바로 이것을 증명하기 위해 만들어졌습니다.

traditional-approach.js
// 매 반복마다 브라우저 레이아웃을 강제합니다
const heights = items.map((item) => {
  const el = createElement(item.text);
  document.body.appendChild(el);

  // ← 여기서 레이아웃 리플로우가 발생합니다
  const h = el.getBoundingClientRect().height;
  리플로우!

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

// 1000개 항목 = 1000번 리플로우 = ~94ms ≈ 6프레임 드롭
// 작동 원리

Pretext 작동 원리: 한 번 측정하고, 영원히 레이아웃합니다.

구분선을 드래그하여 기존 DOM 방식과 Pretext를 비교해 보세요. 하나는 매 호출마다 리플로우를 발생시키고, Pretext는 순수 산술 연산을 사용합니다.

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

// prepare()는 한 번만 실행 — Canvas 사용
const prepared = prepare(
  'The quick brown fox jumped.',
  '16px Inter'
);

// layout()은 순수 산술 연산
const { height, lineCount } = layout(
  prepared,
  containerWidth,
  lineHeight
); 리플로우 없음

// 1000개 항목 = 0번 리플로우 = ~0.05ms
// 500배 빠름, DOM 접근 제로
traditional-approach.js
// 매 반복마다 브라우저 레이아웃을 강제합니다
const heights = items.map((item) => {
  const el = createElement(item.text);
  document.body.appendChild(el);

  // ← 여기서 레이아웃 리플로우가 발생합니다
  const h = el.getBoundingClientRect().height;
  리플로우!

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

// 1000개 항목 = 1000번 리플로우 = ~94ms
// ≈ 60fps에서 6프레임 드롭
Before
After
1

텍스트 분할

공백을 정규화하고, 유니코드 줄 바꿈 규칙을 적용하고, 브라우저의 자체 텍스트 분할을 사용하여 문자열을 측정 가능한 단위로 분리합니다.

2

Canvas로 측정

각 세그먼트를 Canvas measureText()에 전달하여 폰트 엔진에서 실제 글리프 너비를 가져옵니다. 결과는 캐시됩니다.

3

Pretext는 순수 산술 연산을 사용합니다

컨테이너 너비가 주어지면, 세그먼트 너비를 합산하여 줄 바꿈을 계산합니다. 줄 수에 줄 높이를 곱합니다. 높이를 반환합니다. DOM 접근은 절대 없습니다.

// 기능

Pretext 기능: 성능이 중요한 경우를 위해 설계되었습니다.

Pretext는 기존 DOM 측정이 병목이 된 복잡한 텍스트 중심 UI를 구축하는 개발자를 위해 설계되었습니다. 프로덕션에 바로 사용할 수 있는 핵심 기능들입니다.

DOM 읽기 제로

Pretext에서 prepare() 이후, 모든 layout() 호출은 순수 산술 연산입니다. getBoundingClientRect 없음, offsetHeight 없음, 강제 동기 리플로우 — 절대 없습니다.

🔡

실제 폰트 메트릭

Pretext는 휴리스틱이나 조회 테이블이 아닌, 브라우저 자체의 Canvas 폰트 엔진을 사용하여 글리프 너비를 측정합니다. 결과는 브라우저가 실제로 렌더링하는 것과 일치합니다.

🌍

다국어 지원 설계

Pretext는 올바른 유니코드 분할과 양방향 텍스트 처리를 포함하여 CJK, 아랍어, 히브리어, 태국어, 힌디어, 한국어 문자 체계를 완벽하게 지원합니다.

📘

TypeScript 네이티브

처음부터 TypeScript로 작성되었습니다. 모든 함수, 매개변수, 반환 값에 정확한 타입이 있으며 — @types 패키지 필요 없음, 타입 체조 필요 없습니다.

♻️

재사용 가능한 prepared 핸들

하나의 prepare() 호출로 모든 컨테이너 너비를 커버합니다. 동일한 핸들에서 세 번의 산술 연산으로 모바일, 태블릿, 데스크톱 높이를 계산하세요.

📦

런타임 의존성 제로

외부 패키지 없음, 폴리필 없음, 번들에 예상치 못한 요소 없음. Pretext는 모든 최신 환경에서 사용 가능한 표준 브라우저 API만 사용합니다.

// 데모

실제 시나리오에서의 Pretext.

Pretext는 기존 DOM 측정이 한계에 부딪히는 곳에서 가장 빛납니다. 이 예제들은 가상 스크롤링에서 다국어 채팅 인터페이스까지 실제 프로덕션 과제를 해결하는 Pretext를 보여줍니다.

모든 예제 →
// 커뮤니티 쇼케이스

Pretext로 만든 작품들.

커뮤니티의 창의적인 데모들 — 텍스트 드럼 머신, 유체 시뮬레이션, 협업 화이트보드 등. 개발자들이 Pretext로 만들고 있는 것들을 확인하세요.

모든 쇼케이스 →
// 시작하기

3분 안에 Pretext를 설치하세요.

Pretext는 npm에 게시되어 있으며 완전한 TypeScript 선언과 함께 제공됩니다. 원하는 패키지 매니저로 설치하고, 필요한 두 함수를 import하면 DOM을 건드리지 않고 텍스트를 측정할 준비가 완료됩니다.

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

// 1단계: 주어진 텍스트 + 폰트 쌍에 대해 한 번 준비
const handle = prepare(
  'Hello, pretext.js — no reflow needed.',
  '16px "Inter"'
);

// 2단계: 어떤 너비에서든 즉시 레이아웃
const { height, lineCount } = layout(
  handle,
  400,  // 컨테이너 너비 (px)
  24    // 줄 높이 (px)
);

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

// 3단계: 다른 너비에 핸들 재사용
const narrow = layout(handle, 240, 24); // → 3줄
// 블로그

Pretext 블로그.

텍스트 렌더링, 브라우저 성능, 그리고 개발자들이 매일 겪는 문제를 Pretext가 어떻게 해결하는지에 대한 심층 분석 — 근본 원인을 모르더라도.

모든 글 →
// 다음 단계

오늘 Pretext를 사용해 보세요.

가상 스크롤 목록, 코드 에디터, AI 채팅 인터페이스, 또는 텍스트 높이가 중요한 무엇을 만들든 — Pretext는 성능 비용 없이 정확한 측정을 제공합니다.

Pretext.js - DOM을 건드리지 않는 텍스트 측정.