Coder Social home page Coder Social logo

Better JSX about next.js HOT 24 CLOSED

vercel avatar vercel commented on May 12, 2024
Better JSX

from next.js.

Comments (24)

rauchg avatar rauchg commented on May 12, 2024 3

We could also call this issue "Universal JSX"

from next.js.

SeeThruHead avatar SeeThruHead commented on May 12, 2024 3

I encountered something like this in a project recently that had to be built for both react and preact.
Solved the issue with different babel env's and a babel plugin called jsx-pragmatic

from next.js.

matthewmueller avatar matthewmueller commented on May 12, 2024 2

This has been working quite well for me: https://github.com/matthewmueller/sun. Right now it only works with Preact, but could work in React with some cajoling.

Works in ES6, ES5, ES3... it's just functions.

from next.js.

trueadm avatar trueadm commented on May 12, 2024 1

I don't think it's ideal to to expect all objects to be inline. You can get big performance wins on hoisting static elements out, which would fail in this case as they'd be hoisted outside of the exported function. Inferno takes this further and uses hoisting all over the place to get really good performance/memory wins.

This is a tricky problem, I'll have a think on how to solve it.

from next.js.

rauchg avatar rauchg commented on May 12, 2024 1

Additionally, we can have the renderer extend the config any way it wants:

decorate(config)

function decorateForInferno (cfg) {
  return Object.extend({}, cfg, {
    cfg.cdn: false, // or your own build of the next cdn
    cfg.jsxPragma: 'Preact.createElement'
  })
}

If we switch to practical JSX we can make the pragma a config option

from next.js.

tolmasky avatar tolmasky commented on May 12, 2024

Not sure if you've taken a look at the work I've done with generic jsx (http://tolmasky.com/2016/03/24/generalizing-jsx/), but it is a re-imaging of jsx as a pure syntax transformation (that then could incidentally be used to represent inline HTML), which could serve these goals. Essentially, any function can be used as a JSX tag, and it has some nice benefits like being able to curry tags as well (OurTable = <Table style = { style }/>; <OurTable>...</OurTable>). We've successfully used it in DemoKit, but it would take a bit of work to make work with react, although it aircraft includes a babel plugin.

from next.js.

rauchg avatar rauchg commented on May 12, 2024

I think generalizing it is absolutely critical. Thanks for the pointer.
Otherwise we'll be perpetually in the limbo of "it's JavaScript buuuuut not
quite".

On Tuesday, October 25, 2016, Francisco Ryan Tolmasky I <
[email protected]> wrote:

Not sure if you've taken a look at the work I've done with generic jsx (
http://tolmasky.com/2016/03/24/generalizing-jsx/), but it is a re-imaging
of jsx as a pure syntax transformation (that then could incidentally be
used to represent inline HTML), which could serve these goals. Essentially,
any function can be used as a JSX tag, and it has some nice benefits like
being able to curry tags as well (OurTable = <Table style = { style }/>;
...). We've successfully used it in DemoKit, but it
would take a bit of work to make work with react, although it aircraft
includes a babel plugin.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#23 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAAy8UujGYS8GIHnqPciJS-JyW2ddqcMks5q3jC1gaJpZM4KYHmr
.

@rauchg https://twitter.com/rauchg

from next.js.

trueadm avatar trueadm commented on May 12, 2024

@matthewmueller I don't see how that addresses the issues here? React elements can be hoisted, as can Preact ones – for a good reason, they're very performant if they do. What you're suggesting actually reduces performance as this optimisation isn't able to apply itself.

from next.js.

trueadm avatar trueadm commented on May 12, 2024

For example: if I did the following in my code:

function MyComponent() {
  return <div className="something"><span>Hello world</span></div>
}

With hoisting it becomes:

var hoisted = <div className="something"><span>Hello world</span></div>;

function MyComponent() {
  return hoisted
}

The performance difference according to my benchmarks to mount and update is 650%. Now hopefully you understand the importance of this feature.

from next.js.

matthewmueller avatar matthewmueller commented on May 12, 2024

@trueadm oh okay, up until your first comment this sounded more like a developer experience issue (needing a magic import react + forgetting the slash on <div/>).

thanks for the insight there. while i haven't seen VDOM tree rendering be a performance bottleneck in any of my apps (even with top to bottom re-renders every time), it's good to keep in mind.

from next.js.

rauchg avatar rauchg commented on May 12, 2024

@trueadm I think it should still be possible to perform that optimization even if we go with a generic jsx transform?

from next.js.

developit avatar developit commented on May 12, 2024

FWIW, this only affects static leaves. Any JSX containing variable references cannot be hoisted. In my experience this is the majority of JSX, but it varies depending on your use-case.

Also, functions can be memoized to achieve similar performance gains without relying on any transpiler features.

from next.js.

trueadm avatar trueadm commented on May 12, 2024

@developit Unfortunately, Inferno doesn't work this way :/ it creates blueprints that are hoisted out and referenced in the vDOM.

from next.js.

developit avatar developit commented on May 12, 2024

True, though that seems outside the scope of JSX itself.

from next.js.

developit avatar developit commented on May 12, 2024

@rauchg we could avoid the extra function invocation by making Next.createElement just a reference to the appropriate underlying hyperscript implementation rather than a proxy function.

from next.js.

trueadm avatar trueadm commented on May 12, 2024

@developit in fact after thinking about this more, I don't see why this is an issue. Can't Next simply look at the file AFTER Babel has compiled JSX and then use that code?

from next.js.

developit avatar developit commented on May 12, 2024

@trueadm You mean transpile to something like Next.createElement but then rewrite those to point to whatever implementation is in use?

from next.js.

trueadm avatar trueadm commented on May 12, 2024

@developit No need. If someone was using JSX in their module, they would have put import React from 'react'; at the top of their module, so the whole module should get passed to the client in that case, not just the function.

from next.js.

developit avatar developit commented on May 12, 2024

I might be mixing things up here - I believe @rauchg was advocating for removing the import entirely and automatically injecting the appropriate JSX reviver based on the configured renderer.

from next.js.

trueadm avatar trueadm commented on May 12, 2024

@developit Why go to the hassle of that? It's only going to bring issues downstream when more renderers are added. I'd much rather the configured renderer also could define its own Babel transforms. The "default" renderer, aka React would define the React Babel transforms, etc.

from next.js.

developit avatar developit commented on May 12, 2024

ahh yeah that seems simpler, since the babel config is created at a time when the renderer would already have been specified.

from next.js.

developit avatar developit commented on May 12, 2024

@SeeThruHead seems like that plugin could actually do basically all of the work for this issue haha

from next.js.

rauchg avatar rauchg commented on May 12, 2024

@trueadm I really like the idea of the renderer defining transforms!

from next.js.

rauchg avatar rauchg commented on May 12, 2024

I'm closing this for the time being. We addressed the import problem with #295. We're addressing custom renderers by giving them the ability to change webpack and babel configs :)

from next.js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.