mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-09-11 22:57:35 +03:00
Adds React pe-functional-components benchmark and some React SSR changes (#2560)
Summary: Release notes: none All these changes are only internal changes related to React. This PR adds the `pe-functional-components` benchmark as tests to the React reconciler. The test was taken from: https://github.com/facebook/react/tree/master/scripts/bench/benchmarks/pe-functional-components. In order to make the server side renderer test pass, a few TODOs had to be filled in (logic was missing) and the JSON logic has to be updated to account for empty strings in children that the compiler merges. Pull Request resolved: https://github.com/facebook/prepack/pull/2560 Differential Revision: D10008375 Pulled By: trueadm fbshipit-source-id: 3b39a3e6387e23e17532a2343bd84ebebb7ee9cd
This commit is contained in:
parent
465b8defba
commit
0e52d02190
@ -14,7 +14,15 @@
|
|||||||
// security holes in the string escaping because of this.
|
// security holes in the string escaping because of this.
|
||||||
|
|
||||||
import type { Realm } from "../../realm.js";
|
import type { Realm } from "../../realm.js";
|
||||||
import { AbstractValue, BooleanValue, FunctionValue, NumberValue, SymbolValue, Value } from "../../values/index.js";
|
import {
|
||||||
|
AbstractValue,
|
||||||
|
BooleanValue,
|
||||||
|
FunctionValue,
|
||||||
|
NumberValue,
|
||||||
|
StringValue,
|
||||||
|
SymbolValue,
|
||||||
|
Value,
|
||||||
|
} from "../../values/index.js";
|
||||||
import invariant from "../../invariant.js";
|
import invariant from "../../invariant.js";
|
||||||
|
|
||||||
type PropertyType = 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
type PropertyType = 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
||||||
@ -389,12 +397,12 @@ export function shouldRemoveAttribute(
|
|||||||
}
|
}
|
||||||
return invariant(false, "TODO");
|
return invariant(false, "TODO");
|
||||||
case NUMERIC:
|
case NUMERIC:
|
||||||
if (value instanceof NumberValue) {
|
if (value instanceof NumberValue || value instanceof StringValue) {
|
||||||
return isNaN(value.value);
|
return isNaN(value.value);
|
||||||
}
|
}
|
||||||
return invariant(false, "TODO");
|
return invariant(false, "TODO");
|
||||||
case POSITIVE_NUMERIC:
|
case POSITIVE_NUMERIC:
|
||||||
if (value instanceof NumberValue) {
|
if (value instanceof NumberValue || value instanceof StringValue) {
|
||||||
return isNaN(value.value) || (value.value: any) < 1;
|
return isNaN(value.value) || (value.value: any) < 1;
|
||||||
}
|
}
|
||||||
return invariant(false, "TODO");
|
return invariant(false, "TODO");
|
||||||
|
@ -32,6 +32,7 @@ import {
|
|||||||
} from "../../values/index.js";
|
} from "../../values/index.js";
|
||||||
import { Reconciler } from "../reconcilation.js";
|
import { Reconciler } from "../reconcilation.js";
|
||||||
import {
|
import {
|
||||||
|
applyObjectAssignConfigsForReactElement,
|
||||||
createReactEvaluatedNode,
|
createReactEvaluatedNode,
|
||||||
forEachArrayValue,
|
forEachArrayValue,
|
||||||
getComponentName,
|
getComponentName,
|
||||||
@ -67,7 +68,7 @@ import {
|
|||||||
} from "./dom-config.js";
|
} from "./dom-config.js";
|
||||||
// $FlowFixMe: flow complains that this isn't a module but it is, and it seems to load fine
|
// $FlowFixMe: flow complains that this isn't a module but it is, and it seems to load fine
|
||||||
import hyphenateStyleName from "fbjs/lib/hyphenateStyleName";
|
import hyphenateStyleName from "fbjs/lib/hyphenateStyleName";
|
||||||
import { To } from "../../singletons.js";
|
import { Properties, To } from "../../singletons.js";
|
||||||
import { createOperationDescriptor } from "../../utils/generator.js";
|
import { createOperationDescriptor } from "../../utils/generator.js";
|
||||||
|
|
||||||
export type ReactNode = Array<ReactNode> | string | AbstractValue | ArrayValue;
|
export type ReactNode = Array<ReactNode> | string | AbstractValue | ArrayValue;
|
||||||
@ -139,12 +140,14 @@ function createMarkupForProperty(
|
|||||||
const { type } = propertyInfo;
|
const { type } = propertyInfo;
|
||||||
if (type === BOOLEAN || (type === OVERLOADED_BOOLEAN && value === true)) {
|
if (type === BOOLEAN || (type === OVERLOADED_BOOLEAN && value === true)) {
|
||||||
return attributeName + '=""';
|
return attributeName + '=""';
|
||||||
} else if (value instanceof StringValue || value instanceof NumberValue) {
|
} else if (value instanceof StringValue || value instanceof NumberValue || value instanceof BooleanValue) {
|
||||||
|
// $FlowFixMe: Flow complains about booleans being converted to strings, which is the intention
|
||||||
return attributeName + "=" + quoteAttributeValueForBrowser(value.value + "");
|
return attributeName + "=" + quoteAttributeValueForBrowser(value.value + "");
|
||||||
} else if (value instanceof AbstractValue) {
|
} else if (value instanceof AbstractValue) {
|
||||||
return ([attributeName + "=", renderValueWithHelper(realm, value, htmlEscapeHelper)]: Array<ReactNode>);
|
return ([attributeName + "=", renderValueWithHelper(realm, value, htmlEscapeHelper)]: Array<ReactNode>);
|
||||||
}
|
}
|
||||||
} else if (value instanceof StringValue || value instanceof NumberValue) {
|
} else if (value instanceof StringValue || value instanceof NumberValue || value instanceof BooleanValue) {
|
||||||
|
// $FlowFixMe: Flow complains about booleans being converted to strings, which is the intention
|
||||||
return name + "=" + quoteAttributeValueForBrowser(value.value + "");
|
return name + "=" + quoteAttributeValueForBrowser(value.value + "");
|
||||||
} else if (value instanceof AbstractValue) {
|
} else if (value instanceof AbstractValue) {
|
||||||
return ([name + '="', renderValueWithHelper(realm, value, htmlEscapeHelper), '"']: Array<ReactNode>);
|
return ([name + '="', renderValueWithHelper(realm, value, htmlEscapeHelper), '"']: Array<ReactNode>);
|
||||||
@ -393,9 +396,46 @@ class ReactDOMServerRenderer {
|
|||||||
let tag = type.toLowerCase();
|
let tag = type.toLowerCase();
|
||||||
|
|
||||||
if (tag === "input") {
|
if (tag === "input") {
|
||||||
invariant(false, "TODO");
|
let defaultValueProp = getProperty(this.realm, propsValue, "defaultValue");
|
||||||
|
let defaultCheckedProp = getProperty(this.realm, propsValue, "defaultChecked");
|
||||||
|
let valueProp = getProperty(this.realm, propsValue, "value");
|
||||||
|
let checkedProp = getProperty(this.realm, propsValue, "checked");
|
||||||
|
|
||||||
|
let newProps = new ObjectValue(this.realm, this.realm.intrinsics.ObjectPrototype);
|
||||||
|
Properties.Set(this.realm, newProps, "type", this.realm.intrinsics.undefined, true);
|
||||||
|
|
||||||
|
let inputProps = new ObjectValue(this.realm, this.realm.intrinsics.ObjectPrototype);
|
||||||
|
Properties.Set(this.realm, inputProps, "defaultChecked", this.realm.intrinsics.undefined, true);
|
||||||
|
Properties.Set(this.realm, inputProps, "defaultValue", this.realm.intrinsics.undefined, true);
|
||||||
|
Properties.Set(
|
||||||
|
this.realm,
|
||||||
|
inputProps,
|
||||||
|
"value",
|
||||||
|
valueProp !== this.realm.intrinsics.null ? valueProp : defaultValueProp,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
Properties.Set(
|
||||||
|
this.realm,
|
||||||
|
inputProps,
|
||||||
|
"checked",
|
||||||
|
checkedProp !== this.realm.intrinsics.null ? checkedProp : defaultCheckedProp,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
applyObjectAssignConfigsForReactElement(this.realm, newProps, [propsValue, inputProps]);
|
||||||
|
propsValue = newProps;
|
||||||
} else if (tag === "textarea") {
|
} else if (tag === "textarea") {
|
||||||
invariant(false, "TODO");
|
let initialValue = getProperty(this.realm, propsValue, "value");
|
||||||
|
|
||||||
|
if (initialValue === this.realm.intrinsics.null) {
|
||||||
|
invariant(false, "TODO");
|
||||||
|
}
|
||||||
|
|
||||||
|
let newProps = new ObjectValue(this.realm, this.realm.intrinsics.ObjectPrototype);
|
||||||
|
let textareaProps = new ObjectValue(this.realm, this.realm.intrinsics.ObjectPrototype);
|
||||||
|
Properties.Set(this.realm, textareaProps, "value", this.realm.intrinsics.undefined, true);
|
||||||
|
Properties.Set(this.realm, textareaProps, "children", initialValue, true);
|
||||||
|
applyObjectAssignConfigsForReactElement(this.realm, newProps, [propsValue, textareaProps]);
|
||||||
|
propsValue = newProps;
|
||||||
} else if (tag === "select") {
|
} else if (tag === "select") {
|
||||||
invariant(false, "TODO");
|
invariant(false, "TODO");
|
||||||
} else if (tag === "option") {
|
} else if (tag === "option") {
|
||||||
|
@ -37,14 +37,14 @@ export function mergeAdjacentJSONTextNodes(node: JSON, removeFunctions: boolean,
|
|||||||
concatString = child;
|
concatString = child;
|
||||||
}
|
}
|
||||||
} else if (typeof child === "object" && child !== null) {
|
} else if (typeof child === "object" && child !== null) {
|
||||||
if (concatString !== null) {
|
if (concatString !== null && concatString !== "") {
|
||||||
arr.push(concatString);
|
arr.push(concatString);
|
||||||
concatString = null;
|
concatString = null;
|
||||||
}
|
}
|
||||||
arr.push(((mergeAdjacentJSONTextNodes(child, removeFunctions, visitedNodes): any): JSON));
|
arr.push(((mergeAdjacentJSONTextNodes(child, removeFunctions, visitedNodes): any): JSON));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (concatString !== null) {
|
if (concatString !== null && concatString !== "") {
|
||||||
arr.push(concatString);
|
arr.push(concatString);
|
||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
|
@ -147,3 +147,7 @@ it("Hacker News app", () => {
|
|||||||
it("Function bind", () => {
|
it("Function bind", () => {
|
||||||
runTest(__dirname + "/FBMocks/function-bind.js");
|
runTest(__dirname + "/FBMocks/function-bind.js");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("PE Functional Components benchmark", () => {
|
||||||
|
runTest(__dirname + "/FBMocks/pe-functional-benchmark.js");
|
||||||
|
});
|
||||||
|
4767
test/react/FBMocks/pe-functional-benchmark.js
Normal file
4767
test/react/FBMocks/pe-functional-benchmark.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -20,3 +20,7 @@ it("Hacker News app", () => {
|
|||||||
let data = JSON.parse(fs.readFileSync(__dirname + "/ServerRendering/hacker-news.json").toString());
|
let data = JSON.parse(fs.readFileSync(__dirname + "/ServerRendering/hacker-news.json").toString());
|
||||||
runTest(__dirname + "/ServerRendering/hacker-news.js", { data });
|
runTest(__dirname + "/ServerRendering/hacker-news.js", { data });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("PE Functional Components benchmark", () => {
|
||||||
|
runTest(__dirname + "/ServerRendering/pe-functional-benchmark.js");
|
||||||
|
});
|
||||||
|
4792
test/react/ServerRendering/pe-functional-benchmark.js
Normal file
4792
test/react/ServerRendering/pe-functional-benchmark.js
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -39,3 +39,43 @@ ReactStatistics {
|
|||||||
"optimizedTrees": 0,
|
"optimizedTrees": 0,
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`PE Functional Components benchmark: (JSX => JSX) 1`] = `
|
||||||
|
ReactStatistics {
|
||||||
|
"componentsEvaluated": 0,
|
||||||
|
"evaluatedRootNodes": Array [],
|
||||||
|
"inlinedComponents": 0,
|
||||||
|
"optimizedNestedClosures": 0,
|
||||||
|
"optimizedTrees": 0,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`PE Functional Components benchmark: (JSX => createElement) 1`] = `
|
||||||
|
ReactStatistics {
|
||||||
|
"componentsEvaluated": 0,
|
||||||
|
"evaluatedRootNodes": Array [],
|
||||||
|
"inlinedComponents": 0,
|
||||||
|
"optimizedNestedClosures": 0,
|
||||||
|
"optimizedTrees": 0,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`PE Functional Components benchmark: (createElement => JSX) 1`] = `
|
||||||
|
ReactStatistics {
|
||||||
|
"componentsEvaluated": 0,
|
||||||
|
"evaluatedRootNodes": Array [],
|
||||||
|
"inlinedComponents": 0,
|
||||||
|
"optimizedNestedClosures": 0,
|
||||||
|
"optimizedTrees": 0,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`PE Functional Components benchmark: (createElement => createElement) 1`] = `
|
||||||
|
ReactStatistics {
|
||||||
|
"componentsEvaluated": 0,
|
||||||
|
"evaluatedRootNodes": Array [],
|
||||||
|
"inlinedComponents": 0,
|
||||||
|
"optimizedNestedClosures": 0,
|
||||||
|
"optimizedTrees": 0,
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
Loading…
Reference in New Issue
Block a user