Coder Social home page Coder Social logo

Comments (24)

Rich-Harris avatar Rich-Harris commented on May 3, 2024 18

@trueadm thanks for @-ing me, now I know why @gaearon was tweeting about this! Since AOT is a bit buzzwordy and has some misconceptions around it, probably worth addressing a few things as I (creator of Svelte, for those of you who don't know me) see them.

Firstly, AOT doesn't necessarily mean 'having no runtime', it just means that some work is moved from the browser to the compiler. Whether or not you describe a particular framework as having a 'runtime' largely depends on your semantics. When Svelte talks about not having a runtime, it just means that your components get compiled to code that manipulates the DOM directly, rather than creating a data structure that requires an additional step (be it some form of key-value observation, or virtual DOM reconciliation) before the UI can reflect the app state. This is partly about making smaller apps, but it's also partly about performance — it's just less work for the browser to do.

Secondly, I don't see it as a binary thing — I think there are degrees of AOT. I would certainly consider babel-react-optimize to be a form of AOT. (The reason you won't find the AOT label on the Svelte website is because I don't want people to think Svelte is doing the same thing as Angular — it's not! Angular is just turning string templates into an intermediate representation, which other frameworks have been doing for years, rather than actual code.)

Thirdly, there's a perception that AOT doesn't scale, which is to say that the incremental cost of components is higher and will overtake the initial savings once your app reaches a certain size. That's theoretically true, and we don't know where that threshold is yet (and it's different for e.g. React and Preact). AOT frameworks can (and Svelte does) deduplicate shared helpers. But the key thing to note is that it's the initial cost that hurts the most, when the user is impatiently waiting for the app to become interactive. Today you can't visit Twitter without someone hectoring you about code-splitting, but if any of your entry points have a dependency on a framework, that's an immovable cost that you can't code-split away. Selectively including the bits of framework a given entry point needs — aka AOT — is the only way to eliminate it.

Fourthly (sorry, I'm rambling a bit!), debugging is nicer than you might imagine, at least in Svelte's case — decent sourcemap support, and when things do go wrong you're stepping through a short stack trace (and the generated code is pretty readable). And we have dev mode warnings. It's an important point though, and always something to improve.

Anyway, the tl;dr is that AOT encompasses lots of different ideas, and I'm excited to see how they impact the React ecosystem.

I don't think AOT compilation to vanilla JS DOM operations is the ideal. More, transforming components and vdom into OP codes that are put into shared array buffers that can be operated on at a WASM level as well as JS. I've been hacking on some ideas around this actually and it looks promising

Hope you can share something soon!

from react-future.

sebmarkbage avatar sebmarkbage commented on May 3, 2024 8

Well said, @Rich-Harris.

TBH, the reason I haven't really gotten into this discussion is that I think it is a typical pattern of any new technology focus that we'll quickly get past. 1) We see a misconception about what it actually is. 2) We see a misconception of how magical it will be. 3) We see a misconception how hard it will be to build. 4) We see a misconception how hard it will be to debug. Always solvable.

I'm just excited to get into the details and having many people exploring this space. Particularly how this can be made to work with abortable scheduling, across component levels and what heuristic with regard to inlining vs. reusability ends up being the most efficient. How we can make whole program compilation or small subset compilation parallelizable and scalable so we don't hit cliffs when large companies start using (cough, Swift). Let's talk about those things instead.

It is clearly better to have some for AOT compilation if you can, and debugging is solvable.

FWIW, we have an internal compiler project at FB that I'm hoping will set the foundation that we can build on top. There's a lot of infra to be built for us to be able to actually take advantage of this stuff at scale.

It is also unclear to me whether compiling to JS is the best step. I think custom byte code with an interpreter runtime can be more efficient after a certain application scale - which wouldn't strictly be pure application code.

If you don't mind, I will close out this issue since I don't think that it will completely describe the goal here. Then I'll reopen another "umbrella" issue which can encompass a project with various incremental steps we need to take advantage of more advanced AOT compilation.

from react-future.

gaearon avatar gaearon commented on May 3, 2024 7

To be honest I find this particular example a bit of a straw man. This is not representative of most React components I worked with, which have more complex updates, lifecycles, and render child components depending on state.

As I mentioned earlier, you can find our thinking about this here: https://github.com/facebook/react/labels/Component%3A%20Optimizing%20Compiler. For example, "component folding" would inline trivial components into bigger components, reducing the output size.

from react-future.

trueadm avatar trueadm commented on May 3, 2024 4

I don't think AOT compilation to vanilla JS DOM operations is the ideal. More, transforming components and vdom into OP codes that are put into shared array buffers that can be operated on at a WASM level as well as JS. I've been hacking on some ideas around this actually and it looks promising.

from react-future.

trueadm avatar trueadm commented on May 3, 2024 3

@developit Yep, there is no VDOM, it's just low level instructions that can better interop.

from react-future.

developit avatar developit commented on May 3, 2024 2

Having looked into svelte et al a little bit, I think the complexity comes in child and composition diffing, not attribute/prop diffing. Diffing a large list of components based on keys via AOT would produce fairly verbose output and likely not optimize as well.

from react-future.

gaearon avatar gaearon commented on May 3, 2024 1

We might explore a limited version of this in the future. I don't think we'll ever go "full AOT" like Svelte because some things are inherently dynamic (e.g. diffing lists), and inlining that logic into components while preserving full React power would produce bloated bundles.

I'm not very familiar with Angular so can't comment on that comparison but just wanted to note React doesn't have a "template compilation" step in the first place.

from react-future.

gaearon avatar gaearon commented on May 3, 2024 1

You might be interested in these issues: https://github.com/facebook/react/labels/Component%3A%20Optimizing%20Compiler

from react-future.

trueadm avatar trueadm commented on May 3, 2024 1

@scottmas It's far easier to AOT compile templates, that's why all AOT examples have so far been from template based libraries/frameworks. React components with JSX aren't that constrained, so it makes it far harder to do that work at compile time. This is all definitely stuff for the future.

from react-future.

blainekasten avatar blainekasten commented on May 3, 2024

This has been on my mind here and there. I think there are 2 sides to this coin.

  1. The code you write is not the code you debug.
  2. The weight of the code is dramatically increased by the need for framework and ceremony.

Frameworks like svelte seem promising, though it is early to know if the appeal is worth it. I personally have concerns about the code being hard to debug. But I think this is a very interesting concept and have tried to think about if it's possible to extract out enough logic into simple and concise code that the framework is unnecessary beyond development conveniences.

from react-future.

styfle avatar styfle commented on May 3, 2024

@blainekasten What makes you say this?

The code you write is not the code you debug

Today, I debug ES6 code that has been compiled and running as ES5 code in the browser. Just include the source maps. Is there a reason you think source maps would not work for AOT compiling?

from react-future.

scottmas avatar scottmas commented on May 3, 2024

I'm also skeptical source maps will work in the AoT world, except in a very rudimentary form.

Source mapping was invented to solve a problem that is equivalent to translating Australian English (ES6) to American English (ES5). You'll need to change a couple idoms here and there (i.e. change var declarations), but it's pretty straightforward.

However, translating English (React) to Chinese (AoT compiled code) becomes orders of magnitude more complex. The "meaning" remains the same, but nearly all the implementation details are different.

This said, I think this is an acceptable tradeoff if the benefits are significant enough. Particularly since developers will still be able to perform development in React proper, not the AoT version.

It's unclear at this point how large the potential benefits could be, but for example Svelte was able to decrease code size about 12x for TodoMVC (4kb vs 45kb), be about 1.3x faster, and be probably significantly faster on initial boot time since there's far less code to parse. But it's unclear if these benefits scale to complex real world applications.

from react-future.

scottmas avatar scottmas commented on May 3, 2024

@gaearon @sebmarkbage @acdlite @trueadm @developit and other people working on the future of React (e.g. React Fiber) have opinions?

from react-future.

acdlite avatar acdlite commented on May 3, 2024

Yeah, I think the tl;dr version is that we will likely compile to code that modifies React internal data structures (fibers), but not the DOM directly. Will always need a runtime.

from react-future.

scottmas avatar scottmas commented on May 3, 2024

Interesting. So just so I can clarify this in my mind... Right now there are three major code pieces that need to be loaded to run a react app: (1) react, (2) react-dom, and (3) the application itself.

So are you saying devs could create a compiled version of the application (3), but that (1) and (2) would remain the same?

from react-future.

gaearon avatar gaearon commented on May 3, 2024

Yes. To clarify, we're working on making the bundles smaller. However in our experience the size of React or ReactDOM is not the bottleneck—it's the application code. So we're interested in optimizing that for bigger and scalable wins.

from react-future.

sophiebits avatar sophiebits commented on May 3, 2024

It might be the case that we could cut out some parts of react or react-dom if all components were AOT compiled, but it is a non-goal to have no runtime – just like in Babel it makes sense to have a shared helper for creating classes instead of writing out all of the logic every time.

from react-future.

developit avatar developit commented on May 3, 2024

FWIW I agree about the runtime being a likely necessity, implementing AOT compilation of compositional components without a runtime seems like it would be either impossible or end up being N copies of a microframework for dealing with that case, which puts you in the same situation as babel helpers as mentioned.

from react-future.

blainekasten avatar blainekasten commented on May 3, 2024

However in our experience the size of React or ReactDOM is not the bottleneck—it's the application code

True, though it is semi-related to the way React application code is written. Trivial example here:

// React application code
import React from 'react';

class HideableDiv extends React.Component {
  state = {
    hidden: false,
  };
  
  toggleHide() {
    this.setState({hidden: !this.state.hidden});
  }

  render() {
    return (
      <div
        onClick={() => this.toggleHide()}
        style={{display: this.state.hidden ? 'none' : 'block'}}
      >Click To Hide Me!</div>
    );
  }
}

Now implemented in traditional JS:

const div = document.createElement('div');
div.innerHTML = 'Click to Hide Me!';
let hidden = false;

div.addEventListener('click', () => {
  hidden = !hidden;
  div.style.display = hidden;
});

The compared nature here is 17LOC to 7LOC. So the bottleneck may not be React or ReactDOM libraries, but may be the requirements of those libraries.

FWIW, I agree with almost ever sentiment here. Although I would be very interested to see this as a community project to gauge the viability of transforming stateful react application code into imperative runtime code while successfully source mapping back. If possible, that'd be pretty huge.

from react-future.

trueadm avatar trueadm commented on May 3, 2024

@developit I was under the impression that @Rich-Harris added in shared helpers into Svelte to help deal with those cases?

from react-future.

KyleAMathews avatar KyleAMathews commented on May 3, 2024

@trueadm similar to Glimmer? https://thefeedbackloop.xyz/designing-and-implementing-glimmer-like-a-programming-language/

from react-future.

trueadm avatar trueadm commented on May 3, 2024

@KyleAMathews very similar in some aspects, except the tricky parts is building a JSX+JS+Flow compiler that built these opcodes rather than working with Handlebars templates. From the opcodes you could then use OCaml, Rust or C++ to work with them and do all the diffing/hard work. Lifecycle events, refs and other user escape hatches would mean switching from WASM to JS to deal with them.

from react-future.

developit avatar developit commented on May 3, 2024

@trueadm seems like the opcode approach you outlined avoids having to jump between JS and WASM entirely, which is nice. Component implementation stays in JS but the actual diffing is done in a separately optimized layer?

from react-future.

scottmas avatar scottmas commented on May 3, 2024

@trueadm, this approach is ages off though, right? Seems like in the near future of React, compiler optimizations of application code will be the order of the day.

from react-future.

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.