-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Implement proposal for standardized JSX #25312
Comments
What's the demand for this particular kind of proposal like? Are there any frameworks out there that want to use it? The way it's specified every JSX node has a different object shape due to spreading the attributes on it. There is no guarantee that two JSX nodes stemming from that proposal have the exact same keys in the same order. Having different shapes makes them megamorphic from a JS engine perspective which will lead to code always being deopted that handles them. It's effectively the worst case scenario for performance in JS engines and would make this proposal significantly slower in real world apps compared to the existing JSX standard. Overall it's very unlikely that we're going to support it, unless a significant amount of users want it. |
|
|
There are only two major uses left for transpilers: types and JSX. I said around 2016 that types were going to become standardized, and everyone laughed it off. It's now at stage 1. JSX will eventually be standardized. But nobody wants to standardize classic or automatic runtime transformations, because we all know they're stop-gap solutions with serious flaws. I'm proposing an alternative implementation that has the real potential to become standardized due to its isolated nature. I just have no ability to get the word out that my proposal exists. Deno would implement it if it become standardized, but it won't become standardized unless at least some runtimes implement it. So this feature request was to solve the chicken/egg problem. I'm not absolutely proposing this be implemented right now. The purpose of this issue, and the one I filed in Bun, and the one I'll file in Babel soon, is to spark conversation with the intent of garnering the interest in framework and runtime authors, to see whether anyone thinks it's worthwhile to start implementing this as a possible solution towards future JSX standardization. |
Also yes, the playground uses spreads, but only when code authors use them. That was my point: not all JSX expressions contain spreads, and there's nothing inherent to JSX itself or my proposal that requires spreads. At most you're saying that a currently existing spread optimization will go away with this proposal. And I think that's fair to say. But I also think that it's worth it on the path to standardization. Plus, there are other benefits to my proposal, including the ability to use multiple different, incompatible JSX runtimes in the same file, which make up for the loss of an incidentally current optimization. |
Also, vanillajsx.com itself was on the top of hacker news a few weeks ago for a weekend, and had lots of discussion. There is interest about this concept. But my HN submission this morning of https://vanillajsx.com/unity/ got I think 1 view. So I do think there's a lot of potential interest in this proposal, I just can't prove it because I just can't get word out that it exists. I bet if you shared the link with some of your colleagues, at least a few would be interested in the idea. |
If you want more attention around your proposal then I think you need to talk more about the flaws of the current implementation and how your one solves them. You also never addressed the above mentioned supposed issue that your output is bad for performance. |
Can you imagine a standardization that says JSX must have auto-imports? Can existing auto-imports support more than one JSX runtime within the same project? Within the same file? Does anyone even recommend the classic runtime? Could you imagine a "well known global function" ever getting standardized? There's no path to standardization for the JSX status quo. |
I think @marvinhagemeister was misunderstanding the proposal, because the first transformation on the page is const b1 = {
[Symbol.for("jsx")]: "a",
...attrs,
href: "/foo",
children: ["Click me"]
}; and so I think he therefore thought that every JSX transformation results in const b1 = <a {...attrs} href='/foo'>Click me</a>; All the rest of the examples are like this: const b1 = <a href='/foo'>Click me</a>;
// becomes
const b1 = {
[Symbol.for("jsx")]: "a",
href: "/foo",
children: ["Click me"]
};
const b2 = <Button w={3} h={4}>Click me</Button>;
// becomes
const b2 = {
[Symbol.for("jsx")]: Button,
w: 3,
h: 4,
children: ["Click me"]
};
const b3 = <div class='foo' style='color:red' />;
// becomes
const b3 = {
[Symbol.for("jsx")]: "div",
class: "foo",
style: "color:red",
children: []
};
function Button(attrs, children) {
return <>Button title: {children}.</>;
}
// becomes
function Button(attrs, children) {
return {
[Symbol.for("jsx")]: "",
children: ["Button title: ", children, "."]
};
} |
No, you're too focused on the spread alone. The problem is that I'd highly recommend reading up about object shapes, shape transitions and inline caches in JS engines to get a better understanding of this topic. If you google a bit you'll find lots of information about that online. Speaking from experience of maintaining Preact rendering performance over the years and having built the precompile transform in Deno, getting these details right matters quite a bit for performance, both on the server and in the browser. |
@marvinhagemeister Thanks for the clarification. You clearly know a lot more than me about the internals of V8 etc. Can you recommend an alternation to my proposal to get rid of that inefficiency? Maybe just moving JSX attrs back into an |
Thanks to your feedback @marvinhagemeister I've updated the proposal to be compatible with optimizations you mentioned. It now matches the behavior of declare const jsx: unique symbol;
interface JsxExpr {
[jsx]: true,
tag: string | any,
attrs?: {
children?: any | any[],
[attr: string]: any,
},
} |
Proposal is at https://vanillajsx.com/unity/
The text was updated successfully, but these errors were encountered: