對普通開發者,文本
不是取代 CSS
很多人問 :這不就是把 CSS 活搶了嗎?比如 CSS Shapes,
我特別欣賞它對 whiteSpace 的引擎處理。walkLineRanges 更底層,值注自動換行輸入框、得关家族),文本手寫動畫流式渲染 ,排版文字繞圖、引擎自己對齊瀏覽器 quirks) ,它讓你寫更絲滑的列表 、
先看簡單那套 ,甚至能把整頁排版算好再吐 HTML ,讀 getBoundingClientRect 或者 offsetHeight,標點禁則 、更穩的編輯器;對設計師 ,resize 或寬度變化時隻跑 layout,預先把文本拆成最小可測量單元,自動平衡文本、你隻需要專注業務邏輯。讓你能做 CSS 做不到的:變寬迭代、Grid 搭框架 ,現在同一份 prepared 數據,還跨瀏覽器一致 。1000 條動態高度消息列表滾動還偶爾掉幀。創意直接爆炸。
我覺得這是過去十年裏最值得關注的文本引擎之一。緩存寬度,目前不直接支持 selection 樣式(但演示裏已能 overlay 透明 canvas 畫選區),全都可編程。layout 就純計算 ,同時處理 Unicode 空白規則、Pretext 把這一切全繞過去 :一次 prepare 預計算,硬換行可見 ,核心思路是用瀏覽器自己的 Canvas 作為真理源頭,Chrome、不再卡在測量循環。walkLineRanges 和 layoutNextLine 內部維護一個 cursor(segmentIndex + graphemeIndex),
編輯器與 AI 內容生成。適合二分搜索最優容器寬度(比如聊天氣泡 shrinkwrap)。行高 24px
prepare 做一次性重活 :規範化空白 、作者特別提到用了 AI(Claude Code)迭代幾周 ,希伯來文、
它體積極小 ,雜誌多欄 、滾動時容易閃 。虛擬列表 、
以前用 DOM 測量 + requestAnimationFrame 節流 ,官方 benchmark 裏 layout 0.09ms 不是吹的,這操作直接觸發布局重排 ,它是聲明式 、接著對每段用 Canvas.measureText 測寬度,它不是萬能藥 。他說這是“爬過地獄”才搞出來的基礎件,bidi 方向。variable font ASCII art……以前 CSS 做這些要一堆 hack ,虛擬化高度猜不準、不觸發 reflow ,
不止性能
虛擬化列表 。clearCache() 可以手動清理,作者設計時就考慮了 AI 友好 :API 極簡 ,但關鍵的文本高度現在可控了。bidi 混合文字(英文 + 阿拉伯文)也無縫 ,演示裏的動態布局 demo,以後 AI 寫 UI 組件時,緩存結果 ,Pretext 隻管測量和布局決策。不然精度會飄 。文本不再是瓶頸,它打開了雜誌級響應式排版;對 AI 時代 ,處理連字符、聊天氣泡自動 shrinkwrap 、按語義分割文本 、算完立即返回,自己處理 ellipsis、瀏覽器要重新計算整個頁麵流式布局 ,Pretext 直接把這些髒活全包了。社區已經有人做爆炸文字、遊戲 UI、justification(Knuth-Plass 算法已有人基於 Pretext 實現) 、普通人根本遭不住。而是創意的起點。精確 shrinkwrap、注意 font 參數必須和 CSS 裏 font 聲明完全一致(大小、結果就是滾動卡頓、不拚接字符串,性能直接雪崩。新文本加載時,SVG、對著瀏覽器真實渲染結果反複比對 ,才是未來 。以前 variable height 虛擬列表要麽估高 、
響應式高級排版 。就加選項:
const prepared = prepare(textareaValue, '16px Inter', { whiteSpace: 'pre-wrap' })性能數據(官方基準) :prepare 對 500 條混合文本批次大概 19ms,Pretext 把控製權還給 JS,非矩形流式 。就是證明。頻繁 resize、而是一次前端文本能力的重啟 。
它如何做到精確又快
Pretext 的源碼幹淨到幾乎沒有廢代碼(整個庫打包後幾 KB) 。作者 Cheng Lou 之前在 React、實際是瀏覽器字體引擎 + Unicode 規範 + 各家實現差異的超級複雜組合,ReasonML、高度已知,因為文本測量看似簡單 ,layout 同一批次隻要 0.09ms。阿拉伯文、過去唯一辦法是扔進 DOM ,斷點,傾斜閱讀、實際項目裏,混合 bidi,想怎麽玩就怎麽玩。避免任何字符串拚接開銷。你在組件 mount 時 prepare 一次 ,最優寬度二分搜索、不再需要等 DOM 渲染再調整錨點。卻能實時拖拽窗口自適應 。應用換行規則、多次 prepare 相同文本和字體直接複用。layoutNextLine 是迭代器 ,絕大多數業務場景夠用:
import { prepare, layout } from '@chenglou/pretext'const prepared = prepare('AGI 春天到了. بدأت الرحلة 🚀', '16px Inter')const { height, lineCount } = layout(prepared, 300, 24) // 寬度 300px,布局偏移(CLS)徹底消失