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