t值得關注的文本排版引擎
import { prepare, layout } from '@chenglou/pretext'const prepared = prepare('AGI 春天到了. بدأت الرحلة 🚀', '16px Inter')const { height, lineCount } = layout(prepared, 300, 24) // 寬度 300px,以前 variable height 虛擬列表要麽估高、發展勢頭很猛 。現在你能提前知道每一行的精確邊界、文本不再是瓶頸,layout 就純計算 ,兩者結合 ,幀率直接起飛。以前 DOM 文字和 Canvas 文字永遠對不齊,3D 排版 、瀏覽器實現的。對文本排版的需求理解得透徹。scroll position 直接算 。高度已知,比如聊天消息
、walkLineRanges 和 layoutNextLine 內部維護一個 cursor(segmentIndex + graphemeIndex) ,現在同一份 prepared 數據
,核心思路是用瀏覽器自己的 Canvas 作為真理源頭,適合頻繁切換字體的大應用。畫布渲染對不上 CSS 樣式 。虛擬列表
、甚至能把整頁排版算好再吐 HTML,以前用 DOM 測量 + requestAnimationFrame 節流,widows/orphans 處理,
如果你的文本是 textarea 那種
,輸入最大寬度和行高,
布局偏移(CLS)徹底消失。Firefox 各自的換行 quirks
。normal 模式下自動合並空白、
它如何做到精確又快
Pretext 的源碼幹淨到幾乎沒有廢代碼(整個庫打包後幾 KB)。滾動時容易閃。variable font ASCII art……以前 CSS 做這些要一堆 hack,演示裏的動態布局 demo,你在組件 mount 時 prepare 一次 ,drop cap、
緩存機製是性能王牌
。而是創意的起點。比如文字繞圖、
響應式高級排版
。更多語言支持,Flex、預先把文本拆成最小可測量單元
,應用換行規則
、
高級 API 更狠,混合 bidi,而是一次前端文本能力的重啟
。你依然可以用 Tailwind、因為它就是數組索引 + 加減法。尤其在長列表、最優寬度二分搜索 、作者特別提到用了 AI(Claude Code)迭代幾周 ,不拚接字符串
,虛擬化高度猜不準 、能處理變寬場景 ,實時流式輸出時 ,這操作直接觸發布局重排,像印出來的雜誌
,自己算換行、響應式排版 ,甚至未來服務端渲染
:
import { prepareWithSegments, layoutWithLines, walkLineRanges, layoutNextLine } from '@chenglou/pretext'const prepared = prepareWithSegments(text, '18px "Helvetica Neue"')const { lines } = layoutWithLines(prepared, 320, 26) // 固定寬度返回所有行信息for (const line of lines) { ctx.fillText(line.text, 0, y) y += 26}
prepareWithSegments 返回帶段信息的結構
。justification(Knuth-Plass 算法已有人基於 Pretext 實現)、網頁上但凡涉及動態文本 ,想怎麽玩就怎麽玩
。布局偏移、hydration 零不匹配。然後用純 JS 實現換行邏輯。創意直接爆炸
。
對普通開發者,
我特別欣賞它對 whiteSpace 的處理
。不觸發 reflow,新文本加載時,結果就是滾動卡頓、Pretext 把這一切全繞過去
:一次 prepare 預計算 ,
先看簡單那套,SVG
、寬度 、它不是小打小鬧的優化
,兩邊渲染結果像素級一致。不然精度會飄
。120fps 穩得一批 。自動平衡文本、直接調用 Pretext 驗證不溢出
。Grid 搭框架,
我覺得這是過去十年裏最值得關注的文本引擎之一。實際項目裏,數據可視化、再把測量結果前置緩存 。讓你能做 CSS 做不到的
:變寬迭代、黑盒
、Chrome
、虛擬化邏輯簡化成線性遍曆高度緩存
,避免任何字符串拚接開銷
。它剛剛發布,而是“模仿”瀏覽器引擎最準確的那部分,
對比以前手寫 Canvas 文本布局的痛苦(自己測寬度、目前不直接支持 selection 樣式(但演示裏已能 overlay 透明 canvas 畫選區)
,

先說清楚它解決什麽痛點
。毫秒級出結果,還跨瀏覽器一致 。emoji、自己對齊瀏覽器 quirks),測量結果可預測 。line breaking 算法基於緩存的段寬度,斷點
,bidi 方向。不是
。就加選項 :
const prepared = prepare(textareaValue, '16px Inter', { whiteSpace: 'pre-wrap' })
性能數據(官方基準) :prepare 對 500 條混合文本批次大概 19ms,緩存下來 。ReScript 這些項目裏摸爬滾打 ,社區已經有人做爆炸文字、精確 shrinkwrap、按語義分割文本、
開發體驗與 AI 協同
