
Pretext、文本高度计算、JavaScript文本测量、TypeScript排版库、Canvas文本布局、虚拟列表优化、前端性能优化、DOM Reflow、文本换行计算、富文本排版
Pretext 是一个高性能 JavaScript/TypeScript 文本测量与排版库,无需访问 DOM 即可精准计算文本高度和换行结果,适用于虚拟列表、AI聊天应用、Canvas 编辑器、瀑布流布局等场景。

大家好 这里是「代码简单说」,欢迎大家关注同名公众号,不定时更新更多实用有趣的教程 也欢迎大家在评论区一起讨论交流!~
在前端开发中,文本高度计算一直是一个比较头疼的问题。
很多开发者会通过:
getBoundingClientRect()offsetHeightclientHeight等方式获取文本尺寸。
但这些 API 都有一个共同的问题:
会触发浏览器 Layout(布局计算)和 Reflow(回流),在大量数据场景下性能开销巨大。
最近发现一个非常有意思的开源项目:
Pretext 是一个基于 JavaScript / TypeScript 开发的高性能文本测量与排版库。
它最大的特点是:
✅ 不依赖 DOM
✅ 不触发浏览器回流
✅ 支持多语言文本
✅ 支持 Canvas、SVG、自定义渲染
✅ 支持虚拟列表、瀑布流等复杂布局场景
GitHub:
Pretext 的核心目标:
在完全不访问 DOM 的情况下,精确计算文本布局信息。
传统方案:
element.getBoundingClientRect()浏览器需要:
Style Calculation
↓
Layout
↓
Paint
↓
Composite其中 Layout 是最昂贵的步骤之一。
而 Pretext:
文本
↓
Canvas测量
↓
缓存宽度
↓
纯数学计算整个过程不会触发页面布局。
使用 npm 安装:
npm install @chenglou/pretext或者:
pnpm add @chenglou/pretext或者:
yarn add @chenglou/pretextPretext 内部基于:
Intl.Segmenter实现文本分段。
因此支持:
例如:
AGI 春天到了
بدأت الرحلة 🚀都能正确处理换行和测量。
这是最核心的功能。
例如一个聊天应用:
import { prepare, layout } from '@chenglou/pretext'
const prepared = prepare(
'AGI 春天到了. بدأت الرحلة 🚀',
'16px Inter'
)
const result = layout(
prepared,
320,
20
)
console.log(result)输出:
{
height: 40,
lineCount: 2
}参数说明:
layout(
prepared,
maxWidth,
lineHeight
)参数 | 说明 |
|---|---|
prepared | 预处理文本 |
maxWidth | 最大宽度 |
lineHeight | 行高 |
Pretext 使用两阶段设计。
const prepared = prepare(
text,
'16px Inter'
)执行:
只执行一次。
layout(
prepared,
width,
lineHeight
)执行:
纯数学计算不会再次测量文本。
窗口缩放时:
window.onresize = () => {
layout(prepared,newWidth,20)
}即可重新计算高度。
默认行为类似:
white-space: normal;如果需要保留:
可以这样:
prepare(
text,
'16px Inter',
{
whiteSpace: 'pre-wrap'
}
)例如:
hello
world布局结果会与 textarea 保持一致。
对应 CSS:
word-break: keep-all;使用方式:
prepare(
text,
'16px Inter',
{
wordBreak: 'keep-all'
}
)适用于:
文本排版。
对应 CSS:
letter-spacing例如:
prepare(
text,
'16px Inter',
{
letterSpacing: 2
}
)等同于:
letter-spacing: 2px;很多场景不仅需要高度。
还需要知道:
第一行是什么
第二行是什么
第三行是什么使用:
layoutWithLines()示例:
import {
prepareWithSegments,
layoutWithLines
} from '@chenglou/pretext'
const prepared =
prepareWithSegments(
'Hello Pretext',
'18px Arial'
)
const result =
layoutWithLines(
prepared,
320,
26
)
console.log(result.lines)输出:
[
{
text:"Hello",
width:80
},
{
text:"Pretext",
width:100
}
]获取每行文本后:
for(let i=0;i<lines.length;i++){
ctx.fillText(
lines[i].text,
0,
i * 26
)
}即可实现:
很多时候需要:
文本最小包裹宽度例如聊天气泡:
import {
measureLineStats
} from '@chenglou/pretext'
const stats =
measureLineStats(
prepared,
320
)
console.log(
stats.maxLineWidth
)返回:
{
lineCount:3,
maxLineWidth:198
}可以直接用于:
width: fit-content;类似效果的实现。
Pretext 支持动态宽度布局。
例如:
┌───────┐
│ 图片 │文字
│ 图片 │文字
└───────┘文字
文字文字文字代码:
while(true){
const width =
y < image.bottom
? columnWidth - image.width
: columnWidth
const range =
layoutNextLineRange(
prepared,
cursor,
width
)
if(!range) break
const line =
materializeLineRange(
prepared,
range
)
ctx.fillText(
line.text,
0,
y
)
y += 26
}这类功能在浏览器中实现往往比较复杂。
Pretext 可以轻松完成。
项目还提供:
@chenglou/pretext/rich-inline专门处理:
例如:
const prepared =
prepareRichInline([
{
text:'Hello '
},
{
text:'@Tom',
break:'never',
extraWidth:20
}
])其中:
break:'never'表示:
不可拆分适合:
例如:
提前计算高度:
layout(prepared,width,20)即可实现精准虚拟滚动。
无需:
offsetHeight提前获取卡片高度。
实现:
Masonry
Pinterest
小红书布局更加容易。
当前很多 AI 产品:
都需要动态渲染大量文本。
Pretext 可以:
体验会明显更好。
适用于:
提前完成文本布局计算。
传统方案:
文本
↓
DOM
↓
Layout
↓
Reflow
↓
获取高度Pretext:
文本
↓
Canvas测量
↓
缓存
↓
数学计算优势:
Pretext 是一个非常有潜力的文本排版引擎。
它填补了前端生态中一个长期存在的空白:
在不触发浏览器布局的前提下,准确计算多行文本尺寸与换行结果。
如果你正在开发:
那么 Pretext 值得深入研究。
项目地址:
GitHub:
https://github.com/chenglou/pretextNPM:
npm install @chenglou/pretext