Skip to content

v9.0.0

Latest

Choose a tag to compare

@fb55 fb55 released this 29 Oct 00:06

Full speed unlocked: This release features a faster approach to decoding entities based on cuckoo hashing, replacing the previous trie-based approach. Instead of walking a trie character by character, we now do a few lookups in a hash table.

I first looked into cuckoo hashing around 2015, and again when I adopted the trie approach that @inikulin had pioneered for parse5, but could never make it work. This was a fun problem to throw AI models at for some time, but now Fable solved it quite well.

This feels like the last big speed boost for entities decoding in JS.

Breaking changes

  • Streaming decoders no longer take a decode table: new EntityDecoder(htmlDecodeTree, emit, errors) becomes new HtmlEntityDecoder(emit, errors), and XmlEntityDecoder replaces the XML variant. The htmlDecodeTree, xmlDecodeTree and determineBranch exports are removed. Synchronous decoding APIs are unchanged. #2336
  • Encoding emits decimal numeric references and the shortest named aliases: encodeXML("ü") yields ü instead of ü, and encodeHTML("ℵ") yields ℵ instead of ℵ. #2355
  • escapeAttribute and EncodingMode.Attribute also escape < and >, matching the latest HTML spec. By @ybai08 in #2398
  • The deprecated getCodePoint export of entities/escape is removed; use String.prototype.codePointAt instead. #2355

Improvements

  • HTML decoding: common named references 1.15–1.23×, a dense sweep of all 2,125 names 1.24–1.33×, attribute-heavy HTML 1.06–1.18× as fast. XML decoding with mixed named and numeric references is 1.06–1.09× as fast. #2336
  • Smaller decoders: the HTML bundle shrinks from 15.54 to 13.42 kB gzipped, the XML-only bundle from 0.92 to 0.84 kB gzipped, and 29–32 kB less memory is retained after import. #2336
  • The readme now compares entities with popular alternatives across a range of inputs. #2407

Compared with v8.1.0; ranges span Node 26.8 and Node 24.19 on a Ryzen 7 5800X3D. Results vary with input.

Full Changelog: v8.1.0...v9.0.0