uhtml v4 - Release notes by WebReflection · Pull Request #86 · WebReflection/uhtml
This MR is a partial rewrite of v3 with a "back to origins" purpose and a lot of performance and RAM consumption improvements over the previous stable v3 version.
Please note that while most needed or demanding v3 features will be, eventually, ported over v4, this should be almost a drop-in replacement for v3, with the following most notable breaking changes.
Breaking Changes
- this is now a 100% ECMAScript Module, with its own CJS counterpart but only for developers purpose. The builds to leak globally uhtml are gone for good, as it's been always awkward anyway to do so in the first place. Times are different now, and so is the default module nature: a module and nothing else
- current exports are
uhtml(~2.5K) for default, non-keyed yet blazing fast and most common use cases,uhtml/keyed(~2.6K) for both implicit (default) and explicit keyed operations anduhtml/node(~2.2K) for one-off only use cases - all attributes that are part of the element prototype are handled directly whenever their value changes:
- any
onclickor nativeon*handler is just directly set like any other special attribute such asvaluefor inputs or textareas, and so on - both
classandstyleare handled as special attributes (amongaria,dataandref) so thatclass=${value}now directly setclassNameof the element whilestyle=${value}now directly set theelement.style.cssTextbut only when the current value is different from the previous one
- any
- both
html.for(...)andhtml.nodeutilities have been moved:- the
uhtml/keyedexport provides anhtmlForand ansvgFordirect callback to create related tags. The full export there is{Hole, render, html, svg, htmlFor, svgFor, attr}and these are all typed - the
uhtml/nodeexport provides a one-off only implementation of the logic, without ever caching details around nodes and without logic around updates ... this export is literally for one-off operations and nothing else, but as escape hatch, creating one-off content can always be done with theuhtml/keyedexport and eitherhtmlFor({})orsvgFor({})utility, still keeping performance high and memory consumption low
- the
- the default, non keyed, export, only accepts Hole instances either to render or as interpolation, among other usual values such as
string,boolean,number, or arrays within interpolations - once an array is used as interpolation, it is always expected for that interpolation to be an array. This actually better reflects real-world scenarios and it makes it possible to actually improve both holed arrays and not-holed arrays performance
- array can contain only nodes or holes ... hybrid array are not supported so use
htmlorsvgtags even to create just static text content - beside holed array cases, there are no comments pinned or visible on the produced layout anymore: the layout is as clear as possible and only when lists are meant to grow or shrink a comment might appear as "pin" to be able to perform DOM diffing operations
- callbacks as holes have been removed for good as it's unclear what would be the intent there and it's always possible to invoke callbacks with the current node via
reffeature
Memory Improvements
- the amount of runtime closures (callbacks) creation has been drastically reduced to "almost 0". While templates are parsed, all operations are pre-inferred for attributes, where the static name part is very static, and both array operations and text cases (style, script, textarea and others where no nodes are allowed inside) don't need any closure creation per each copy or clone of the very same template. Only generic nodes or fragments operations use a
bindfor the very always same callback, helping engines further to optimize for its operations. All other updates use always the exact same callback reference just passing a bit more details than before and the resulting value would update the retained one when that's different from the previous one - comments as placeholders/pins on the template tree are swapped once only if the comment is not an Array operation, avoiding the need to even create text nodes over comment nodes so that nodes count is always ideal
- the "wired" fake DocumentFragment to represent multiple nodes at the same reference is now a real PresistentFragment class so that there is actually zero duplication of virtual fragments. The PersistentFragment is technically portable and reusable in any project but right now it just satisfies this module's requirements
- the non-keyed (default) stack dance has been simplified quite a lot so that retained references and values count has been lowered too
About TypeScript
This module now generates automatically all definitions in the most accurate way and it describes types also internally, hoping to welcome more TS contributors when it comes to bugs or improvements.