Back

Pretext и будущее вёрстки текста в вебе

Pretext и будущее вёрстки текста в вебе

Браузерная вёрстка справляется с большинством задач превосходно. Однако когда требуется последовательно измерить высоту тысяч текстовых блоков, начинают проявляться её ограничения. Именно это противоречие и призвана устранить библиотека Pretext.

Ключевые выводы

  • DOM-reflow, инициируемые вызовами getBoundingClientRect() или обращениями к offsetHeight, относятся к наиболее затратным операциям при рендеринге в браузере и быстро накапливаются в интерфейсах, где требуется измерять множество текстовых блоков.
  • Pretext — это TypeScript-библиотека, которая выполняет измерение и вёрстку текста полностью за пределами DOM, используя двухфазную архитектуру: prepare() и layout().
  • Библиотека ориентирована на конкретные узкие места: виртуализированные списки, masonry-сетки, ленты AI-чатов и интерфейсы на основе canvas, — но не предназначена для общей вёрстки страниц.
  • Pretext отражает более широкую тенденцию: вёрстка и измерение всё чаще рассматриваются как программируемые задачи на уровне приложения, а не как ответственность браузера, скрытая за чёрным ящиком.

Реальная цена DOM-reflow

Когда вы вызываете getBoundingClientRect() или обращаетесь к offsetHeight DOM-элемента, браузер вынужден приостановиться и пересчитать геометрию страницы, прежде чем вернуть ответ. Это layout reflow — и на странице со сложной структурой данная операция является одной из наиболее дорогостоящих при рендеринге.

Для большинства интерфейсов эти затраты незаметны. Но в виртуализированных списках, masonry-сетках, лентах AI-чатов или любых UI, где требуется динамически измерять сотни текстовых блоков, reflow накапливается стремительно. Результат — просадки частоты кадров, «дёрганье» анимации и интерфейсы, которые ощущаются тяжелее, чем должны быть.

Именно эту конкретную проблему решает Pretext. Не CSS. Не общий рендеринг. Только узкий и болезненный случай: повторные измерения текста, провоцирующие повторный DOM-reflow.

Подход Pretext к измерению текста

Pretext — это библиотека с открытым исходным кодом на TypeScript, созданная Чэн Лу (Cheng Lou), известным своим вкладом в развитие React, а ныне инженером в Midjourney. Библиотека выполняет измерение и вёрстку текста полностью за пределами DOM, используя двухфазную архитектуру.

Фаза первая: prepare()

import { prepare, layout } from '@chenglou/pretext'

const prepared = prepare('Hello, world 🌍', '16px Inter')

Это затратный шаг, который выполняется единожды. Pretext использует метод measureText() из Canvas API для сегментации текста, применяет правила переноса строк Unicode и кэширует ширину каждого сегмента в пикселях. Никаких обращений к DOM. Никакого reflow. Поддержка в современных браузерах зависит от таких API, как Intl.Segmenter, которые сегодня широко доступны.

Фаза вторая: layout()

const { height, lineCount } = layout(prepared, 320, 24)
// Чистая арифметика. Без DOM. Без reflow.

Это «горячий путь». Зная ширину контейнера и высоту строки, функция вычисляет итоговую высоту с переносами, опираясь исключительно на закэшированные ширины сегментов. Её можно вызывать при каждом событии изменения размера окна, не инициируя ни единого reflow.

Бенчмарки, опубликованные в момент выхода библиотеки, показывают: одна операция layout() для 500 текстовых блоков занимает с Pretext около 0,09 мс — значительно меньше, чем при измерении через DOM. Библиотека также поддерживает многоязычный текст, двунаправленные письменности и эмодзи — это стало возможным благодаря итеративной разработке с применением ИИ, где браузерный рендеринг использовался в качестве эталона для верификации результатов.

Где это действительно имеет смысл

Pretext не является заменой CSS. Он не управляет визуальным рендерингом, деревом доступности или полной сложностью строчной модели форматирования браузера. Это специализированный инструмент для конкретного узкого места.

Сценарии, в которых он применим:

  • Виртуализированные текстовые списки, где необходимо знать точную высоту элементов до их рендеринга
  • Masonry-раскладки, требующие предварительно рассчитанной высоты блоков для размещения по колонкам
  • Интерфейсы AI-чатов с потоковыми сообщениями переменной длины
  • Canvas- или WebGL-интерфейсы, где текст должен располагаться полностью за пределами DOM
  • Редакторы и ленты, в которых вёрстка постоянно пересчитывается по мере изменения контента

Для обычной контентной страницы, блога или маркетингового сайта Pretext не нужен. Нативная вёрстка браузера прекрасно справляется с этими случаями.

Более широкая тенденция, заслуживающая внимания

Pretext отражает паттерн, который становится всё более распространённым во фронтенд-разработке: вёрстка, измерение и рендеринг всё чаще рассматриваются как программируемые задачи на уровне приложения, а не делегируются браузеру. Библиотеки react-window и react-virtualized уже реализуют этот подход применительно к виртуализации списков. Pretext распространяет его на уровень измерения текста.

Интересен не вопрос о том, что именно Pretext заменяет, — он ничего не заменяет. Настоящий вопрос звучит иначе: что становится возможным, когда вёрстка текста перестаёт быть чёрным ящиком? Текстовый поток переменной ширины, контейнеры по содержимому, серверное предсказание вёрстки и алгоритмы выравнивания полиграфического качества — всё это превращается в решаемые задачи.

Для фронтенд-разработчиков, работающих над интерфейсами, где измерение текста является реальным узким местом, Pretext заслуживает пристального изучения. Для всех остальных — это полезный сигнал о том, в каком направлении движется граница возможностей браузерного рендеринга.

Заключение

Pretext не пытается заменить движок вёрстки браузера. Он выделяет одну узкую и дорогостоящую проблему — повторное измерение текста — и решает её чисто, выходя за пределы DOM. Для большинства сайтов это различие несущественно. Но для команд, создающих виртуализированные ленты, masonry-раскладки или интерфейсы на основе canvas, библиотека предлагает ощутимый прирост производительности. Что важнее, она указывает на будущее, в котором вёрстка текста становится программируемым примитивом, а не закрытым поведением браузера.

Часто задаваемые вопросы

Нет. Pretext отвечает только за измерение текста и расчёт переносов строк за пределами DOM. Он не выполняет визуальный рендеринг, не управляет деревом доступности и не обрабатывает полную строчную модель форматирования. Для фактического рендеринга вы по-прежнему полагаетесь на CSS и браузер. Pretext дополняет браузерную систему вёрстки в критичных по производительности сценариях измерения, но не заменяет её.

Если ваше приложение представляет собой обычный контентный сайт, блог, маркетинговую страницу или любой интерфейс, не требующий динамического измерения сотен текстовых блоков, Pretext добавляет сложность без ощутимой выгоды. Нативная вёрстка браузера вполне справляется с такими случаями. Обращайтесь к Pretext только тогда, когда DOM-reflow от повторных измерений текста подтверждён как узкое место по данным профилирования.

Pretext использует метод measureText из Canvas API в сочетании с правилами переноса строк Unicode для сегментации текста. Библиотека поддерживает эмодзи, двунаправленные письменности и многоязычный контент; её поведение было отточено в ходе итеративной разработки с применением ИИ, при которой результаты сравнивались с браузерным рендерингом — браузер выступал эталоном для проверки корректности.

Пока не в полной мере. На данный момент Pretext ориентирован на браузерные среды, хотя серверная поддержка обсуждается в проекте и может стать практически реализуемой там, где доступны совместимые реализации canvas. Серверное предсказание вёрстки и предварительный расчёт высот остаются перспективными сценариями использования в будущем, однако на сегодняшний день их следует считать экспериментальными.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay