Skip to content

perf(image-utils): byte-compare fast path for toMatchPdfSnapshot - #9384

Draft
eventualbuddha wants to merge 11 commits into
mainfrom
perf/pdf-snapshot-fast-path
Draft

eventualbuddha wants to merge 11 commits into
mainfrom
perf/pdf-snapshot-fast-path

Conversation

@eventualbuddha

Copy link
Copy Markdown
Contributor

Stores a normalized PDF beside each snapshot and only rasterizes when the bytes differ, warning when that slow path runs. Makes pollbook and hmpb PDF output deterministic so the fast path actually hits, moves normalizePdf/concatenatePdfs into image-utils, and keeps one getPdfPageCount.

Stacked on #9383.

TODO: edit before review.

🤖 Generated with Claude Code

@eventualbuddha
eventualbuddha added this pull request to stack #9385 September 16, 2026 23:49
@eventualbuddha
eventualbuddha force-pushed the perf/pdf-snapshot-fast-path branch 2 times, most recently from b648658 to 6173c3c Compare September 17, 2026 00:16
Base automatically changed from perf/explicit-monospace-font to main September 17, 2026 14:40
eventualbuddha and others added 11 commits September 17, 2026 07:41
Lets `@votingworks/image-utils` normalize PDFs itself, since hmpb already depends on it; the only content changes are `assertDefined` guards for image-utils' stricter index checks and a local test fixture.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…-reference streams

Renumbering objects and rebuilding the xref table assumed a classic table, which broke pdf-lib's default output (`Invalid Root reference`), so such PDFs now only get same-length substitutions and hex `/ID` pairs keep their surrounding whitespace.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Wraps the input without copying and declares the `Buffer` it already returned, so callers need no conversions on either side.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Stores the normalized PDF beside the PNG snapshots and passes immediately when a later render matches it byte for byte, falling back to the page-by-page image comparison otherwise; the PDF is written only when missing or when updating snapshots.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Generated by running every suite that uses the matcher, so those suites now take the byte-compare fast path.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Flags a stored PDF that matched visually but not byte for byte, or one missing in CI, so nondeterministic output and renderer changes are visible in the test log rather than only as slower tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…with pollbook

Pollbook's own copy used pdf-lib's default `save()`, whose compressed object streams hide fresh timestamps and defeat `normalizePdf`, so the backup checklist PDFs never matched byte for byte; the shared version is deterministic and lets pollbook drop its direct `pdf-lib` dependency.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Saves without object streams and runs `normalizePdf`, matching the package's other pdf-lib output, so the print test deck PDFs compare byte for byte.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The image-utils version now leaves its input intact, so printing's pdf-lib duplicate and the defensive copies at call sites go away.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ime`

Every other receipt already uses it, so tests can pin the printed time and no longer need a 5% image tolerance that could also hide a wrong count.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Importing `@votingworks/image-utils/pdf` no longer loads `@napi-rs/canvas`, so browser bundles such as the hmpb preview can use `normalizePdf` and `concatenatePdfs`; `pdfToImages` loads the addon lazily, the barrel file no longer re-exports PDF code, and the dev dock inserts the first mock PDI sheet before returning so its status is settled.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@eventualbuddha
eventualbuddha force-pushed the perf/pdf-snapshot-fast-path branch from 6173c3c to c154642 Compare September 17, 2026 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant