
这两天在前端圈炸开锅的一个项目,短短几天就获得了海量关注。
仅三天,GitHub 标星直接狂飙到20.8K,目前还在持续上涨中。

该项目叫做 pretext,很多开发者看完后拍案叫绝,直呼 「这才是我们真正需要的东西」。
做前端的都知道,文本测量 一直是个老大难问题。
要知道一段文字会占多大空间,传统做法必须先把它渲染到DOM里,然后用getBoundingClientRect 或者 offsetHeight 去量。
这听起来简单,但每次测量都会触发浏览器的布局回流(reflow),这可是浏览器里最昂贵的操作之一。
每次性能优化,我们都在和这些DOM测量做斗争。几万条消息量下来,页面直接卡死。
而现在 pretext 帮我们找到了一个全新的解决方式。
pretext 是一个纯 JS/TS 写的文本测量引擎,由知名开发者chenglou(React核心贡献者之一)推出。

它的核心理念很简单:让你不碰DOM就能精确知道文字会占多大空间。
这个项目不是凭空出现的,它的设计思路可以追溯到Sebastian Markbage十年前的text-layout项目。
但pretext把这个想法推向了新的高度,支持了几乎所有你能想到的语言场景,处理了各种浏览器的 quirks。
pretext目前支持渲染到DOM、Canvas、SVG,未来还会支持服务端渲染。它把前端文本排版从浏览器的黑盒里解放出来,变成了可预测、可缓存的东西。
1️⃣ 不依赖DOM,零回流
pretext 完全绕过了DOM测量。
它用Canvas作为底层来测量文本宽度,但只在prepare阶段做一次,之后的所有layout都是纯算术运算。
这意味着你想测量多少次就测量多少次,完全不用担心性能问题。
2️⃣ 快到离谱的性能
官方基准测试数据:500段文本批量prepare()约19ms,layout()约0.09ms。
对比传统DOM测量,快了整整500倍!这个性能差异是什么概念?原本只能做几十次测量的预算,现在能做几万次。
3️⃣ 支持几乎所有语言
这是最让人惊叹的一点。
pretext支持中日韩、阿拉伯RTL、Emoji混排、混合双向文本,甚至处理了你不知道名字的语言。它还自动处理各种浏览器的quirks,保证在不同环境下结果一致。
4️⃣ AI友好的设计
pretext的实现方式特别适合AI迭代。
它用浏览器自己的字体引擎作为ground truth,可以快速迭代优化。在AI生成界面的时代,这种可预测的文本测量能力简直是基础设施级别的存在。
pretext提供了两类API,满足不同的使用场景。
第一类:简单测量段落高度
这是最常用的场景,只需要两个函数:
比如在resize的时候,你只需要重新调用layout(),而不需要重新prepare(),性能完全不是问题。
第二类:手动布局段落行
如果你需要更精细的控制,比如让文字环绕图片、实现各种奇特的布局,pretext也提供了丰富的API:
这些API让你能实现任何你能想到的文本布局效果,比如文字环绕图片、瀑布流布局、动态调整每行宽度等等。
安装
npm install @chenglou/pretext最简单的用法:
测量段落高度,不碰DOM:
import { prepare, layout } from '@chenglou/pretext'
const prepared = prepare('AGI 春天到了. بدأت الرحلة 🚀', '16px Inter')
const { height, lineCount } = layout(prepared, 300, 20)就是这么简单!没有DOM操作,没有回流,纯计算。
处理textarea风格的文本:
如果你需要保留空格、制表符和换行符:
const prepared = prepare(textareaValue, '16px Inter', { whiteSpace: 'pre-wrap' })
const { height } = layout(prepared, textareaWidth, 20)手动布局行:
让文字环绕图片:
import { prepareWithSegments, layoutNextLine } from '@chenglou/pretext'
const prepared = prepareWithSegments('很长的文本...', '18px "Helvetica Neue"')
let cursor = { segmentIndex: 0, graphemeIndex: 0 }
let y = 0
while (true) {
const width = y < image.bottom ? columnWidth - image.width : columnWidth
const line = layoutNextLine(prepared, cursor, width)
if (line === null) break
ctx.fillText(line.text, 0, y)
cursor = line.end
y += 26
}找到最合适的容器宽度
用walkLineRanges找到最宽的行,得到刚好能容纳文本的宽度:
let maxW = 0
walkLineRanges(prepared, 320, line => {
if (line.width > maxW) maxW = line.width
})其他辅助函数
import { clearCache, setLocale } from '@chenglou/pretext'
// 清除缓存,释放内存
clearCache()
// 设置语言环境
setLocale('zh-CN')查看演示
你可以clone仓库运行演示:
git clone https://github.com/chenglou/pretext
cd pretext
bun install
bun start然后打开浏览器访问 /demos(注意不要加末尾斜杠)。或者直接访问在线演示:chenglou.me/pretext
pretext的出现,代表着前端开发的一个重要转变。它把原本封闭在浏览器内部的文本排版能力,以一种可预测、可缓存的方式暴露给了开发者。
这解锁了太多可能性:
在AI生成界面的时代,这种能力简直是基础设施级别的。你可以想象,未来的AI界面生成器,会大量依赖这样的库来保证生成的界面是正确的。
pretext是一个革命性的文本测量引擎,它让前端开发者终于摆脱了DOM测量的性能桎梏。
500倍的性能提升,全语言支持,零回流操作——这每一点都足够让人兴奋。
如果你正在做虚拟滚动、复杂排版、或者任何需要频繁测量文本的应用,pretext绝对值得你加入技术栈。它不仅能提升性能,更能让你的代码变得更简洁、更可维护。
最后,别忘了去GitHub给这个项目点个Star,支持一下这些默默为前端社区做贡献的开发者们!
GitHub: https://github.com/chenglou/pretext
如果本文对您有帮助,也请帮忙点个 赞👍 + 在看 哈!❤️
在看你就赞赞我!