MicroLighter:用 CSS Custom Highlight API 干掉 span 的语法高亮

前端
JavaScript
CSS
开源
性能
2026/9/29
·

阅读时间: 大约 8 分钟

MicroLighter:用 CSS Custom Highlight API 干掉 span 的语法高亮

MicroLighter 首页:被划掉的 span 与 ::highlight(),gzip 后 2.09KB

语法高亮是个被 Prism、highlight.js、Shiki 占领多年的成熟领域,看起来早该没什么可创新的了。但 MicroLighter 找到了一个新角度:它不换解析器,而是换上色方式——利用浏览器较新的 CSS Custom Highlight API,把”给每个词包一层 span”换成”在文档里建高亮范围、用 CSS 伪元素上色”。作者 d4vatron5000 用一句口号概括:“No more spans!”。本文核对它的机制、实际体积与兼容边界。

一、背景:传统高亮为什么慢

传统语法高亮的做法是:解析代码 → 给每个 token(关键字、字符串、注释……)包一层带 token class 的行内标签 → 再用 CSS 给这些 class 上色。问题在于,一个代码块动辄几百上千个 token,就意味着几百上千个额外 DOM 节点。在文档里嵌大量代码示例的页面(文档站、博客),这些 span 会推高渲染开销、内存占用,也让 DOM 树变得臃肿。

MicroLighter 的思路是把”标记”和”样式”解耦:用浏览器的 Highlight API 在文本范围内建立高亮(Highlight 对象 + CSS Custom Highlight 注册),然后用 ::highlight() 伪元素写 CSS 上色。DOM 里还是原来那一个 <pre><code>,不插入任何 span。

二、它是什么

官方首页亮出的核心数字:

  • 2.09 KB(gzip) 核心体积;
  • 零依赖;
  • 语法按语言模块懒加载(页面用到哪种语言才加载对应的 css.js / html.js / ruby.js);
  • 采用 VS Code 同款的 TextMate grammar 格式;
  • 内置 12 套主题(GitHub、Dracula、Monokai、Night Owl、Solarized、Tokyo Night、Gruvbox、Cobalt2、Vesper、Min、Flexoki、VS Code Plus)。

用法极简:

import { highlightAll } from "microlighter";
import "microlighter/themes/github.css";
await highlightAll();

配合标准的 <pre><code class="language-javascript"> 标记即可。想要自动运行就引入压缩版 auto-runner;想要复制按钮和行号,就引入自定义元素包,用 <micro-lighter language="javascript" controls="copy" line-numbers> 包一层。

主题化也很”CSS for humans”:直接用伪元素写变量:

::highlight(keyword) { color: var(--syntax-keyword); }

三、语言覆盖

官方把支持的语法分了四类,合计 40 多种,每种都是独立模块、按需加载:

  • Web:HTML、CSS、SCSS、JavaScript、TypeScript、TSX、Astro、Svelte、Vue、HEEx;
  • Systems:C、C++、Rust、Go、Assembly;
  • Application:Java、C#、Kotlin、Swift、Objective-C、Dart、PHP、Elixir;
  • Scripting:Python、Ruby、Bash、Perl、PowerShell、Lua、R;
  • Data/Config/Docs:JSON、YAML、TOML、SQL、Markdown、GraphQL、Dockerfile、Git diff、INI、nginx。

值得注意的是它连 Git diff、TOML、nginx 配置这类”不是编程语言但需要 TextMate scoping”的格式也覆盖了。

四、口径与局限

  1. 浏览器兼容是硬门槛:整个方案依赖 CSS Custom Highlight API。该 API 在 Chromium 系(Chrome/Edge)与较新版本的 Safari 上支持,老浏览器、需要兼容旧环境的场景直接用不了。这是它和 Prism/highlight.js 最大的工程差异——后者靠 span 能跑在几乎任何浏览器上。周报点评也指出:老浏览器或要兼容 IE 的场景,这条路走不通。
  2. 体积小是”核心”体积:2.09KB 指的是运行时核心;真正的语法 grammar 是按需懒加载的,首次高亮某语言时仍要拉取对应 grammar 文件。不要把 2.09KB 理解成”整站高亮总共才 2KB”。
  3. 生态年轻:它是个人项目,主题和语言覆盖在快速扩充中,但遇到冷门语言可能要自己写 TextMate grammar;生产级长期维护性有待观察。
  4. 调试方式变了:不再有 .token 类可查,样式挂在 ::highlight() 上,习惯了在 DevTools 里翻 span class 调试高亮的人需要换思路。

五、适用与不适用

适合:现代浏览器为主的文档站/博客,尤其是页面里嵌大量代码块、在意 DOM 节点数与内存的项目;想要小体积、TextMate grammar、主题化干净的开发者。

不适合:需要兼容老浏览器/旧 Safari 的站点;依赖大量自定义 .token 样式、已有 Prism/highlight.js 全套主题的存量项目(迁移有成本)。

六、它意味着什么

MicroLighter 的价值不在”又一个高亮库”,而在于它示范了如何用浏览器新原生能力拆掉一个长期被 DOM 模式固化的需求。语法高亮过去十年都默认”要上色就得包 span”,而 Custom Highlight API 提供了一条不增加 DOM 节点的新路——对代码密集型页面,这意味着渲染开销和内存随代码块数量线性下降的曲线被压平了。它现在受限于浏览器覆盖率,但随着 Custom Highlight API 逐渐普及,“零 span 高亮”很可能从小众技巧变成文档站的默认做法。对前端而言,这又是一个”等浏览器能力到位后,老问题有了更便宜解法”的典型案例。

参考来源