写过前端的都给客户做过 PDF 导出功能——导出慢、页数多就崩溃、生成的 PDF 文字是图片不可复制。今天 dompdf.js 用 Rust 把这件事从根上变了:2 秒生成 500 页,文字是真正的矢量对象,代码体积还只有原来的 35%
写过前端的都给客户做过 PDF 导出功能——导出慢、页数多就崩溃、生成的 PDF 文字是图片不可复制。今天 dompdf.js 用 Rust 把这件事从根上变了:2 秒生成 500 页,文字是真正的矢量对象,代码体积还只有原来的 35%。
做前端 PDF 导出,主流方案一直是 html2canvas + jsPDF:把 DOM 截图贴进 Canvas,再把 Canvas 转成图片塞进 PDF。这条路有解不开的死循环——Canvas 有尺寸限制,超过几千像素就可能崩溃;长文档需要手写分页逻辑,代码臃肿,分页错乱是高频 bug;最关键的是,导出来的是图片不是文字,文字选不了、复制不了、搜索不了。
这套方案在短文档场景勉强能用,但金融报表、合同、证书这类正式文档,它就不合格了。
dompdf.js v2 换了一条路
dompdf.js v2 重写了核心渲染引擎,架构从截图变成了直接解析 DOM:
DOM → DOM Snapshot → Web Worker → Rust + WASM → PDF
不再截图了。直接解析 DOM 结构和页面样式,原生生成 PDF 字节流。Rust 负责分页计算、字体子集化、压缩和 PDF 写入;TypeScript 负责采集 DOM、收集样式、处理 Worker 通信;全程跑在浏览器里,不需要后端。
实测数据:100 页秒出,500 页约 2 秒,极限 10000+ 页也能跑,文件体积只有传统方案的十分之一。文字是真正的矢量对象——可选中、可复制、可搜索,支持中文字体和 Unicode。
分页解决得干净
PDF 分页有两个经典坑:一是把一行字从中间劈开,二是表格行或图片被切成两半分别卡在两页。
v2 的做法是把文字在快照阶段就切成”行盒”作为最小分页单位,分页边界只落在行与行之间,不会劈开一行字。卡片、表格、图片等整块内容一旦跨越页边界,会整体下移到下一页,不会出现”上半张图在这页、下半张在下页”的情况。这是传统”整页截图硬切”方案做不到的。
AI 测试闭环是工程亮点
v2 内置了一套 5 级 PDF 回归测试框架,并以 MCP Server 对外暴露——AI 编程工具可以直接调用它:自动跑像素对比、文本对比 → 定位渲染 bug 根因 → 修改 Rust 源码 → 重跑验证。这把”生成-检测-修复”串成了一个闭环。
怎么用
npm install dompdf.js
import { render } from 'dompdf.js';
const blob = await render(document.getElementById('invoice'), {
format: 'a4',
});
// 返回标准 Blob,可直接下载或上传
迁移建议
v1 项目迁移到 v2 需要注意:不再依赖 jsPDF,字体配置方式有变化,API 以 render(dom, options) 为主。官方提供了迁移文档,已有项目建议先用 1-2 个简单页面试跑,确认分页效果后再全量迁移。
PDF 导出长期是前端痛点,dompdf.js v2 用 Rust 把性能问题、矢量质量问题、AI 测试闭环三个问题一次解决。
评论区
登录后可评论。