Skip to content

Commit

Permalink
perf: optimize serializing renderBody & legacy widgets (#1539)
Browse files Browse the repository at this point in the history
(cherry picked from commit 5a74012)
  • Loading branch information
DylanPiercey committed Apr 13, 2020
1 parent 792aa6a commit eb9e156
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 41 deletions.
4 changes: 2 additions & 2 deletions packages/marko/src/runtime/components/Component.js
Expand Up @@ -150,9 +150,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
19 changes: 10 additions & 9 deletions packages/marko/src/runtime/components/ComponentDef.js
@@ -1,16 +1,16 @@
"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_OLD_HYDRATE_NO_CREATE = 8;
var FLAG_HAS_RENDER_BODY = 2;

/**
* A ComponentDef is used to hold the metadata collected at runtime for
Expand Down Expand Up @@ -90,22 +90,24 @@ 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 state = extra.s;
var componentProps = extra.w;
var flags = extra.f;
var renderBody = flags & FLAG_HAS_RENDER_BODY ? w10Noop : extra.r;

var component = registry.___createComponent(typeName, id);

// Prevent newly created component from being queued for update since we area
// just building it from the server info
component.___updateQueued = true;

if (
flags & FLAG_WILL_RERENDER_IN_BROWSER &&
!(flags & FLAG_OLD_HYDRATE_NO_CREATE)
) {
if (renderBody) {
input.renderBody = renderBody;
}

if (flags & FLAG_WILL_RERENDER_IN_BROWSER) {
if (component.onCreate) {
component.onCreate(input, { global: global });
}
Expand Down Expand Up @@ -147,7 +149,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
8 changes: 1 addition & 7 deletions packages/marko/src/runtime/components/beginComponent.js
Expand Up @@ -3,9 +3,7 @@
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_OLD_HYDRATE_NO_CREATE = 8;
// var FLAG_HAS_RENDER_BODY = 2;

module.exports = function beginComponent(
componentsContext,
Expand Down Expand Up @@ -54,10 +52,6 @@ module.exports = function beginComponent(
componentsContext.___isPreserved = false;
}

if (out.global.oldHydrateNoCreate === true) {
componentDef.___flags |= FLAG_OLD_HYDRATE_NO_CREATE;
}

if ((ownerIsRenderBoundary || ownerWillRerender) && key != null) {
out.w(
"<!--" +
Expand Down
60 changes: 42 additions & 18 deletions packages/marko/src/runtime/components/index.js
Expand Up @@ -3,6 +3,9 @@
var warp10 = require("warp10");
var safeJSONRegExp = /<\/|\u2028|\u2029/g;

// var FLAG_WILL_RERENDER_IN_BROWSER = 1;
var FLAG_HAS_RENDER_BODY = 2;

function safeJSONReplacer(match) {
if (match === "</") {
return "\\u003C/";
Expand All @@ -11,6 +14,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 @@ -33,6 +47,12 @@ function addComponentsFromContext(componentsContext, componentsToHydrate) {
var bubblingDomEvents = component.___bubblingDomEvents;

var hasProps = false;
var renderBody;

if (input && input.renderBody) {
renderBody = input.renderBody;
input.renderBody = undefined;
}

component.___state = undefined; // We don't use `delete` to avoid V8 deoptimization
component.___input = undefined; // We don't use `delete` to avoid V8 deoptimization
Expand All @@ -44,16 +64,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 @@ -75,24 +86,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: hasProps ? component : undefined,
r: renderBody
};

componentsToHydrate.push([
id, // 0 = id
typeName, // 1 = type
input, // 2 = input
extra // 3
]);
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(parts);
}

components.length = 0;
Expand Down
Expand Up @@ -18,6 +18,7 @@ var serverRenderedGlobals = {};
var serverComponentRootNodes = {};

var FLAG_WILL_RERENDER_IN_BROWSER = 1;
// var FLAG_HAS_RENDER_BODY = 2;

function indexServerComponentBoundaries(node, runtimeId, stack) {
var componentId;
Expand Down
3 changes: 1 addition & 2 deletions packages/marko/src/runtime/components/util.js
@@ -1,6 +1,5 @@
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;

function nextComponentIdProvider(out) {
var prefix = out.global.componentIdPrefix || out.global.widgetIdPrefix || "s"; // "s" is for server (we use "b" for the browser)
Expand Down
1 change: 1 addition & 0 deletions packages/marko/src/runtime/helpers/dynamic-tag.js
Expand Up @@ -11,6 +11,7 @@ var RENDER_BODY_TO_JSON = function() {
};

var FLAG_WILL_RERENDER_IN_BROWSER = 1;
// var FLAG_HAS_RENDER_BODY = 2;
var IS_SERVER = typeof window === "undefined";

/**
Expand Down
3 changes: 1 addition & 2 deletions packages/marko/src/runtime/html/helpers/data-marko.js
Expand Up @@ -4,8 +4,7 @@ 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;

module.exports = function dataMarko(props, key, componentDef) {
var result = "";
Expand Down
@@ -1 +1 @@
<html><head>Components</head><body><!--M#s0-4--><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-5--><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-6--><div><h1>split1</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/--><!--M#s0-7--><div><h1>split2</h1><!--M^s0-7-@split-child1 s0-7 @split-child1--><div><h1>split-child1</h1></div><!--M/--><!--M^s0-7-@split-child2 s0-7 @split-child2--><div><h1>split-child2</h1></div><!--M/--></div><!--M/--><script>$components=(window.$components||[]).concat({"r":"M","w":[["s0-4",0,{"name":"foo1"},{"f":1}],["s0-5",0,{"name":"foo2"},{"f":1}],["s0-6",1,{"name":"split1"},{}],["s0-6-@split-child1",2,{"name":"split-child1"},{}],["s0-6-@split-child2",2,{"name":"split-child2"},{}],["s0-7",1,{"name":"split2"},{}],["s0-7-@split-child1",2,{"name":"split-child1"},{}],["s0-7-@split-child2",2,{"name":"split-child2"},{}]],"t":["EMljIY5B","30jLCJ__","IdzCtSbr"]})||$components</script></body></html>
<html><head>Components</head><body><!--M#s0-4--><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-5--><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-6--><div><h1>split1</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/--><!--M#s0-7--><div><h1>split2</h1><!--M^s0-7-@split-child1 s0-7 @split-child1--><div><h1>split-child1</h1></div><!--M/--><!--M^s0-7-@split-child2 s0-7 @split-child2--><div><h1>split-child2</h1></div><!--M/--></div><!--M/--><script>$components=(window.$components||[]).concat({"r":"M","w":[["s0-4",0,{"name":"foo1"},{"f":1}],["s0-5",0,{"name":"foo2"},{"f":1}],["s0-6",1,{"name":"split1"}],["s0-6-@split-child1",2,{"name":"split-child1"}],["s0-6-@split-child2",2,{"name":"split-child2"}],["s0-7",1,{"name":"split2"}],["s0-7-@split-child1",2,{"name":"split-child1"}],["s0-7-@split-child2",2,{"name":"split-child2"}]],"t":["EMljIY5B","30jLCJ__","IdzCtSbr"]})||$components</script></body></html>

0 comments on commit eb9e156

Please sign in to comment.