DocRaptor 是个不错的产品。它把 Prince——HTML 转 PDF 的金标准引擎——包装成托管 REST API,配上重试、异步任务、还算好的文档。它存在十多年,对很多团队来说是「我不想自己跑 Prince」的明显选择。
我们是另一种产品形态。gPdf 根本不接受 HTML——它接受结构化 JSON,并在 Cloudflare 边缘直接生成 PDF。100K 页/月的标价差距是 $5/月(gPdf Basic) vs $89/月(DocRaptor Basic)——大约 18×。这个差距不是首发优惠,是结构性的。本文讲为什么架构会产生这个价格,以及两种工具各自适合哪里。
两种架构并排看
| 层 | DocRaptor (HTML → PDF) | gPdf (JSON → PDF) |
|---|---|---|
| 输入 | HTML + CSS(带 Prince 的 paged-media 扩展) | DocumentRequest JSON |
| 渲染器 | Prince(编译型 C++ 引擎) | 自研 Rust 引擎,编译为 WebAssembly |
| 部署 | DocRaptor 中心化服务器(美国机房) | Cloudflare Workers,每个 CF colo(300+ 城市) |
| 冷启动 | 服务端 worker pool | V8 isolate 启动,个位数毫秒 |
| 单次渲染算力 | HTML/CSS 布局过程 + Prince 分页 | 直接排版,无布局解读过程 |
| 单次 p50 | ~250–800 ms wall-clock(含网络) | ~3–8 ms(含网络) |
| 输出确定性 | 高(Prince 成熟) | 字节一致(同 JSON → 同字节) |
如果你把这两列读成「通用 HTML 打印机」vs「专为文档构建的生成器」,你已经理解了架构决策。其他一切(延迟、成本、甚至功能清单)都是这一选择的结果。
Prince 税
Prince 是好的。它也在做大多数发票/收据/运单工作流不需要的事:为用户可能扔过来的任意 HTML 实现 CSS Paged Media——分页规则、running header、脚注、交叉引用、生成内容框。
这种通用性有运行时成本。要分页任意 HTML 文档,引擎必须:
- 解析并验证 HTML
- 解析并解算 CSS 级联(可能含 Prince 自己的扩展)
- 构建渲染树
- 跑多遍布局(尤其是跨页表格、平衡列)
- 跨页解算交叉引用
- 输出 PDF 对象
大多数过程是接受 HTML 作为输入的代价。如果你的输入本来就是结构化数据(几乎总是——你的发票在被包成 HTML 之前就以 JSON 对象形式存在),你每次生成 PDF 都在为这些过程付算力和延迟,而它们并不会提升最终输出。
gPdf 完全跳过布局解读这一步。JSON DocumentRequest 已经用结构化方式指定页面布局——{ pages: [{ size, elements: [...] }] }。渲染器排字、确定性分页、输出 PDF。没有 CSS 级联可解算、没有浮动布局可计算、没有交叉引用解算过程。
结果:DocRaptor 上 ~300 ms 的同一张单页发票,在 gPdf 上 ~3 ms。我们快不是因为写了一个更快的 Prince——而是因为我们不做 Prince 大部分要做的事。
“便宜得不真实” 是真实的采购异议
直接讲清楚,因为每次 B2B 销售都会被问到。
“$5/月,10 万次渲染。DocRaptor 是 $89。Anvil 是 $0.10/PDF(同量是 $10,000)。你们到底有什么问题?”
我们能这么收费的三个诚实原因:
1. 我们不跑浏览器
DocRaptor 把 Prince 基础设施摊销到客户身上。gPdf 摊销的是一个 Cloudflare Worker——Workers Bundled 大约 $0.50/百万次请求。JSON 形状的输入,我们的渲染器单次大约 1.5 ms CPU。叠 50% 毛利还在「美分级别每千次」区间。算术就是价格。
2. 我们不跑控制面
没有异步任务、没有回调、没有重试队列、没有文档存储、没有预览链接 UI、没有多租户数据库。每次渲染都是单次往返到无状态函数再返回。这去掉了大多数「PDF API」公司需要承担的运维面——也就是让他们价格变高的那部分。
3. 这模型自动筛掉我们会亏钱的工作负载
如果你的文档真的需要 HTML 转 PDF(60 页法律合同、复杂 CSS Grid 报告),你第一小时就会发现 JSON 模型不适合,然后转向 DocRaptor。我们不需要为这些工作负载防御性定价,因为它们会自然流向更合适的工具。我们只需要为「结构化数据→文档」这类长尾但边界清晰的工作负载定价——单次渲染成本本来就极小。
合起来:$5/100K 不是赔本赚吆喝,而是真实的成本+毛利。我们能长期保持这个价格,因为底层算力就是这么便宜,只要不把浏览器放进生成链路。
DocRaptor 是正确选择的场景
我们尽量不写自利对比。DocRaptor 真正胜出的几种情况:
- 你的输入是你不完全控制的 HTML。 用户生成的报告、第三方模板、CMS 渲染的 Markdown 转 HTML。你不想为任意输入写 JSON 映射器。
- 你需要 Prince 支持的 CSS Paged Media 特性。 每章 running header/footer、复杂脚注 reflow、命名页选择器、生成的目录、索引。gPdf 对常见子集有结构化对等品,但如果你住在
@page :left选择器里,Prince 是你的朋友。 - 你的内容团队写 HTML/CSS,不写 JSON。 别强迫非工程团队用 JSON 撰写工作流。他们会恨你。
- 异步 + 回调 + 文档存储即服务。 DocRaptor 存生成的 PDF 并给你签名 URL 用于交付。gPdf 严格无状态——你的代码自己存结果。
如果你在以上任一桶里,留在 DocRaptor。 它是对的工具。
gPdf 是正确选择的场景
镜像反过来:
- 你的输入已经是结构化数据(数据库行、JSON API 载荷、队列消息)。
- 延迟重要——交互式结账流、实时面单打印、按需对账单生成。
- 你在乎字节一致可复现用于测试/审计/电子发票留存。
- 在几千次/月以上的任何量级你都对成本敏感。
- 你需要条码(GS1-128、QR、Data Matrix、PDF417、Aztec、MaxiCode)做亚毫米精度——Prince 技术上支持 SVG 条码,但通过 HTML/CSS 做到 0.1 mm 整体长度精度并不简单。
- 你需要 PDF/A(1b/2b/3b/4)或 Factur-X / ZUGFeRD 附件做合规。
- 你宁愿不跑「JSON → HTML → PDF」管线——既然可以跑「JSON → PDF」管线。
迁移是机械活,不是战略活
常见的担心:「换工具意味着重写所有模板。」通常不是。大多数 HTML 转 PDF 模板是 20% 布局(一次性变成 JSON 结构)+ 80% 数据插值(无论渲染器接什么都一样)。
实操路径:
- 选一种文档类型迁移。从最大量的开始——节省最大、爆炸半径最小。
- 拿 HTML 模板的数据接口(它插值的变量),写个小
mapToDocumentRequest(data)函数。 - 在在线体验中迭代,直到输出符合预期。
- 生产 A/B:路由 5% 流量到 gPdf 跑两周。Diff PDF。比账单。
- 按数据决定,不按感觉。
我们见过团队一个 sprint 内做完,下个月把 90% PDF 账单收进口袋。也见过团队意识到自己工作负载其实是 HTML 转 PDF 场景,留在 DocRaptor——带着我们的祝福。
一句话
| DocRaptor | gPdf | |
|---|---|---|
| 擅长 | 任意内容的 HTML → PDF | 结构化文档的 JSON → PDF |
| 100K 页/月价 | $89 | $5 |
| p50 渲染 | 250–800 ms | 3–8 ms |
| 边缘部署 | ❌ 中心化 | ✅ 300+ Cloudflare colo |
| 异步 + 存储 | ✅ 含 | ❌ 设计上无状态 |
| PDF/A + Factur-X | ⚠️ 通过 Prince 扩展 | ✅ 内置 |
如果你的文档本质上是结构化数据,只是套了一层 HTML,你就在为一个不该存在的转换环节付费。来在线体验试试——用 JSON 描述你的一张发票,在浏览器里 5 ms 内生成 PDF,看看差距是否符合你的判断。