Обзор Pretext.JS
Pretext.JS — это быстрый, чистый JavaScript/TypeScript‑движок для расчёта текстового макета, который измеряет и раскладывает многострочный текст полностью с помощью арифметики, не обращаясь к Document Object Model (DOM). Он устраняет узкое место производительности — «forced synchronous reflows», возникающее из‑за традиционных DOM‑измерений вроде getBoundingClientRect(), и обеспечивает значительно более быстрый и эффективный расчёт текстового макета. Основывается на принципе «один раз измерил — далее раскладываешь мгновенно», что делает все последующие вычисления макета практически моментальными.
Основное назначение
Предоставлять высокопроизводительные, точные и не требующие перерасчёта DOM измерения текстового макета (например, высоты и количества строк) для динамичных и сложных веб‑интерфейсов. Решает критическую проблему «browser thrashing», возникающую из‑за повторяющихся DOM‑измерений.
Целевая аудитория
Веб‑разработчики и команды, создающие производительно критичные, текстоёмкие пользовательские интерфейсы. Это приложения с виртуальными списками и скроллингом, AI‑чаты, редакторы кода, коллаборативные доски, системы визуализации данных и любые сценарии, где динамический текстовый макет должен быть плавным, быстрым и отзывчивым без ухудшения пользовательского опыта.
Подробности работы и операции
Pretext.JS работает в два основных шага:
-
prepare(text, font)
Эта функция вызывается один раз для заданной текстовой строки и стиля шрифта. Нормализует пробелы, применяет правила переноса строк Unicode, сегментирует текст и точно измеряет ширину глифов каждого сегмента с помощью шрифтового движка Canvas в браузере. Результаты кэшируются в переиспользуемом «handle». -
layout(handle, containerWidth, lineHeight)
Эта функция — чистая арифметика и выполняется мгновенно. Получив подготовленный handle, ширину контейнера и высоту строки, она вычисляет переносы строк путём суммирования ширин сегментов, считает общее количество строк и определяет итоговую высину текста. Ключевой момент: этот шаг полностью обходится без чтения из DOM, что гарантирует отсутствие reflow.
Ключевые возможности
-
Нулевые чтения из DOM
После первоначального вызоваprepare()все операцииlayout()— чисто арифметические, полностью обходятся безgetBoundingClientRect(),offsetHeightи принудительных синхронных reflow. -
Реальные метрики шрифтов
Использует нативный шрифтовой движок Canvas в браузере для измерения ширины глифов, благодаря чему макет точно соответствует фактическому рендерингу текста в браузере. -
Многоязычная поддержка по умолчанию
Полноценная поддержка сложных письменностей, включая CJK (китайский, японский, корейский), арабский, иврит, тайский, хинди, с корректной сегментацией по Unicode и обработкой двунаправленного текста. -
Нативный TypeScript
Разработан изначально на TypeScript и предоставляет точные типы для всех функций, параметров и возвращаемых значений без необходимости в сторонних пакетах@types. -
Переиспользуемые подготовленные handle
Один вызовprepare()создаёт handle, который можно многократно использовать для расчёта макета при разных ширинах контейнера (например, мобильный, планшет, десктоп) с минимальными накладными расходами. -
Отсутствие runtime‑зависимостей
Полностью построен на стандартных браузерных API, что обеспечивает небольшой размер бандла и отсутствие проблем с внешними пакетами.
Преимущества для пользователя
-
Исключительная производительность
Обеспечивает до 500‑кратного ускорения расчёта текстового макета по сравнению с традиционными методами через DOM, позволяя добиться плавного скроллинга в 60fps и высокой отзывчивости интерфейса даже при тысячах динамических текстовых элементов. -
Улучшенный пользовательский опыт
Устраняет «дёргание» интерфейса, скачки и рывки, обеспечивая плавное и стабильное визуальное поведение, особенно в динамичных лентах контента или интерфейсах чатов. -
Точный макет
Гарантирует корректные измерения текста, совпадающие с реальным рендерингом в браузере, предотвращая визуальные несоответствия. -
Упрощение разработки
Предлагает прямолинейный, нативный для TypeScript API, который скрывает сложность измерения текста и повышает продуктивность разработчиков. -
Готовность к глобальным приложениям
Надёжная поддержка разных письменностей позволяет создавать по‑настоящему интернационализированные приложения. -
Лёгкий и надёжный
Отсутствие внешних зависимостей уменьшает размер бандла и повышает стабильность.
Совместимость и интеграция
-
Независимость от фреймворков
Как чистая JavaScript/TypeScript‑библиотека, Pretext.JS легко интегрируется в любой современный веб‑фреймворк (React, Vue, Angular, Svelte) или в проект на ванильном JavaScript. -
Поддержка современных браузеров
Опирается на стандартные браузерные API, доступные во всех современных веб‑средах. -
Установка
Легко устанавливается через популярные пакетные менеджеры: npm, pnpm и bun. -
Интеграция с TypeScript
Нативная поддержка TypeScript обеспечивает бесшовное подключение к TypeScript‑проектам без дополнительной конфигурации.
Практические приложения и демо
-
Виртуальный скролл
Демонстрирует рендеринг 10 000 строк переменной высоты с плавным скроллингом 60fps, причём все вычисления выполняются полностью без чтения из DOM. -
AI‑чат
Используется для предварительного вычисления высоты чат‑«баблов» при потоковой выдаче AI‑ответов, устраняя скачки и рывки макета. -
Интернационализация
Показывает точный макет многоязычных лент контента, смешивающих китайский, арабский, корейский и латиницу в одном виртуализированном списке. -
Сообщество и showcase‑проекты
Представляет креативные применения, такие как эффекты письма по песку, геометрические визуализации текста и обтекание текстом трёхмерных объектов в реальном времени, демонстрируя универсальность подхода.
Доступ и способы подключения
-
Установка
- Через npm:
$ npm install @chenglou/pretext - Через pnpm:
$ pnpm add @chenglou/pretext - Через bun:
$ bun add @chenglou/pretext
- Через npm:
-
Использование
- Импортируйте функции
prepareиlayout:
import { prepare, layout } from '@chenglou/pretext' - Вызовите
prepare(text, font)один раз, чтобы получить переиспользуемый handle. - Вызовите
layout(handle, containerWidth, lineHeight), чтобы мгновенно получить высоту текста и количество строк.
- Импортируйте функции
-
Изучение и демо
Живой playground и различные демонстрации доступны на официальном сайте (pretextjs.dev) для мгновенного тестирования и более глубокого понимания работы Pretext.JS.