Skip to content

Commit

Permalink
perf: optimize serializing renderBody & legacy widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Apr 6, 2020
1 parent c958f49 commit 275e51a
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 45 deletions.
4 changes: 2 additions & 2 deletions packages/marko/src/runtime/components/Component.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ function checkInputChanged(existingComponent, oldInput, newInput) {
return true;
}

for (var i = 0; i < len; i++) {
for (var i = len; i--; ) {
var key = oldKeys[i];
if (oldInput[key] !== newInput[key]) {
if (!(key in newInput && oldInput[key] === newInput[key])) {
return true;
}
}
Expand Down
24 changes: 14 additions & 10 deletions packages/marko/src/runtime/components/ComponentDef.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
"use strict";
var complain = "MARKO_DEBUG" && require("complain");
var w10Noop = require("warp10/constants").NOOP;
var componentUtil = require("./util");
var attachBubblingEvent = componentUtil.___attachBubblingEvent;
var addDelegatedEventHandler = require("./event-delegation")
.___addDelegatedEventHandler;
var extend = require("raptor-util/extend");
var KeySequence = require("./KeySequence");
var EMPTY_OBJECT = {};

var FLAG_WILL_RERENDER_IN_BROWSER = 1;
// var FLAG_HAS_BODY_EL = 2;
// var FLAG_HAS_HEAD_EL = 4;
var FLAG_HAS_RENDER_BODY = 2;
var FLAG_IS_LEGACY = 4;
var FLAG_OLD_HYDRATE_NO_CREATE = 8;

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

var isLegacy = extra.l;
var state = extra.s;
var componentProps = extra.w;
var flags = extra.f;
var isLegacy = flags & FLAG_IS_LEGACY;
var renderBody = flags & FLAG_HAS_RENDER_BODY ? w10Noop : extra.r;

var component =
typeName /* legacy */ &&
Expand All @@ -105,6 +108,13 @@ ComponentDef.___deserialize = function(o, types, global, registry) {
// just building it from the server info
component.___updateQueued = true;

if (isLegacy) {
component.widgetConfig = componentProps;
component.___widgetBody = renderBody;
} else if (renderBody) {
input.renderBody = renderBody;
}

if (
!isLegacy &&
flags & FLAG_WILL_RERENDER_IN_BROWSER &&
Expand Down Expand Up @@ -132,11 +142,6 @@ 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 All @@ -156,7 +161,6 @@ ComponentDef.___deserialize = function(o, types, global, registry) {
return {
id: id,
___component: component,
___boundary: extra.r,
___domEvents: extra.d,
___flags: extra.f || 0
};
Expand Down
4 changes: 2 additions & 2 deletions packages/marko/src/runtime/components/beginComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
const ComponentDef = require("./ComponentDef");

var FLAG_WILL_RERENDER_IN_BROWSER = 1;
// var FLAG_HAS_BODY_EL = 2;
// var FLAG_HAS_HEAD_EL = 4;
// var FLAG_HAS_RENDER_BODY = 2;
// var FLAG_IS_LEGACY = 4;
var FLAG_OLD_HYDRATE_NO_CREATE = 8;

module.exports = function beginComponent(
Expand Down
69 changes: 46 additions & 23 deletions packages/marko/src/runtime/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
var warp10 = require("warp10");
var safeJSONRegExp = /<\/|\u2028|\u2029/g;

// var FLAG_WILL_RERENDER_IN_BROWSER = 1;
var FLAG_HAS_RENDER_BODY = 2;
var FLAG_IS_LEGACY = 4;
// var FLAG_OLD_HYDRATE_NO_CREATE = 8;

function safeJSONReplacer(match) {
if (match === "</") {
return "\\u003C/";
Expand All @@ -11,6 +16,17 @@ function safeJSONReplacer(match) {
}
}

function isNotEmpty(obj) {
var keys = Object.keys(obj);
for (var i = keys.length; i--;) {
if (obj[keys[i]] !== undefined) {
return true;
}
}

return false;
}

function safeJSON(json) {
return json.replace(safeJSONRegExp, safeJSONReplacer);
}
Expand All @@ -35,8 +51,17 @@ function addComponentsFromContext(componentsContext, componentsToHydrate) {
var bubblingDomEvents = component.___bubblingDomEvents;

var hasProps = false;
var renderBody;

if (isLegacy) {
flags |= FLAG_IS_LEGACY;
renderBody = component.___widgetBody;
} else {
if (input && input.renderBody) {
renderBody = input.renderBody;
input.renderBody = undefined;
}

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;
Expand All @@ -47,16 +72,7 @@ function addComponentsFromContext(componentsContext, componentsToHydrate) {
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;
}
}
hasProps = isNotEmpty(component);
}

var undefinedPropNames = undefined;
Expand All @@ -79,30 +95,37 @@ function addComponentsFromContext(componentsContext, componentsToHydrate) {
}
}

if (typeof renderBody === "function") {
flags |= FLAG_HAS_RENDER_BODY;
renderBody = undefined;
}

var extra = {
b: bubblingDomEvents,
d: componentDef.___domEvents,
e: customEvents,
f: flags ? flags : undefined,
p: customEvents && scope, // Only serialize scope if we need to attach custom events
r: componentDef.___boundary && 1,
s: state,
u: undefinedPropNames,
w: hasProps ? component : undefined
w: isLegacy ? component.widgetConfig : hasProps ? component : undefined,
r: renderBody
};

if (isLegacy) {
extra.l = 1;
extra.c = component.widgetConfig;
extra.a = component.___legacyBody;
var parts = [id, typeName];
var hasExtra = isNotEmpty(extra);

if (input) {
parts.push(input);

if (hasExtra) {
parts.push(extra);
}
} else if (hasExtra) {
parts.push(0, extra); // empty input;
}

componentsToHydrate.push([
id, // 0 = id
typeName, // 1 = type
input, // 2 = input
extra // 3
]);
componentsToHydrate.push(parts);
}

components.length = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ var serverRenderedGlobals = {};
var serverComponentRootNodes = {};

var FLAG_WILL_RERENDER_IN_BROWSER = 1;
// var FLAG_HAS_RENDER_BODY = 2;
// var FLAG_IS_LEGACY = 4;
// var FLAG_OLD_HYDRATE_NO_CREATE = 8;

function indexServerComponentBoundaries(node, runtimeId, stack) {
var componentId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ module.exports = function defineRenderer(renderingLogic) {
}
} else if (component) {
newProps = newProps || component.___widgetProps;
widgetBody = component.___legacyBody;
widgetBody = component.___widgetBody;
widgetState = component.___rawState;
widgetConfig = component.widgetConfig;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ var resolveComponentKey = modernRenderer.___resolveComponentKey;
var trackAsyncComponents = modernRenderer.___trackAsyncComponents;
var beginComponent = require("../beginComponent");
var endComponent = require("../endComponent");
var w10NOOP = require("warp10/constants").NOOP;
var complain = "MARKO_DEBUG" && require("complain");

function createRendererFunc(templateRenderFunc, componentProps) {
Expand Down Expand Up @@ -112,7 +111,7 @@ function createRendererFunc(templateRenderFunc, componentProps) {

component.state = widgetState;
component.widgetConfig = widgetConfig;
component.___legacyBody = widgetBody || component.___legacyBody || w10NOOP;
component.___widgetBody = widgetBody || component.___widgetBody;

var componentDef = beginComponent(
componentsContext,
Expand Down
5 changes: 3 additions & 2 deletions packages/marko/src/runtime/components/util.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var FLAG_WILL_RERENDER_IN_BROWSER = 1;
// var FLAG_HAS_BODY_EL = 2;
// var FLAG_HAS_HEAD_EL = 4;
// var FLAG_HAS_RENDER_BODY = 2;
// var FLAG_IS_LEGACY = 4;
// var FLAG_OLD_HYDRATE_NO_CREATE = 8;

function nextComponentIdProvider(out) {
var prefix = out.global.componentIdPrefix || out.global.widgetIdPrefix || "s"; // "s" is for server (we use "b" for the browser)
Expand Down
3 changes: 3 additions & 0 deletions packages/marko/src/runtime/helpers/dynamic-tag.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ var RENDER_BODY_TO_JSON = function() {

var autoKeyReg = /^\d[\d[\]]*$/;
var FLAG_WILL_RERENDER_IN_BROWSER = 1;
// var FLAG_HAS_RENDER_BODY = 2;
// var FLAG_IS_LEGACY = 4;
// var FLAG_OLD_HYDRATE_NO_CREATE = 8;
var IS_SERVER = typeof window === "undefined";

/**
Expand Down
5 changes: 3 additions & 2 deletions packages/marko/src/runtime/html/helpers/data-marko.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ var escapeQuoteHelpers = require("./escape-quotes");
var escapeSingleQuotes = escapeQuoteHelpers.___escapeSingleQuotes;
var escapeDoubleQuotes = escapeQuoteHelpers.___escapeDoubleQuotes;
var FLAG_WILL_RERENDER_IN_BROWSER = 1;
// var FLAG_HAS_BODY_EL = 2;
// var FLAG_HAS_HEAD_EL = 4;
// var FLAG_HAS_RENDER_BODY = 2;
// var FLAG_IS_LEGACY = 4;
// var FLAG_OLD_HYDRATE_NO_CREATE = 8;

module.exports = function dataMarko(props, key, componentDef) {
var result = "";
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<html><head>Components</head><body><!--M#s0-3--><div><h1>foo1</h1><div><h1>bar1</h1></div><div><h1>bar2</h1></div><div><h1>foo-split1</h1><div><h1>split-child1</h1></div><div><h1>split-child2</h1></div></div><div><h1>foo-split2</h1><div><h1>split-child1</h1></div><div><h1>split-child2</h1></div></div></div><!--M/--><!--M#s0-4--><div><h1>foo2</h1><div><h1>bar1</h1></div><div><h1>bar2</h1></div><div><h1>foo-split1</h1><div><h1>split-child1</h1></div><div><h1>split-child2</h1></div></div><div><h1>foo-split2</h1><div><h1>split-child1</h1></div><div><h1>split-child2</h1></div></div></div><!--M/--><!--M#s0-5--><div><h1>split1</h1><!--M^s0-5-split-child1 s0-5 split-child1--><div><h1>split-child1</h1></div><!--M/--><!--M^s0-5-split-child2 s0-5 split-child2--><div><h1>split-child2</h1></div><!--M/--></div><!--M/--><!--M#s0-6--><div><h1>split2</h1><!--M^s0-6-split-child1 s0-6 split-child1--><div><h1>split-child1</h1></div><!--M/--><!--M^s0-6-split-child2 s0-6 split-child2--><div><h1>split-child2</h1></div><!--M/--></div><!--M/--><script>$components=(window.$components||[]).concat({"r":"M","w":[["s0-3",0,{"name":"foo1"},{"f":1}],["s0-4",0,{"name":"foo2"},{"f":1}],["s0-5",1,{"name":"split1"},{}],["s0-5-split-child1",2,{"name":"split-child1"},{}],["s0-5-split-child2",2,{"name":"split-child2"},{}],["s0-6",1,{"name":"split2"},{}],["s0-6-split-child1",2,{"name":"split-child1"},{}],["s0-6-split-child2",2,{"name":"split-child2"},{}]],"t":["/marko-test$1.0.0/render/fixtures/components/components/foo/index.marko","/marko-test$1.0.0/render/fixtures/components/components/split/component-browser","/marko-test$1.0.0/render/fixtures/components/components/split/components/split-child/component-browser"]})||$components</script></body></html>
<html><head>Components</head><body><!--M#s0-3--><div><h1>foo1</h1><div><h1>bar1</h1></div><div><h1>bar2</h1></div><div><h1>foo-split1</h1><div><h1>split-child1</h1></div><div><h1>split-child2</h1></div></div><div><h1>foo-split2</h1><div><h1>split-child1</h1></div><div><h1>split-child2</h1></div></div></div><!--M/--><!--M#s0-4--><div><h1>foo2</h1><div><h1>bar1</h1></div><div><h1>bar2</h1></div><div><h1>foo-split1</h1><div><h1>split-child1</h1></div><div><h1>split-child2</h1></div></div><div><h1>foo-split2</h1><div><h1>split-child1</h1></div><div><h1>split-child2</h1></div></div></div><!--M/--><!--M#s0-5--><div><h1>split1</h1><!--M^s0-5-split-child1 s0-5 split-child1--><div><h1>split-child1</h1></div><!--M/--><!--M^s0-5-split-child2 s0-5 split-child2--><div><h1>split-child2</h1></div><!--M/--></div><!--M/--><!--M#s0-6--><div><h1>split2</h1><!--M^s0-6-split-child1 s0-6 split-child1--><div><h1>split-child1</h1></div><!--M/--><!--M^s0-6-split-child2 s0-6 split-child2--><div><h1>split-child2</h1></div><!--M/--></div><!--M/--><script>$components=(window.$components||[]).concat({"r":"M","w":[["s0-3",0,{"name":"foo1"},{"f":1}],["s0-4",0,{"name":"foo2"},{"f":1}],["s0-5",1,{"name":"split1"}],["s0-5-split-child1",2,{"name":"split-child1"}],["s0-5-split-child2",2,{"name":"split-child2"}],["s0-6",1,{"name":"split2"}],["s0-6-split-child1",2,{"name":"split-child1"}],["s0-6-split-child2",2,{"name":"split-child2"}]],"t":["/marko-test$1.0.0/render/fixtures/components/components/foo/index.marko","/marko-test$1.0.0/render/fixtures/components/components/split/component-browser","/marko-test$1.0.0/render/fixtures/components/components/split/components/split-child/component-browser"]})||$components</script></body></html>

0 comments on commit 275e51a

Please sign in to comment.