Skip to content

Pixelmatch Performance

When to Use

Read this when evaluating whether pixelmatch is fast enough for your suite size, or when CI diff throughput is a bottleneck.

Decision

Situation Action
Suite < 500 screenshots per run Stay on pixelmatch — latency is invisible
Suite 500–2000 screenshots Pixelmatch acceptable; profile to confirm
Suite > 2000 screenshots Consider odiff
4K+ captures odiff pays back even at small suite sizes
Playwright inner loop Keep pixelmatch — it's tied to the auto-retry stability check
Post-process diff in CI odiff is fine — drop-in via odiff-bin

Pattern: pixelmatch for the inner loop, odiff for post-process

Don't replace pixelmatch inside Playwright's toHaveScreenshot() — its auto-retry stability mechanism is tied to it. If suite size warrants, run odiff after the test run on the same PNGs to catch finer-grained diffs faster.

Benchmarks

Per odiff's published Hyperfine benchmarks:

Image pixelmatch odiff Speedup
Cypress.io full-page diff 7.712 s 1.168 s ~6.67×
8K image diff 10.614 s 1.951 s ~5.5×

Pixelmatch is pure single-threaded JS — no SIMD, no native bindings.

Common Mistakes

  • Wrong: Replacing pixelmatch in Playwright's internals — breaks the auto-retry stability mechanism
  • Wrong: Profiling pixelmatch on tiny test images — performance only matters at scale
  • Wrong: Switching to odiff before identifying the bottleneck — capture often dominates over diff time; profile first

See Also