본문으로 건너뛰기
피드

Pretext: DOM 리플로우 없이 텍스트 크기를 측정하는 TS 라이브러리

frontend 약 5분
vote
0
댓글
북마크

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

  • 1

    DOM 레이아웃 리플로우를 완전히 우회하는 자체 텍스트 측정 엔진

  • 2

    prepare() 19ms + layout() 0.09ms의 2단계 캐싱 아키텍처

  • 3

    다국어·이모지·혼합 양방향 텍스트 및 브라우저 quirk 대응

  • 4

    가상화·Masonry·레이아웃 시프트 방지 등 실용적 활용처

  • Pretext — DOM 레이아웃 리플로우 없이 텍스트 크기를 측정하는 순수 JS/TS 라이브러리가 나옴

    • getBoundingClientRect, offsetHeight 같은 DOM 측정을 완전히 우회하는 게 핵심
    • 브라우저 폰트 엔진을 ground truth로 삼아 자체 텍스트 측정 로직을 구현한 방식
    • DOM, Canvas, SVG 렌더링 지원하고 서버사이드도 곧 지원 예정
  • 아키텍처가 깔끔한 2단계 구조로 되어 있음

    • prepare(): 공백 정규화, 텍스트 분절, 글루 규칙 적용, Canvas로 세그먼트 측정 → 결과를 캐싱
    • layout(): 캐싱된 폭 데이터로 순수 산술 연산만 수행하는 hot path
    • 리사이즈 시 layout()만 다시 호출하면 되니까 같은 텍스트에 prepare() 재실행할 필요 없음

중요

> 벤치마크 수치가 인상적 — 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 측정 비용 문제를 라이브러리 레벨에서 근본적으로 해결하려는 시도. 특히 AI 코드 생성 시 렌더링 결과를 브라우저 없이 검증하는 용도가 새로운 수요를 만들 수 있음.

댓글

댓글

댓글을 불러오는 중...

frontend

요즘 픽셀 폰트가 그냥 복고 감성이 아닌 이유

1990년대 기기 화면 느낌을 현대 폰트 시스템으로 재해석한 픽셀 폰트 몇 가지를 소개한 글이다. 핵심은 예쁜 복고풍 글자 모양만이 아니라, 실제 제품에서 쓸 수 있게 기준선, 자간, 메타데이터, 세로 메트릭까지 챙기는지가 중요하다는 점이다.

frontend

HTML의 `<dl>`이 생각보다 쓸모 많은 이유

이 글은 HTML의 description list, 즉 `<dl>`, `<dt>`, `<dd>`가 단순 용어 사전용 태그가 아니라 이름-값 쌍 UI를 표현하는 꽤 강력한 시맨틱 도구라고 설명한다. 숙소 편의시설, 요금 내역, 기술 용어 설명, 게임 능력치표처럼 흔한 패턴을 중첩 `<div>` 대신 의미 있는 HTML로 만들 수 있다는 얘기다.

frontend

HTML을 캔버스 안에 넣는 데모 모음이 등장함

구글 크롬 랩스 저장소에 HTML-in-Canvas 관련 데모와 프레임워크 지원 목록이 정리됐다. Duck Hunt 스타일 폼, 흔들리는 버튼, 셰이더 기반 페이지 전환, 천처럼 매달린 폼 같은 실험적 예제가 포함돼 있고 Three.js와 PlayCanvas 쪽 샘플도 연결돼 있다.

frontend

싱글 페이지 앱이 웹을 너무 비싸게 만들었다는 불평

이 글은 싱글 페이지 앱(SPA)이 사용자 경험을 좋게 만든다는 명분 아래 웹의 초기 로딩 비용, 도구 복잡도, 개발 진입 장벽을 키웠다고 비판한다. 페이스북 로그인 페이지의 CSS 3.8MB, 레딧 몇 개 클릭 후 33MB 다운로드 같은 숫자를 들며, 지금의 프론트엔드 생태계가 사람보다 대기업의 요구에 맞춰져 있다고 주장한다.

frontend

네이티브로 끝까지 가려다 텍스트에서 막힌 macOS 개발자의 고백

20년 가까이 macOS와 iOS 네이티브 개발을 해온 작성자가 SwiftUI, AppKit, TextKit 2로 마크다운 채팅 UI를 만들다 결국 WebKit과 Electron 쪽이 훨씬 낫다는 결론에 도달한 글이다. 문제는 성능 하나가 아니라 선택, 스트리밍, 스크롤, 접근성, 텍스트 상호작용 같은 ‘사용자가 당연히 기대하는 기본기’가 네이티브 조합에서 계속 깨진다는 점이다.