Pretext一夜斩获13万星,前React核心成员出手干掉困扰前端30年的性能杀手

做过前端开发的同学,大概率都曾被一个问题折磨过:如何动态计算一段多行文本的高度?

为了实现一个高性能的长列表,或者做一个严丝合缝的聊天气泡,你不得不先让浏览器把文字渲染出来,然后调用以下方法去获取高度:

  • getBoundingClientRect
  • offsetHeight

结果呢?这会直接触发浏览器的强制同步布局回流(Layout Reflow)!

当页面上有 500 个文本块需要独立测量时,这种读写交替会导致每帧耗时飙升到 30 毫秒以上,界面的渲染会瞬间卡顿,掉帧掉到让人怀疑人生。

三十年来,前端开发者在这个问题上绞尽脑汁,妥协于各种“估算”和“魔法数字”。

但就在最近,一个名为 Pretext 的开源项目横空出世,在 GitHub 上迅速斩获 13 万+ Stars。

Pretext GitHub Star 数据截图

它不碰 DOM,不依赖浏览器回流,仅仅用纯粹的数学和缓存,就把多行文本测量的速度提升了几个数量级——单次排版计算耗时仅需惊人的 0.0002 毫秒

今天,我们就来扒一扒这个黑科技:它究竟是什么?它是怎么做到的?以及,它到底能帮我们解决哪些极其刁钻的真实业务场景?什么情况下又千万别用它?

1. 故事的主角与 AI 时代的降维打击

在这个项目背后,站着一位前端圈的传奇人物——Cheng Lou

他曾是 React 核心开发团队的成员,也是当年火爆全网 React-motion 动画库的原作者。

Cheng Lou 肖像图

文本排版引擎一直被认为是“地狱级”难度,因为你需要处理连字符、Emoji、中文的分词、阿拉伯语、希伯来语的从右到左阅读(RTL),甚至还要面对不同浏览器极其微小的渲染差异。

Hacker News 上有开发者感叹:“你一开始以为能搞定,3 个月后你会躲在角落里尖叫:为什么中文在多列渲染时标点符号的旋转方式不一样?!”

有趣的是,如此庞大繁琐、充满无数边缘用例的底层库,很大程度上是 Cheng Lou 在 AI(如 Claude Code 和 Codex)的深度辅助下完成的。

这向我们展示了 AI 时代顶级程序员的恐怖生产力:一个人加上 AI,就能完成过去需要整个浏览器团队才能做出的底层渲染逻辑。

2. 核心揭秘:Pretext 是如何做到“不碰 DOM 还准得离谱”的?

Pretext 是一个纯 JavaScript/TypeScript 编写的多行文本测量与布局库。

它的底层原理可以提炼为一个极具智慧的“两阶段流水线”:

2.1. 第一阶段:prepare() —— 磨刀不误砍柴工

这是一次性的预计算阶段。

  • 清理:按照 CSS 规则压缩空格和回车。
  • 分词:使用浏览器原生的 Intl.Segmenter 将长句子切分成词元,完美支持中日韩文、泰语(词之间无空格)和阿拉伯文。
  • 粘合:运用一套“胶水规则”,把标点符号死死粘在前面的词上(比如把“better.”当作整体),处理复杂的 Emoji。
  • 测量:利用离屏 Canvas API 测量这些切好的词元,并把结果死死缓存起来。

2.2. 第二阶段:layout() —— 极致的数学狂飙

当容器宽度改变,需要重新计算文本高度时,Pretext 完全不需要再去测量了。

它只需做一个最简单的纯数学遍历:把缓存的“词元宽度”加起来,超过最大宽度就换行。

这一步的耗时仅仅只有 0.0002 毫秒

为了证明算法的绝对精准,作者让 Pretext 跑完了《了不起的盖茨比》全书,以及海量的中文、泰文、阿拉伯文公版文献,与浏览器真实的 DOM 渲染结果进行了像素级的对比测试。

在文末,提供了一个图文拆解原理的讲解,有兴趣的可以阅读。

3. 杀手级落地场景:它究竟能解决什么痛点?

Hacker News 上的各路神仙开发者总结出了 Pretext 的几大杀手级应用场景,这些都是过去纯靠 CSS 或原生 DOM 极其难受、甚至无解的痛点:

3.1. 丝滑的 10 万级数据网格与虚拟列表(Virtualization)

在做包含几十万行的复杂数据表格时,如果单元格里是高度不固定的多行文本,传统的做法只能靠“猜高度”。

有了 Pretext,你可以瞬间、低成本地计算出 10 万行文本的精准高度,无需渲染任何 DOM 就能实现绝对完美的滚动体验。

3.2. 完美包裹的“聊天气泡”与 UI 徽章(Badges)

想让带有背景色的气泡完美包裹住内部多行文字,且右侧不要留出难看的空白,在纯 CSS 中极其困难(这也是 W3C 正在头疼的提案)。

Pretext 可以在 JS 层精准计算每一行的真实排版,让你彻底告别那些丑陋的排版缝隙。

3.3. 视频生成与动态字幕(如 Remotion)

在用代码生成视频时,动态计算字幕需要占多少行一直是个玄学问题。

Pretext 提供了底层的 API,可以精准吐出每一行包含哪些词,让动态视频字幕的生成变得极其简单。

3.4. 突破天际的 Canvas / WebGL 异形渲染

如果你想在 Canvas、SVG 甚至 WebGL 里面画多行文本,你会绝望地发现 Canvas 根本不支持自动换行!

现在,你可以用纯 JS 的 Pretext 直接算出每个词的坐标,甚至能让文本绕着一个 3D 的圆环(Torus)进行异形排版!

几个 demo:

4. 冷静一下:为什么你的产品官网大概率还用不上它?

看到这里,你可能已经跃跃欲试了。

比如在我开发的 AI 产品 CyberWhisper(cyberwhisper.ai)的官网,页面里有很多精美的“打字机波浪特效”卡片,以及一些 AI 对文字进行加工处理的动画效果,并且它们都需要适配手机和电脑端。

CyberWhisper 官网效果截图一

CyberWhisper 官网效果截图二

面对这种场景,能用 Pretext 来优化吗?

答案是:暂时不建议,强行引入反而会成为灾难。

为什么呢?这要从 Pretext 的核心定位说起:

4.1. 杀鸡焉用牛刀,性能痛点根本不匹配

Pretext 解决的是“高频次、大规模”读取 DOM 导致的性能雪崩(比如一帧内测量 500 个文本块引发 30 毫秒卡顿)。

而对于一个落地页上的几段介绍文字、哪怕是多设备的响应式换行,现代浏览器的原生渲染性能早已优化到了极致,完全可以轻松拿捏,引入 Pretext 不会带来任何肉眼可见的性能提升。

4.2. 它是排版计算器,不是动画渲染库

千万要记住,Pretext 本身不渲染任何东西,最终的文字渲染还是得靠浏览器。

它只是一个输出排版数据(例如“这段话应该在哪里断行”)的“数学计算器”。

像这种网站,通常已经使用了现成的 DOM 动画库(比如依次给标签添加波浪动画)。

如果你强行引入 Pretext,你不得不自己写大量极其复杂的“胶水代码”:先让 Pretext 算好分词,然后手动把这些词拼装成 DOM 节点,再喂给你的动画库。

这不仅违背了动画库的初衷,还极易引发 Bug。

结论就是:如果你只是做普通的网页动效、少量文本的排版,请安心继续使用原生 CSS 和你熟悉的动画库。只有当你准备把网页画进 Canvas / WebGL 里,或者要手写一个支持十万级列表的长表格、或是开发下一代富文本编辑器时,Pretext 才是你不可或缺的神兵利器!

5. 结语:退一步,海阔天空

Hacker News 上的网友感慨:“等了 30 多年,Web 前端终于补齐了这项基础设施。”

Pretext 让我们看到了解决复杂问题的一种优雅思路:当你觉得某条路(频繁读取 DOM)走不通,性能陷入死胡同时,不妨退后一步,拆解问题(把分词和布局拆开),用最纯粹的数学去降维打击。

如果你团队的产品正好卡在长列表性能、Canvas 画布文本渲染、视频生成、或是需要极其精准的排版控制上,别犹豫,现在就去 GitHub 上给 Pretext(github.com/chenglou/pretext)点个 Star,并把这个黑科技引入你的项目中吧!


附:Pretext 详细原理图

Pretext 详细原理图 1

Pretext 详细原理图 2

Pretext 详细原理图 3

Pretext 详细原理图 4

Pretext 详细原理图 5