react
react copied to clipboard
Compile JSX directly to VDom for improve draw of view performance and allow progressive view rendering
Right now JSX compiles to array of React.createElement or _jsx function. Each function calls for make VDom elements in runtime. I suggest compiling JSX directly to VDom. Because each function call in javascript has its own cost. On my PC its 2 nanoseonds. On 1000 JSX elements its 2 milliseconds.
This (call function) operation can be done not at runtime, but at the time of compilation. This optimization will improve the speed of JSX calculation by 25-50%.
Performance test
The simplest speed test. Can be copied to a file and run in nodejs. On my PC have next result: time-jsx: 0.22ms time-vdom: 0.15ms
On a real application, the gap can be much larger.
const ce = (elem, props, childrens) => {
return {
type: elem,
props,
childrens
}
}
const compJsx = () => {
return (
ce(
"div",
null,
[
ce(
"div",
null,
[
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
)
]
),
ce(
"div",
null,
[
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
)
]
),
ce(
"div",
null,
[
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
)
]
),
ce(
"div",
null,
[
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
)
]
),
ce(
"div",
null,
[
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
)
]
),
ce(
"div",
null,
[
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
)
]
),
ce(
"div",
null,
[
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
)
]
),
ce(
"div",
null,
[
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
)
]
),
ce(
"div",
null,
[
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
)
]
),
ce(
"div",
null,
[
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
),
ce(
"div",
null,
"Текст"
)
]
)
]
)
);
}
console.time("time-jsx");
const resultJsx = compJsx();
console.timeEnd("time-jsx");
const compVDom = () => {
return {
"type": "div",
"props": null,
"childrens": [{
"type": "div",
"props": null,
"childrens": [{
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens":
"Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props"
: null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}
]
}, {
"type": "div",
"props": null,
"childrens": [{
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens":
"Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}
]
}, {
"type": "div",
"props": null,
"childrens": [{
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens":
"Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}
]
}, {
"type": "div",
"props": null,
"childrens": [{
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}
]
}, {
"type": "div",
"props": null,
"childrens": [{
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}
]
}, {
"type"
: "div",
"props": null,
"childrens": [{
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}
]
}, {
"type": "div",
"props": null,
"childrens": [{
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}
]
}, {
"type": "div",
"props": null,
"childrens": [{
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}
]
}, {
"type": "div",
"props": null,
"childrens": [{
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}
]
}, {
"type": "div",
"props": null,
"childrens": [{
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}, {
"type": "div",
"props": null,
"childrens": "Текст"
}
]
}
]
};
}
console.time("time-vdom");
const resultVDom = compVDom();
console.timeEnd("time-vdom");
console.log("Result JSX length:", JSON.stringify(resultJsx).length);
console.log("Result VDom length:", JSON.stringify(resultVDom).length);
also...
This optimization will allow progressive view calculation and rendering.
The current implementation has the following problem. Calculation is made from depth to upwards. These calculations cannot be interrupted. Heavy calculations will block animations in the browser.
_jsx(
"div",
{},
[
_jsx(
"div",
{},
[
_jsx( // <-- must call first
"div",
{},
"Текст"
)
]
)
]
)
In VDom version you can make calculation of dom from top to bottom and make separation of calculations by 16 ms for unblocked browser animations.
{
type: "div", // <-- must call first
props: {},
childrens: [
{
type: "div",
props: {},
childrens: [
{
type: "div",
props: {},
childrens: "Текст"
}
]
}
]
}