Skip to content

Optimizing Compiler: Component Folding #7323

Open
@sebmarkbage

Description

@sebmarkbage

This is like the final frontier for React but I never really wrote anything about it so I figured I'd create an issue.

Basically, the idea is to utilize information about how React works to do constant folding and inlining of components under certain conditions.

Example Source:

function Foo(props) {
  if (props.data.type === 'img') {
    return <img src={props.data.src} className={props.className} alt={props.alt} />;
  }
  return <span>{props.data.type}</span>;
}
Foo.defaultProps = {
  alt: "An image of Foo."
};
var CSSClasses = {
  bar: 'bar'
};
module.exports = CSSClasses;
var Foo = require('Foo');
var Classes = require('Classes');
function Bar(props) {
  return <Foo data={{ type: 'img', src: props.src }} className={Classes.bar} />;
}

By knowing what Foo and Classes is made up of, we can turn the Bar component into this:

var Foo = require('Foo');
var Classes = require('Classes');
function Bar(props) {
  return <Foo data={{ type: 'img', src: props.src }} className={Classes.bar} />;
}
function Bar_optimized(props) {
  return <img src={props.src} className="Bar" alt="An image of Foo." />;
}

Dead-code elimination then strips it down to just:

function Bar_optimized(props) {
  return <img src={props.src} className="Bar" alt="An image of Foo." />;
}

Now there are a bunch of different cases where this needs to bail out. For example, we need to know that the CSSClasses object and the defaultProps object is immutable, or we need to infer that it is immutable using Escape analysis.

With classes these bail out cases are even more complex.

The problem is that current JS infrastructure is particularly bad at this kind of whole program or whole package linking. Node doesn't have a notion of per package private modules so anything can mutate anything by default. Transpilers such as Babel are set up to work on a single file at a time. They don't have access to the source of other files to do this analysis. Rollup is closer but is limited to a small set of static primitives.

However, once smarter compilers become more prevalent in the JS world or we find ways to hack around the limitations, we can start building out more of these smarter compiler optimizations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    React Core TeamOpened by a member of the React Core Team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions