-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New VDOM Rendering Engine #58
Conversation
private _filterAndConvert(nodes: DNode): WNode | VNode; | ||
private _filterAndConvert(nodes: DNode | DNode[]): (WNode | VNode) | (WNode | VNode)[]; | ||
private _filterAndConvert(nodes: DNode | DNode[]): (WNode | VNode) | (WNode | VNode)[] { | ||
const isArray = Array.isArray(nodes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would probably rename this nodesIsArray so this is clearer
private _filterAndConvert(nodes: DNode | DNode[]): (WNode | VNode) | (WNode | VNode)[]; | ||
private _filterAndConvert(nodes: DNode | DNode[]): (WNode | VNode) | (WNode | VNode)[] { | ||
const isArray = Array.isArray(nodes); | ||
const filteredNodes = Array.isArray(nodes) ? nodes : [nodes]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tiny one; you could just do isArray
rather Array.isArray(nodes)
again
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, it doesn't infer the types correctly if you reuse the var.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shame!
const convertedNodes: (WNode | VNode)[] = []; | ||
for (let i = 0; i < filteredNodes.length; i++) { | ||
const node = filteredNodes[i]; | ||
if (!node) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
node === undefined
will probably be faster and clearer here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can also be null
😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right!
src/widget-core/WidgetBase.ts
Outdated
node.bind = this; | ||
convertedNodes.push(node); | ||
if (node.children && node.children.length) { | ||
node.children = this._filterAndConvert(node.children); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if recursion is faster than iteration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect that the difference is negligible, certainly not shown up as a bottleneck in any of the performance analysis I've done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough, more just an open ended question. If we don't spend much processing time here would imagine it won't matter much as you say.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a hot path, runs for the render result of every widget being processed. I can certainly look at unrolling the loop and see if it makes any meaningful different.
tests/widget-core/unit/d.ts
Outdated
// 'creates VNode with the DOM node attached, associated tagname and default diff type'() { | ||
// const div = document.createElement('div'); | ||
// const vnode = dom( | ||
// { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need deleting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, needs un-commenting!
const projector = new Projector(); | ||
|
||
projector.append(); | ||
const r = renderer(() => w(App, {})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is much more straightforward and easy to understand. Nice 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looking good. End user ergonomics will be simpler and the code reads better in general. 👍
…ction for an invalidation
…he correct position
Tested with js-framework-benchmark and examples - hnpwa, realworld, custom-element-menu, widget-showcase & custom-element-showcase. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Type: feature
The following has been addressed in the PR:
prettier
as per the readme code style guidelinesDescription:
A new implementation of the VDOM rendering engine.
DNode
s.ProjectorMixin
which reduces indirection and ultimately bundle size.ProjectorMixin
to ensure backwards compatibility.Performance benchmarks: New vdom (left) vs the existing implementation (right)
Basic Usage
Implementation Tracking
dom
pragmaupdateanimation support Update animation support has been removedResolves #54