Skip to content

Commit

Permalink
perf: misc improvements (#1535)
Browse files Browse the repository at this point in the history
* perf: attr & escape helper optimization

* perf: optimize server component

* perf: dynamic tag perf improvements

* perf: prevent escaping json attrs, optimize nonce

* perf: legacy widget & dynamic tag key serialization improvement

* perf: prevent serializing component props for legacy components

* fix: auto key regexp for dynamic tag

* perf: prevent creating constructors for implicit components

(cherry picked from commit ff82248)
  • Loading branch information
DylanPiercey committed Apr 13, 2020
1 parent 097f41e commit 6cea32f
Show file tree
Hide file tree
Showing 21 changed files with 213 additions and 197 deletions.
6 changes: 1 addition & 5 deletions packages/marko/src/runtime/compiler.browser.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
{
"dependencies": [
"require: ./*.js",
"require: ./vdom/*.js",
"require-run: ./components/legacy/dependencies/vdom"
]
"dependencies": ["require: ./*.js", "require: ./vdom/*.js"]
}
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 @@ -187,7 +187,6 @@ function Component(id) {
this.___dirty = false;
this.___settingInput = false;
this.___document = undefined;
this.___keySequence = undefined;

var ssrKeyedElements = keyedElementsByComponentId[id];

Expand Down
9 changes: 4 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 state = extra.s;
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
34 changes: 14 additions & 20 deletions packages/marko/src/runtime/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ function addComponentsFromContext(componentsContext, componentsToHydrate) {
var id = componentDef.id;
var component = componentDef.___component;
var flags = componentDef.___flags;

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;

var hasProps = false;

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;
Expand All @@ -44,17 +45,11 @@ function addComponentsFromContext(componentsContext, componentsToHydrate) {
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];
const componentKeys = Object.keys(component);
for (let i = componentKeys.length; i--; ) {
const componentKey = componentKeys[i];

if (component[key] !== undefined) {
if (component[componentKey] !== undefined) {
hasProps = true;
break;
}
Expand All @@ -66,16 +61,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 @@ -87,7 +81,7 @@ function addComponentsFromContext(componentsContext, componentsToHydrate) {
e: customEvents,
f: flags ? flags : undefined,
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
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.t;
var isSplit = componentProps.s === true;
var isImplicitComponent = componentProps.i === 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;
}
};
};

0 comments on commit 6cea32f

Please sign in to comment.