這週的前端圈,可以說是被一個叫 Pretext 的專案徹底洗版了。
短短幾天,GitHub 狂攬 41K+ Stars ⭐⭐⭐。
很多剛入行的朋友看完官方那個極簡的 Readme 可能一頭霧水:不就是一個算文本長寬高的 JS 函式庫嗎?為什麼能火成這樣?CSS 的 word-wrap 和 flex 難道不夠用嗎?
但如果是被各種複雜表格、虛擬列表、Canvas 繪製折磨過的老兵,看到 Pretext 的那一刻,絕對會有一種激動。
因為這個函式庫,極其優雅地處理了前端效能優化裡最討厭、最頑固的問題——強制同步佈局(Forced Synchronous Layout)導致的重排(Reflow)。
今天,我們不念官方文件,結合我這幾年的修坑血淚史,聊聊這個 41K Star 的怪物到底解決了什麼世界級痛點,以及我們在真實業務裡該怎麼用它。
前端開發有個大難題:一段動態文字渲染出來到底有多高?
設想一個極度真實的業務場景:你在做一個擁有十萬筆資料的 虛擬滾動列表(Virtual List)。為了讓列表順滑,你只能渲染視口內的那 20 條資料。問題是,每條資料裡的使用者評論長度不固定。有的人只發一句 哈哈😁,有的人發了 800 字的長文。在渲染之前,你必須提前知道每一行的高度,才能計算整個虛擬列表的滾動條位置和絕對定位的 top 值。
在 Pretext 出現之前,我們通常怎麼做?用的往往是最原始、極其粗暴的 離屏 DOM 測量法(Offscreen Measurement):
// 極其陰鬱的傳統測量法:DOM 測算
function measureTextHeightOldWay(text, width, fontSize) {
// 1. 建立一個隱藏的 div
const hiddenDiv = document.createElement('div');
hiddenDiv.style.visibility = 'hidden';
hiddenDiv.style.position = 'absolute';
hiddenDiv.style.width = `${width}px`;
hiddenDiv.style.fontSize = `${fontSize}px`;
hiddenDiv.innerText = text;
// 2. 強行塞入 DOM 樹
document.body.appendChild(hiddenDiv);
// 3. 讀取高度(災難的開始!!!)
const height = hiddenDiv.offsetHeight; // 或者 getBoundingClientRect()
// 4. 銷毀 DOM
document.body.removeChild(hiddenDiv);
return height;
}
程式看起來沒問題?但如果在初始化時,你在一個迴圈裡把這段程式跑了 1000 次,你的頁面會當場卡死白屏!
為什麼?因為瀏覽器底層是一個極度慵懶的系統。你操作 DOM 節點,它通常會先累積變更,等到這一幀結束再一次性繪製。但當你呼叫了 offsetHeight 或 getBoundingClientRect 時,瀏覽器為了給你一個最精確的值,會被迫打斷所有的優化,立即在主執行緒裡重新計算整個頁面的佈局(Reflow)。
你在迴圈裡呼叫 1000 次,瀏覽器就被迫重排 1000 次。這種 布局抖動(Layout Thrashing) 是前端效能的頭號殺手。
而 Pretext 的核心賣點,就寫在它的第一句介紹裡:純 JavaScript/TypeScript 函式庫,避免對 DOM 進行測量。

它完全摒棄了把元素塞進 DOM 裡量一下的笨方法。你要算這段文字佔據多少像素?好,你告訴我字型、字級、容器寬度,我直接在 JS 記憶體裡,透過底層的文字排版演算法,硬生生給你算出來!
我們直接看程式碼,看看接入 Pretext 之後,世界變得多清爽:
// 使用 Pretext
import { measureText } from 'pretext';
function measureTextHeightNewWay(text, containerWidth) {
// 沒有任何 DOM 操作!直接傳入參數計算
const metrics = measureText(text, {
fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto',
fontSize: 14,
lineHeight: 1.5,
maxWidth: containerWidth,
// 甚至支援複雜的換行策略
wordBreak: 'break-word',
});
// 直接拿到精準的寬高和行數!
return metrics.height;
}
對比一下,這帶來了什麼工程級別的質變?
Pretext vs getBoundingClientRect 性能對比

更多好玩的 demo 👉:https://chenglou.me/pretext/

其實純 JS 估算文字這個想法,很多前端老手都想過。為什麼直到 2026 年,才被 Pretext 徹底做成一個 40K+ Star 的殺手級專案?
因為文字排版(Text Layout)是個深不見底的黑洞。
你以為算個寬度就是「字元數 × 字體寬度」?太天真了。你需要考慮英文單詞的斷詞(換行不能把單詞拆開)、需要考慮阿拉伯語的由右至左(RTL)、需要考慮中文的標點避頭尾規則、更別提那些五花八門的 Emoji(有的 Emoji 占好幾個位元組,但在螢幕上只是單一字元)。
更變態的是,不同瀏覽器(Chrome / Safari)底層的字型引擎(像 HarfBuzz 等)渲染規則都有細微差異。
Pretext 的作者 chenglou(曾參與 React Core,寫過 ReasonML 的大神👍👍👍)用了一種既聰明又符合現在 AI 時代的方法:將瀏覽器自身的字型引擎作為基準進行迭代對齊。

它沒有傻傻地重寫一套從零開始的渲染引擎,而是找到了一套能與主流瀏覽器高度擬合的純數學計算邏輯。精度極高,且非常輕量。
這不是在造輪子,這是在用極客思維給現有的前端標準打補丁。
雖然我把它吹爆了,但作為一個老油條,我必須負責任地告訴你:不要一時衝動,把專案裡所有普通的 CSS 排版都換成它。CSS 引擎依然是渲染標準流程最穩定、最簡單的方案。
Pretext 屬於極端場景的工具。遇到以下三種情況,直接掏出它:
fillText 非常原始,根本不支援自動換行。以前在 Canvas 裡畫多行文字簡直是噩夢,現在可以用 Pretext 算好每一行的位置,然後精確繪製。這兩年,前端圈充滿了大模型、AI 生成程式碼的焦慮,似乎一切不加個 AI 前綴就不夠前沿。
但看到 Pretext 這種純粹為了解決計算機圖學底層痛點、逐行逐行扣效能、追求極致優雅的開源專案,短短幾天收穫 40K+ Star,我心裡其實挺欣慰的。
它證明了一件事:在花裡胡哨的概念之外,這個世界上永遠有那些扎根在工程最深處、被真實痛點折磨的開發者。
真正高階的前端工程能力,不是你接了多少個最新的大模型 API,而是當系統出現肉眼可見的卡頓時,精準指出那句藏在萬行程式碼裡的 offsetHeight,然後用純粹的數學與演算法,把頁面效能拉升兩個數量級。
週末了,別只顧著看熱鬧,去把 Pretext 拉下來,在本地建個 Canvas 或虛擬列表的 Demo 跑一跑。
那種看著耗時從 300 毫秒斷崖式下降到 2 毫秒的爽感,才是寫程式真正的樂趣😁。