Skip to content

feat: migrate to HTML Minifier Next - #170

Open
stevenjoezhang wants to merge 2 commits into
masterfrom
agent/html-minifier-next
Open

stevenjoezhang wants to merge 2 commits into
masterfrom
agent/html-minifier-next

Conversation

@stevenjoezhang

@stevenjoezhang stevenjoezhang commented Aug 17, 2026

Copy link
Copy Markdown
Member

What changed

  • replace the unmaintained html-minifier dependency with html-minifier-next
  • make the Hexo filter async to support the successor's ESM API
  • require Node.js 22.13+
  • replace the two legacy default-type options with removeDefaultTypeAttributes
  • translate compatible legacy option combinations and warn conservatively when the old values differ
  • keep exclude as a plugin-only option without forwarding it to the minifier
  • update the test matrix, documentation, and regression coverage

Why

html-minifier is unmaintained and its ReDoS vulnerability has no patched release. HTML Minifier Next is its actively maintained successor and preserves the configuration and output semantics needed by this plugin much more closely than the alternatives evaluated in #156.

This supersedes #156 and addresses #84 and #148.

Breaking changes

  • Node.js 22.13 or newer is required.
  • The filter is asynchronous internally.
  • removeScriptTypeAttributes and removeStyleLinkTypeAttributes are now represented by the combined removeDefaultTypeAttributes option. Equal legacy values are migrated automatically. When they differ, the plugin preserves both attributes and emits a warning instead of applying a more aggressive transform.

Compatibility and performance

Using the plugin defaults against a local generated Hexo corpus of 1,368 HTML files (99,016,729 input bytes):

  • 1,368/1,368 outputs were byte-for-byte identical to html-minifier@4.0.0
  • <!-- more --> remained intact
  • runtime improved from 8,995.6 ms to 5,717.2 ms, about 1.57x faster on that corpus

Validation

  • npm test -- --no-parallel
  • tests on the minimum runtime with node@22.13.1
  • ESLint using the repository's Hexo configs for source and tests
  • npm audit --omit=dev — 0 production vulnerabilities
  • npm pack --dry-run --json

@stevenjoezhang
stevenjoezhang marked this pull request as ready for review August 17, 2026 17:09
@stevenjoezhang stevenjoezhang changed the title feat!: migrate to HTML Minifier Next feat: migrate to HTML Minifier Next Aug 17, 2026

@SukkaW SukkaW left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not hang dead on one tree. I'd rather having a breaking change and go htmlnano route.

@stevenjoezhang

Copy link
Copy Markdown
Member Author

I ran a fresh benchmark against the hexo-many-posts dataset.

Methodology

  • 1,368 generated HTML files
  • 99,016,729 input bytes (94.43 MiB)
  • Node.js v26.7.0 on an Apple M1 Pro
  • Three independent processes per implementation, reporting the median
  • Files and modules were loaded before timing
  • Files were minified sequentially
  • Each implementation received one small synthetic warm-up document
  • Output size and SHA-256 were identical across all three runs

Results

Implementation Median time Relative speed Output size Reduction
Original: html-minifier 4.0.0 9.043 s 1.00x 92.10 MiB 2.46%
PR #156: htmlnano 3.4.0 11.179 s 0.81x 86.80 MiB 8.08%
PR #170: html-minifier-next 7.6.0 5.358 s 1.69x 92.10 MiB 2.46%
html-minifier-terser 7.2.0 10.580 s 0.85x 92.10 MiB 2.46%
minify 15.3.1 6.314 s 1.43x 83.37 MiB 11.71%
@minify-html/node 0.18.1 3.108 s 2.91x 86.23 MiB 8.68%

PR #170 produced byte-for-byte identical output to the original implementation on this dataset while being 1.69x faster.

PR #156 produced output around 5.3 MiB smaller than PR #170, but it was about 24% slower than the original and 2.09x slower than PR #170.

The other alternatives are less direct comparisons:

  • minify uses more aggressive defaults, including optional-tag removal, and internally depends on html-minifier-next 6.2.11.
  • @minify-html/node has the best overall benchmark numbers, but it is a native Rust binding with different configuration and HTML-processing semantics.
  • html-minifier-terser produced the same output as the original while being slower on this dataset.

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.

Maybe Replace html-minifier with htmlnano or html-minifier-terser due to security vulnerabilities [Proposal] Replace html-minifier with htmlnano

3 participants