Skip to content

Reduce binary size: Zopfli codegen compression + percentage byte-plane#691

Merged
Boshen merged 1 commit into
mainfrom
zopfli-compression
May 29, 2026
Merged

Reduce binary size: Zopfli codegen compression + percentage byte-plane#691
Boshen merged 1 commit into
mainfrom
zopfli-compression

Conversation

@Boshen

@Boshen Boshen commented May 29, 2026

Copy link
Copy Markdown
Member

Two lossless binary-size reductions. The musl inspect example goes 778,528 → 770,944 B (−7,584, −0.97%); macOS is unchanged (segment quantization), so the README's "621K" stays accurate. All tests and the JS-equivalence proptests pass.

Zopfli for the codegen blobs (−6,526 B across all 10 blobs)

Compression happens only in the xtask codegen, and DEFLATE decoding doesn't care how a valid stream was produced. So the encoder is switched from flate2's Compression::best() to Zopfli — a deflate-compatible encoder that uses iterative optimal (shortest-path) LZ77 parsing to squeeze a few percent more from the same format.

  • The output is a standard raw-deflate stream, so the runtime flate2::read::DeflateDecoder reads it unchanged — no format or decoder change.
  • xtask is publish = false and is not in the crate's runtime dependency tree (cargo tree -e normal shows no zopfli), so no consumer-facing dependency changes.
  • The extra build-time cost lands only in offline codegen. Default 15 iterations is the sweet spot (100 iterations saved only ~60 B more for ~50× the time).
  • Biggest blobs: pair_indices 44,567 → 42,556, percentages 39,019 → 35,623, feature_matching 21,188 → 20,578.

Region percentages: 3-byte byte-plane + drop PERCENT_RANGES (−1,056 B)

The region percentage deltas now use three fixed-width byte planes (low/mid/high) — the same stream-split scheme already used for the pair indices — instead of postcard varint.

  • Being fixed-width and element-addressable, the percentages reuse PAIR_RANGES (pairs and percentages share identical per-region counts), so the separate PERCENT_RANGES offset table is removed (−964 B of .rodata).
  • Also drops the decode::<u32> postcard monomorphization. RegionData collapses from 4 fields to 2.

🤖 Generated with Claude Code

Two lossless changes; musl `inspect` example 778,528 -> 770,944 B
(-7,584, -0.97%). All tests and the JS-equivalence proptests pass.

- Compress the generated data blobs with Zopfli instead of flate2 in the
  xtask codegen. Zopfli emits a standard raw-deflate stream, so the runtime
  `flate2::read::DeflateDecoder` reads it unchanged and no consumer-facing
  dependency changes (xtask is `publish = false` and is not in the crate's
  runtime dependency tree). Shrinks all 10 blobs 116,422 -> 109,896 B.

- Store the region percentage deltas as three fixed-width byte planes (the
  same stream-split scheme already used for the pair indices) instead of
  postcard varint. Being element-addressable they reuse PAIR_RANGES, so the
  separate PERCENT_RANGES table is dropped (-964 B of rodata) along with the
  `decode::<u32>` monomorphization. RegionData collapses from 4 fields to 2.
@codspeed-hq

codspeed-hq Bot commented May 29, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 6 untouched benchmarks


Comparing zopfli-compression (d2a6219) with main (82e51cd)

Open in CodSpeed

@codecov

codecov Bot commented May 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.04%. Comparing base (82e51cd) to head (2ca304f).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #691   +/-   ##
=======================================
  Coverage   99.04%   99.04%           
=======================================
  Files          47       47           
  Lines        2413     2415    +2     
=======================================
+ Hits         2390     2392    +2     
  Misses         23       23           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Boshen Boshen force-pushed the zopfli-compression branch from 2ca304f to d2a6219 Compare May 29, 2026 12:32
@Boshen Boshen merged commit f434ade into main May 29, 2026
28 checks passed
@Boshen Boshen deleted the zopfli-compression branch May 29, 2026 13:18
@oxc-guard oxc-guard Bot mentioned this pull request May 29, 2026
Boshen pushed a commit that referenced this pull request May 29, 2026
## 🤖 New release

* `oxc-browserslist`: 3.0.3 -> 3.0.4 (✓ API compatible changes)

<details><summary><i><b>Changelog</b></i></summary><p>

<blockquote>

##
[3.0.4](oxc-browserslist-v3.0.3...oxc-browserslist-v3.0.4)
- 2026-05-29

### Other

- DRY up feature/region codegen with shared table + lookup helpers
([#694](#694))
- Consolidate bundled-data loading behind compression helpers
([#693](#693))
- Reduce binary size: run-length encode feature support versions
([#692](#692))
- Reduce binary size: Zopfli codegen compression + percentage byte-plane
([#691](#691))
- Reduce binary size: byte-plane (stream-split) compression for region
pair indices
([#690](#690))
- Update README binary size to 621K
([#689](#689))
- Reduce binary size of bundled caniuse/electron data
([#688](#688))
- Switch codegen data source from caniuse-db to caniuse-lite
([#687](#687))
- Update browserslist
([#685](#685))
- Update rust crates
([#682](#682))
- Update browserslist
([#679](#679))
- Update browserslist
([#678](#678))
- Update browserslist
([#677](#677))
- Update browserslist
([#673](#673))
- Update browserslist
([#671](#671))
</blockquote>


</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

Co-authored-by: oxc-guard[bot] <276638029+oxc-guard[bot]@users.noreply.github.com>
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