---
title: "Pretext: DOM 리플로우 없이 텍스트 크기를 측정하는 TS 라이브러리"
published: 2026-03-28T16:52:45.000Z
canonical: https://jeff.news/article/1389
---
# Pretext: DOM 리플로우 없이 텍스트 크기를 측정하는 TS 라이브러리

Pretext는 getBoundingClientRect 같은 DOM 측정 없이 텍스트 크기를 계산하는 순수 JS/TS 라이브러리. prepare()/layout() 2단계 구조로 500개 텍스트 배치 기준 layout()이 0.09ms에 완료되며, 가상 스크롤·레이아웃 시프트 방지 등에 활용 가능하다.

- **Pretext** — DOM 레이아웃 리플로우 없이 텍스트 크기를 측정하는 순수 JS/TS 라이브러리가 나옴
  - `getBoundingClientRect`, `offsetHeight` 같은 DOM 측정을 완전히 우회하는 게 핵심
  - 브라우저 폰트 엔진을 ground truth로 삼아 자체 텍스트 측정 로직을 구현한 방식
  - DOM, Canvas, SVG 렌더링 지원하고 서버사이드도 곧 지원 예정

- 아키텍처가 깔끔한 2단계 구조로 되어 있음
  - **`prepare()`**: 공백 정규화, 텍스트 분절, 글루 규칙 적용, Canvas로 세그먼트 측정 → 결과를 캐싱
  - **`layout()`**: 캐싱된 폭 데이터로 순수 산술 연산만 수행하는 hot path
  - 리사이즈 시 `layout()`만 다시 호출하면 되니까 같은 텍스트에 `prepare()` 재실행할 필요 없음

> [!IMPORTANT]
> 벤치마크 수치가 인상적 — `prepare()`가 500개 텍스트 배치에 약 19ms, `layout()`은 같은 배치에 **0.09ms**. 거의 공짜 수준.

- 이 라이브러리로 풀 수 있는 문제들이 꽤 실용적임
  - DOM 측정 없는 **진짜 가상화/occlusion** — 추정치나 캐싱 없이 정확한 높이 계산 가능
  - Masonry 레이아웃, JS 기반 flexbox 등 유저랜드 레이아웃 구현
  - 새 텍스트 로드 시 스크롤 위치 재고정해서 **레이아웃 시프트 방지**
  - AI로 코드 생성할 때 버튼 라벨이 다음 줄로 넘어가는지 브라우저 없이 검증 가능

- 고급 API도 잘 갖춰져 있음
  - `layoutWithLines()` — 고정 폭에서 모든 라인 정보 반환
  - `walkLineRanges()` — 텍스트 문자열 빌드 없이 라인 폭과 커서 위치만 제공
  - `layoutNextLine()` — 폭이 변하는 경우 한 줄씩 레이아웃 가능
  - `{ whiteSpace: 'pre-wrap' }` 옵션으로 textarea 스타일 공백·탭·줄바꿈 보존도 됨

- 다국어·이모지·혼합 양방향 텍스트 지원이 되고, 브라우저별 quirk까지 대응함
  - 다만 macOS에서 `system-ui` 폰트 사용 시 `layout()` 정확도 이슈가 있어서 named font 써야 함
  - 아직 완전한 폰트 렌더링 엔진은 아니고, `white-space: normal` + `overflow-wrap: break-word` 조합이 기본 타겟

---

## 기술 맥락

- `getBoundingClientRect`이나 `offsetHeight` 같은 DOM 측정 API를 호출하면 브라우저가 레이아웃 리플로우를 강제로 수행해요. 이게 브라우저에서 가장 비싼 연산 중 하나거든요. 특히 가상 스크롤이나 동적 레이아웃에서 수백 개 요소의 높이를 측정해야 할 때 병목이 심해지는데, Pretext는 이 문제를 아예 DOM을 건드리지 않는 방식으로 풀어낸 거예요.

- `prepare()` / `layout()` 2단계 분리는 비용이 큰 연산(폰트 측정)과 싼 연산(산술 계산)을 명확히 나눈 설계예요. 윈도우 리사이즈처럼 layout만 바뀌는 상황에서 측정을 다시 할 필요가 없으니까, 실질적으로 0.09ms짜리 연산만 반복하면 되는 거죠.

- 가상화 라이브러리(react-virtuoso, tanstack-virtual 등)가 아이템 높이를 알아내려고 "일단 렌더링하고 측정하고 다시 렌더링"하는 패턴을 쓰는 건 이 DOM 측정 비용 때문이에요. Pretext가 정확한 높이를 미리 계산해줄 수 있다면 이 전체 사이클을 건너뛸 수 있어서, 가상 스크롤 성능이 근본적으로 달라질 수 있어요.

- Canvas에서 `measureText()`를 쓰는 접근은 새로운 건 아닌데, 이걸 다국어·양방향 텍스트·브라우저 quirk까지 포괄하는 수준으로 라이브러리화한 건 드문 시도예요. 특히 AI 코드 생성 시 렌더링 결과를 검증하는 용도는 꽤 참신하고요.

## 핵심 포인트

- DOM 레이아웃 리플로우를 완전히 우회하는 자체 텍스트 측정 엔진
- prepare() 19ms + layout() 0.09ms의 2단계 캐싱 아키텍처
- 다국어·이모지·혼합 양방향 텍스트 및 브라우저 quirk 대응
- 가상화·Masonry·레이아웃 시프트 방지 등 실용적 활용처

## 인사이트

DOM 측정 비용 문제를 라이브러리 레벨에서 근본적으로 해결하려는 시도. 특히 AI 코드 생성 시 렌더링 결과를 브라우저 없이 검증하는 용도가 새로운 수요를 만들 수 있음.
