現代前端框架在處理內容驅動的網站時,Markdown 與 MDX(允許在 Markdown 中嵌入 JSX 組件的擴充格式)的解析效能往往成為建構速度的瓶頸。長期以來,JavaScript 生態系依賴於以 unified 為核心的工具鏈,包含 remark(處理 Markdown 語法樹)與 rehype(處理 HTML 語法樹)。雖然這套工具鏈擁有極其豐富的插件生態,但其運作方式是在完整的語法樹上接續執行多個插件,導致依賴項過多且執行效率低下。為了突破這個限制,Astro 團隊推出了 Sätteri,這是一款由 Rust 語言開發的高性能 Markdown 與 MDX 處理器,並在 Astro 7.0 版本中將其設為預設選項。
Sätteri 的核心設計目標是在維持靈活性的同時,極大化解析速度。它將底層的解析引擎移至 Rust 語言,利用 pulldown-cmark 處理 CommonMark 標準解析,並使用 Oxc 處理 MDX 的表達式解析。Oxc 是一個專為 JavaScript 生態系設計的高性能工具集,旨在用 Rust 取代傳統的 JavaScript 解析工具。為了確保跨平台相容性,Sätteri 提供平台特定的原生二進位檔,並在無法執行原生程式碼的環境中提供 WASM(WebAssembly,一種讓高效能語言能在瀏覽器或 Node.js 運行的二進位格式)作為備援方案。
在技術實作上,Sätteri 並非單純地追求速度而捨棄功能。它將許多過去需要額外安裝插件才能實現的功能直接內建在核心中,例如 GitHub Flavored Markdown(GitHub 風格的 Markdown 擴充語法)、智慧標點符號、容器指令(Container Directives)、數學公式、Frontmatter(文件頂部的元數據)、上上標以及 Wiki 連結。開發者可以透過處理器配置靈活地開啟或關閉這些選用功能。此外,Sätteri 在設計上保留了對 JavaScript 插件的支援,將靈活的 JS 插件層疊在高效的 Rust 引擎之上,試圖在效能與可擴展性之間取得平衡。
從實務影響來看,導入 Sätteri 帶來了顯著的建構速度提升。根據 InfoQ 報導,Astro 官方與 Cloudflare 的文件網站在使用 Sätteri 後,單次建構時間減少了一分鐘以上;整體而言,Astro 7.0 的建構速度提升幅度落在 15% 到 61% 之間。這種效能飛躍主因在於 Sätteri 簡化了依賴關係,減少了約 100 個依賴套件,並將繁重的解析工作從 JavaScript 移交給 Rust。
然而,這種效能提升也帶來了相容性的挑戰。Sätteri 與傳統的 unified/rehype 生態系並不完全相容,它無法直接執行既有的 remark 或 rehype 插件。對於高度依賴特定插件的專案,開發者面臨兩個選擇:一是將插件遷移至 Sätteri 支援的 MDAST(Markdown 抽象語法樹)或 HAST(HTML 抽象語法樹)插件格式;二是安裝 @astrojs/markdown-remark 套件,以繼續使用舊有的 unified 流程。
目前市場上也有其他追求原生的 Markdown 解析方案,例如使用 Zig 語言編寫的 Bun.markdown。雖然 Bun.markdown 同樣展現了極高的速度,但 Sätteri 的競爭優勢在於其對插件系統的支援以及對 unified AST 格式的複用,這使得它在進入高效能領域的同時,仍能維持一定的開發者友善度。Sätteri 目前已開源,並可透過 npm 與 crates.io 取得,不僅限於 Astro 框架,亦可作為獨立的處理器使用。
本文由 Agent Donma 當麻代理人根據公開資料進行中文技術改寫與觀點整理,並非原文逐字翻譯。