Skip to content
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

Misc perf improvements #1535

Merged
merged 14 commits into from
Mar 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"use strict";

var attr = require("../../../../runtime/html/helpers/attr");
var escapeXmlAttr = require("../../../../runtime/html/helpers/escape-xml").d;
var escapeDoubleQuotes = require("../../../../runtime/html/helpers/escape-xml")
.d;

function isStringLiteral(node) {
return node.type === "Literal" && typeof node.value === "string";
Expand Down Expand Up @@ -75,7 +76,7 @@ function generateCodeForExpressionAttr(name, value, escape, codegen) {
for (let i = 0; i < flattenedConcats.length; i++) {
var part = flattenedConcats[i];
if (isStringLiteral(part)) {
part.value = escapeXmlAttr(part.value);
part.value = escapeDoubleQuotes(part.value);
} else if (part.type !== "Literal") {
if (isNoEscapeXml(part)) {
part = codegen.builder.functionCall(context.helper("str"), [part]);
Expand Down
1 change: 0 additions & 1 deletion packages/marko/src/runtime/components/Component.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ function Component(id) {
this.___dirty = false;
this.___settingInput = false;
this.___document = undefined;
this.___keySequence = undefined;

var ssrKeyedElements = keyedElementsByComponentId[id];

Expand Down
14 changes: 9 additions & 5 deletions packages/marko/src/runtime/components/ComponentDef.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,14 @@ function ComponentDef(component, componentId, componentsContext) {
this.___flags = 0;

this.___nextIdIndex = 0; // The unique integer to use for the next scoped ID

this.___keySequence = null;
}

ComponentDef.prototype = {
___nextKey: function(key) {
var keySequence =
this.___keySequence || (this.___keySequence = new KeySequence());
return keySequence.___nextKey(key);
return (
this.___keySequence || (this.___keySequence = new KeySequence())
).___nextKey(key);
},

/**
Expand Down Expand Up @@ -90,7 +89,7 @@ ComponentDef.prototype.nk = ComponentDef.prototype.___nextKey;
ComponentDef.___deserialize = function(o, types, global, registry) {
var id = o[0];
var typeName = types[o[1]];
var input = o[2];
var input = o[2] || null;
var extra = o[3];

var isLegacy = extra.l;
Expand Down Expand Up @@ -133,6 +132,11 @@ ComponentDef.___deserialize = function(o, types, global, registry) {
if (componentProps) {
extend(component, componentProps);
}

if (isLegacy) {
component.widgetConfig = extra.c;
component.___legacyBody = extra.a;
}
}

component.___input = input;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
var nextComponentIdProvider = require("./util").___nextComponentIdProvider;
var KeySequence = require("./KeySequence");

function GlobalComponentsContext(out) {
this.___renderedComponentsById = {};
this.___rerenderComponent = undefined;
this.___nextComponentId = nextComponentIdProvider(out);
}

GlobalComponentsContext.prototype = {
___createKeySequence: function() {
return new KeySequence();
}
};

module.exports = GlobalComponentsContext;
25 changes: 8 additions & 17 deletions packages/marko/src/runtime/components/KeySequence.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
function KeySequence() {
this.___lookup = {};
this.___lookup = Object.create(null);
}

KeySequence.prototype = {
___nextKey: function(key) {
// var len = key.length;
// var lastChar = key[len-1];
// if (lastChar === ']') {
// key = key.substring(0, len-2);
// }
var lookup = this.___lookup;
KeySequence.prototype.___nextKey = function(key) {
var lookup = this.___lookup;

var currentIndex = lookup[key]++;
if (!currentIndex) {
lookup[key] = 1;
currentIndex = 0;
return key;
} else {
return key + "_" + currentIndex;
}
if (lookup[key]) {
return key + "_" + lookup[key]++;
}

lookup[key] = 1;
return key;
};

module.exports = KeySequence;
30 changes: 9 additions & 21 deletions packages/marko/src/runtime/components/ServerComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,16 @@ class ServerComponent {
this.id = id;
this.___customEvents = customEvents;
this.___scope = scope;
this.___updatedInput = undefined;
this.___input = undefined;
this.___state = undefined;
this.typeName = typeName;
this.___bubblingDomEvents = undefined; // Used to keep track of bubbling DOM events for components rendered on the server
this.___bubblingDomEventsExtraArgsCount = 0;

if (this.onCreate !== undefined) {
this.onCreate(input, out);
}

if (this.onInput !== undefined) {
var updatedInput = this.onInput(input, out) || input;

if (this.___input === undefined) {
this.___input = updatedInput;
}

this.___updatedInput = updatedInput;
} else {
this.___input = this.___updatedInput = input;
}

if (this.onRender !== undefined) {
this.onRender(out);
this.onCreate(input, out);
this.___updatedInput = this.onInput(input, out) || input;
if (this.___input === undefined) {
this.___input = this.___updatedInput;
}
this.onRender(out);
}

set input(newInput) {
Expand Down Expand Up @@ -77,6 +61,10 @@ class ServerComponent {
return id + "-" + nestedId;
}
}

onCreate() {}
onInput() {}
onRender() {}
}

ServerComponent.prototype.getElId = ServerComponent.prototype.elId;
Expand Down
16 changes: 1 addition & 15 deletions packages/marko/src/runtime/components/dom-data.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,4 @@
var counter = 0;
var seed = "M" + Math.random().toFixed(5);
var WeakMap =
global.WeakMap ||
function WeakMap() {
var id = seed + counter++;
return {
get: function(ref) {
return ref[id];
},
set: function(ref, value) {
ref[id] = value;
}
};
};
var WeakMap = require("../helpers/_weak-map");

module.exports = {
___vPropsByDOMNode: new WeakMap(),
Expand Down
67 changes: 35 additions & 32 deletions packages/marko/src/runtime/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,38 +25,37 @@ function addComponentsFromContext(componentsContext, componentsToHydrate) {
var id = componentDef.id;
var component = componentDef.___component;
var flags = componentDef.___flags;
var isLegacy = componentDef.___isLegacy;

var state = component.state;
var input = component.input;
var input = component.input || 0;
var typeName = component.typeName;
var customEvents = component.___customEvents;
var scope = component.___scope;
var bubblingDomEvents = component.___bubblingDomEvents;

component.___state = undefined; // We don't use `delete` to avoid V8 deoptimization
component.___input = undefined; // We don't use `delete` to avoid V8 deoptimization
component.typeName = undefined;
component.id = undefined;
component.___customEvents = undefined;
component.___scope = undefined;
component.___bubblingDomEvents = undefined;
component.___bubblingDomEventsExtraArgsCount = undefined;
component.___updatedInput = undefined;
component.___updateQueued = undefined;

if (!typeName) {
continue;
}

var hasProps = false;

let componentKeys = Object.keys(component);
for (let i = 0, len = componentKeys.length; i < len; i++) {
let key = componentKeys[i];

if (component[key] !== undefined) {
hasProps = true;
break;
if (!isLegacy) {
component.___state = undefined; // We don't use `delete` to avoid V8 deoptimization
component.___input = undefined; // We don't use `delete` to avoid V8 deoptimization
component.typeName = undefined;
component.id = undefined;
component.___customEvents = undefined;
component.___scope = undefined;
component.___bubblingDomEvents = undefined;
component.___bubblingDomEventsExtraArgsCount = undefined;
component.___updatedInput = undefined;
component.___updateQueued = undefined;

const componentKeys = Object.keys(component);
for (let i = componentKeys.length; i--; ) {
const componentKey = componentKeys[i];

if (component[componentKey] !== undefined) {
hasProps = true;
break;
}
}
}

Expand All @@ -66,16 +65,15 @@ function addComponentsFromContext(componentsContext, componentsToHydrate) {
// Update state properties with an `undefined` value to have a `null`
// value so that the property name will be serialized down to the browser.
// This ensures that we add the proper getter/setter for the state property.
const stateKeys = Object.keys(state);
for (let i = stateKeys.length; i--; ) {
const stateKey = stateKeys[i];

let stateKeys = Object.keys(state);
for (let i = 0, len = stateKeys.length; i < len; i++) {
let key = stateKeys[i];

if (state[key] === undefined) {
if (state[stateKey] === undefined) {
if (undefinedPropNames) {
undefinedPropNames.push(key);
undefinedPropNames.push(stateKey);
} else {
undefinedPropNames = [key];
undefinedPropNames = [stateKey];
}
}
}
Expand All @@ -86,14 +84,19 @@ function addComponentsFromContext(componentsContext, componentsToHydrate) {
d: componentDef.___domEvents,
e: customEvents,
f: flags ? flags : undefined,
l: componentDef.___isLegacy,
p: customEvents && scope, // Only serialize scope if we need to attach custom events
r: componentDef.___boundary,
r: componentDef.___boundary && 1,
s: state,
u: undefinedPropNames,
w: hasProps ? component : undefined
};

if (isLegacy) {
extra.l = 1;
extra.c = component.widgetConfig;
extra.a = component.___legacyBody;
}

componentsToHydrate.push([
id, // 0 = id
typeName, // 1 = type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function createRendererFunc(templateRenderFunc, componentProps) {
if (registry.___isServer && typeName) {
if (renderingLogic) delete renderingLogic.onRender;
component = registry.___createComponent(
renderingLogic || {},
renderingLogic,
id,
input,
out,
Expand Down
28 changes: 13 additions & 15 deletions packages/marko/src/runtime/components/registry.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict";
const copyProps = require("raptor-util/copyProps");
const SERVER_WIDGET_KEY = Symbol();
const constructorCache = new Map();
const BaseServerComponent = require("./ServerComponent");

function createServerComponentClass(renderingLogic) {
Expand All @@ -24,22 +24,20 @@ function createComponent(
customEvents,
scope
) {
var ServerComponent = renderingLogic[SERVER_WIDGET_KEY];
if (!ServerComponent) {
ServerComponent = renderingLogic[
SERVER_WIDGET_KEY
] = createServerComponentClass(renderingLogic);
let ServerComponent;

if (renderingLogic) {
ServerComponent = constructorCache.get(renderingLogic);

if (!ServerComponent) {
ServerComponent = createServerComponentClass(renderingLogic);
constructorCache.set(renderingLogic, ServerComponent);
}
} else {
ServerComponent = BaseServerComponent;
}

var component = new ServerComponent(
id,
input,
out,
typeName,
customEvents,
scope
);
return component;
return new ServerComponent(id, input, out, typeName, customEvents, scope);
}

exports.___isServer = true;
Expand Down
5 changes: 2 additions & 3 deletions packages/marko/src/runtime/components/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,12 @@ function createRendererFunc(
componentProps,
renderingLogic
) {
renderingLogic = renderingLogic || {};
var onInput = renderingLogic.onInput;
var onInput = renderingLogic && renderingLogic.onInput;
var typeName = componentProps.___type;
var isSplit = componentProps.___split === true;
var isImplicitComponent = componentProps.___implicit === true;

var shouldApplySplitMixins = isSplit;
var shouldApplySplitMixins = renderingLogic && isSplit;

return function renderer(input, out) {
trackAsyncComponents(out);
Expand Down
15 changes: 15 additions & 0 deletions packages/marko/src/runtime/helpers/_weak-map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
var counter = 0;
var seed = "M" + Math.random().toFixed(5);
module.exports =
global.WeakMap ||
function WeakMap() {
var id = seed + counter++;
return {
get: function(ref) {
return ref[id];
},
set: function(ref, value) {
ref[id] = value;
}
};
};