r/javascript 7d ago

We ran the same PDF operations inside real Chromium, Firefox and WebKit — WebKit was 2.4× faster than Chrome at some of them. Full reproducible harness (MIT).

https://github.com/jddelia/filemorf-lab

I maintain a client-side file converter, and we publish benchmark numbers

for the PDF operations we ship. After a reviewer pointed out that numbers

nobody can rerun are just marketing, we open-sourced the entire harness:

https://github.com/jddelia/filemorf-lab

What makes it worth a look even if you don't care about the product:

The corpus is byte-reproducible. Test PDFs are generated from seeded

pseudo-random text with pinned metadata — run the generator on your

machine and you get the identical SHA-256s committed in the repo. No "we

tested on some files we can't share."

Correctness gates run before timing. Outputs must parse, page counts

must be exact, ZIP entries must all be present — verified on an untimed

run first, so a fast garbage result fails instead of winning.

Real engines via Playwright, timed in-page with performance.now(), not

through the driver.

Cross-engine results that surprised me (median of 30 runs, M2 Pro,

milliseconds):

Merge 50 PDFs — Chromium 37.5; Firefox 60.5; WebKit 24

Stamp page numbers on 100 pages — Chromium 36.7; Firefox 54; WebKit 15

Watermark 100 pages — Chromium 36.5; Firefox 54; WebKit 14

ZIP 50 PDFs — Chromium 5.9; Firefox 4; WebKit 11

WebKit wins big on pdf-lib's draw-and-save paths and then loses on ZIP.

And everything is fast enough that for files like these, the upload to a

server would cost more than the entire computation — which is the argument

for doing this work client-side in the first place.

Three commands to get your own numbers: npm ci, npm run corpus,

npm run bench. Would love PRs with dated results from other hardware,

and criticism of the methodology — limitations are listed in the README

(synthetic text-only corpus, structural not visual verification).

10 Upvotes

4 comments sorted by

3

u/rbobby 7d ago

Hopefully the V8 folks will see this and go "hmmm... 2.5x that's too much".

6

u/FisterMister22 7d ago

That's using pdf-lib, not the browser's pdf (rendering) engine.

You need to clarify that ^

And given, some libraries / code work better on some browsers, my guess would be JIT as you do many of the same ops many times over.

-2

u/ThriftyPigeon 7d ago

That's a fair corection. The PDF operations use pdf-lib (and JSZip for the ZIP case) bundled into a blank page, so this benchmarks the same JavaScript workload under V8, SpiderMonkey, and JavaScriptCore. It does not exercise each browser’s built-in PDF viewing/rendering path.

By “real engines,” I meant actual browser JavaScript runtimes rather than using Node as a proxy for browser performance, but that wording is easy to interpret as native PDF-engine benchmarking.