Pretext 

22小时前发布 39 00

Pretext 是一个纯 JavaScript/TypeScript 库,它完全避开了 DOM,通过直接调用浏览器的 Canvas 字体引擎来实现极速、精准的文本测量与布局。无论是中文、阿拉伯语还是 Emoji 混合文本,Pretext 都能在不触发任何页面抖动的情况下,瞬间计算出精确的段落高度和行信息。

所在地:
中国
收录时间:
2026-03-29
其他站点:
Pretext Pretext 

在前端开发中,文本测量(Text Measurement)往往是一个隐蔽的性能杀手。传统的做法是将文本插入 DOM,读取其 getBoundingClientRect,然后再移除。这一过程会强制浏览器进行布局重排(Reflow/Layout Thrashing),这是浏览器中最昂贵的操作之一,尤其在处理大量文本或动画时,会导致严重的卡顿。

Pretext 

Pretext 是一个纯 JavaScript/TypeScript 库,它完全避开了 DOM,通过直接调用浏览器的 Canvas 字体引擎来实现极速、精准的文本测量与布局。无论是中文、阿拉伯语还是 Emoji 混合文本,Pretext 都能在不触发任何页面抖动的情况下,瞬间计算出精确的段落高度和行信息。

Pretext 

核心优势:快、准、无副作用

特性传统 DOM 测量Pretext
性能❌ 慢,强制触发重排 (Reflow)✅ 极快,纯算术运算,零重排
副作用❌ 需插入/移除节点,可能引起闪烁✅ 无副作用,完全在内存中运行
多语言支持⚠️ 依赖浏览器渲染,复杂脚本易出错✅ 原生支持,完美处理 RTL、Emoji、换行
运行环境🌐 仅限浏览器 DOM 环境🌐 DOM / Canvas / SVG / 服务端 (Node.js)
精度✅ 高✅ 极高 (直接使用浏览器字体引擎)

两大核心用例

Pretext 提供了灵活的 API,满足从“简单测高”到“自定义排版引擎”的不同需求。

用例 1:快速测量段落高度 (Measure Height)

适用于需要预先知道文本高度以分配容器空间的场景(如虚拟列表、动态卡片)。

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

// 1. 预处理:一次性分析文本、分割字素、测量基础宽度
// 返回一个不透明的句柄,包含所有缓存数据
const prepared = prepare('AGI 春天到了。بدأت الرحلة 🚀', '16px Inter')

// 2. 布局计算:纯算术运算,瞬间完成
// 传入最大宽度和行高,返回总高度和行数
const { height, lineCount } = layout(prepared, 300, 24) 

console.log(`文本高度: ${height}px, 共 ${lineCount} 行`)

原理prepare() 做了最重的活(调用 Canvas API 测量每个字素),layout() 只是基于缓存数据进行简单的加法和除法,因此可以无限次调用而不影响性能。

用例 2:手动控制行布局 (Custom Layout Engine)

适用于需要构建自定义文本渲染器、富文本编辑器或复杂排版的场景。

import { prepareWithSegments, layoutNextLine } from '@chenglou/pretext'

const text = 'AGI 春天到了。بدأت الرحلة 🚀'
const prepared = prepareWithSegments(text, '18px "Helvetica Neue"')

let cursor = { segmentIndex: 0, graphemeIndex: 0 }
let y = 0
const maxWidth = 320
const lineHeight = 26

// 逐行迭代,每行甚至可以有不同的宽度(如绕开图片)
while (true) {
  // 模拟绕开图片的逻辑:如果 y 在图片范围内,减小可用宽度
  const currentWidth = (y > 100 && y < 200) ? 200 : maxWidth
  
  // 获取下一行信息
  const line = layoutNextLine(prepared, cursor, currentWidth)
  
  if (line === null) break // 文本结束
  
  // 渲染到 Canvas 或其他目标
  ctx.fillText(line.text, 0, y)
  
  // 更新光标和 Y 坐标
  cursor = line.end
  y += lineHeight
}

强大的多语言与特性支持

Pretext 不仅仅是测英文,它对复杂书写系统的支持令人印象深刻:

  • 多语言混合:完美处理中文、日文、韩文 (CJK) 与拉丁字母混排。
  • RTL 支持:原生支持阿拉伯语、希伯来语等从右向左书写的语言。
  • Emoji 处理:正确识别 Emoji 字素簇(Grapheme Clusters),避免切断表情符号。
  • 换行规则:支持 word-breakoverflow-wrapline-break 等标准 CSS 行为。
  • 空白保留:支持 white-space: pre-wrap,保留空格、制表符和硬换行。

安装与使用

npm install @chenglou/pretext

辅助功能

  • 缓存管理clearCache() 可清除内部测量的字体缓存,释放内存。
  • 区域设置setLocale('ar-SA') 可全局设置区域,影响换行和测量逻辑(会自动清缓存)。

注意事项

  1. 字体名称:在 macOS 上,尽量避免使用 system-ui 这类通用族名,因为它们在不同上下文可能解析为不同字体,导致测量误差。建议使用具体的字体名称(如 'Inter''Helvetica Neue')。
  2. 服务端渲染 (SSR):Pretext 设计之初就考虑了 Node.js 环境。虽然目前主要依赖 Canvas API,但在即将更新的版本中将更好地支持纯服务端环境(可能需要 canvas 包作为 polyfill)。
  3. 首次开销prepare() 函数涉及 Canvas 测量,对于超长文本会有微小开销,但相比 DOM 重排依然快得多,且结果可复用。

应用场景

  • 虚拟列表 (Virtual Lists):在滚动前精确计算每行高度,避免滚动条跳动。
  • 动态卡片布局:根据文本内容自适应卡片高度,无需先渲染再调整。
  • Canvas/SVG 绘图:在画布上绘制文本前,预先计算换行和位置。
  • PDF 生成:在服务端生成 PDF 时,精确控制文本分页和布局。
  • 富文本编辑器:实现自定义的文本流布局和环绕效果。

数据统计

相关导航

暂无评论

none
暂无评论...