查看: 5|回复: 0

前端项目Pretext

[复制链接]

10

主题

1

回帖

32

积分

新手上路

积分
32
发表于 昨天 13:53 来自手机 | 显示全部楼层 |阅读模式
前端项目Pretext
github.com/chenglou/pretext
这个一个纯 JavaScript/TypeScript 库,用于多行文本测量与布局。效果如视频。
Pretext 避免了对 DOM 测量的依赖(例如 getBoundingClientRect、offsetHeight),这些操作会触发布局回流,是浏览器中最昂贵的操作之一。它实现了自己的文本测量逻辑,以浏览器自身的字体引擎作为基准(非常适合 AI 友好的迭代方法)。

开发者chenglou的介绍:
“亲爱的前端开发者们(以及对界面未来感兴趣的朋友们):
我历经重重困难,为你们带来了一项在可预见的未来中尤为重要的 UI 工程基础内容(如果不是在实现上,至少在概念上):
一个快速、精确且全面的用户端文本测量算法,完全使用 TypeScript 编写,可用于在无需 CSS 的情况下布局整个网页,绕过 DOM 测量和重排。”

另一个开发者的解释:
许多人不明白这有多酷。我花了大量时间优化网页性能。

这是我在 lovable 和 spawn 工作时的主要任务之一。

下面是一个相对简单而全面的解释:

浏览器的渲染流水线是:Style → Layout → Paint → Composite。

Layout(布局)是最耗性能的步骤。它计算页面上每个元素的位置、大小和换行。

当你读取 offsetHeight 或 getBoundingClientRect 时,你会强制浏览器执行布局。如果在读取之前你对 DOM 进行了修改,它会重新计算所有内容。这就是重排(reflow)。

很多布局工作都是文本测量。比如这一行如何换行,这一段有多高,这个单词有多宽。浏览器是唯一能回答这些问题的地方,没有替代方案。你必须通过 DOM 来获取。

这也是人们日常遇到许多性能问题的根本原因。

虚拟滚动存在的原因是:你在渲染元素之前无法知道它们的高度。CSS contain 的存在是告诉浏览器“不要重新计算这个盒子外的布局”。批量读取和写入 DOM 的存在,是因为混合读写会导致布局抖动(layout thrashing)。

文本测量在这些场景中占了很大比重。它很慢,而且被锁在浏览器内部。

在真实应用中你也能看到这一点。

Slack 会估算消息高度以实现虚拟滚动。当估算不准确时,滚动会跳动。你肯定见过这种情况。

Google Docs 在一行换行时,会重新计算光标下方的每一段文字。每次按键都会触发。这就是为什么处理长文档时会变慢的原因。

AI 聊天应用在流式显示时会变得卡顿,因为每个新生成的 token 可能会导致换行,进而改变高度,页面随之跳动。

每次问题都是一样的:需要文本测量。获取它们的唯一方法是 DOM,而 DOM 很慢。

多年来,人们一直在将部分 UI 工作移出浏览器的布局引擎。渲染搬到了 Canvas 和 WebGL。滚动搬到了自定义实现(transform)。定位搬到了 JavaScript 计算坐标。交互处理一直都是 JS。

但文本是唯一无法移出的部分。你总是必须回到 DOM 去问“这段文字如何换行”。其他部分都有替代方案,唯独文本没有。

于是出现了 Pretext。纯 TypeScript 的文本测量和换行。无需 DOM,无需重排。你给它文字、字体和宽度,它返回精确的换行、宽度和高度。只需一个函数调用。纯数学计算。
文本测量曾是布局中唯一无法在 DOM 外完成的部分,现在不再是。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注公众号

相关侵权、举报、投诉及建议等,请发 E-mail:admin@discuz.vip

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.|青ICP备2025004122号-1

在本版发帖
关注公众号
返回顶部