From 39b45c65c13f5842db0af0be1a7845a4486db50b Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Sat, 3 Oct 2015 23:11:09 -0700 Subject: [PATCH 1/3] Speed up margin/padding/border lookups --- src/Layout.js | 204 +++++++++++++++++++++++++++++++------------------- 1 file changed, 129 insertions(+), 75 deletions(-) diff --git a/src/Layout.js b/src/Layout.js index 0e98bdc6..d6256f3b 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -59,28 +59,6 @@ var computeLayout = (function() { 'column-reverse': 'height' }; - function capitalizeFirst(str) { - return str.charAt(0).toUpperCase() + str.slice(1); - } - - function getSpacing(node, type, suffix, locations) { - for (var i = 0; i < locations.length; ++i) { - var location = locations[i]; - - var key = type + capitalizeFirst(location) + suffix; - if (key in node.style) { - return node.style[key]; - } - - key = type + suffix; - if (key in node.style) { - return node.style[key]; - } - } - - return 0; - } - // When transpiled to Java / C the node type has layout, children and style // properties. For the JavaScript version this function adds these properties // if they don't already exist. @@ -107,24 +85,6 @@ var computeLayout = (function() { return node; } - function getPositiveSpacing(node, type, suffix, locations) { - for (var i = 0; i < locations.length; ++i) { - var location = locations[i]; - - var key = type + capitalizeFirst(location) + suffix; - if (key in node.style && node.style[key] >= 0) { - return node.style[key]; - } - - key = type + suffix; - if (key in node.style && node.style[key] >= 0) { - return node.style[key]; - } - } - - return 0; - } - function isUndefined(value) { return value === undefined; } @@ -139,60 +99,154 @@ var computeLayout = (function() { flexDirection === CSS_FLEX_DIRECTION_COLUMN_REVERSE; } - function getLeadingLocations(axis) { - var locations = [leading[axis]]; - if (isRowDirection(axis)) { - locations.unshift('start'); - } - - return locations; - } - - function getTrailingLocations(axis) { - var locations = [trailing[axis]]; - if (isRowDirection(axis)) { - locations.unshift('end'); - } - - return locations; - } - - function getMargin(node, locations) { - return getSpacing(node, 'margin', '', locations); - } - function getLeadingMargin(node, axis) { - return getMargin(node, getLeadingLocations(axis)); + if (node.style.marginStart != null && isRowDirection(axis)) { + return node.style.marginStart; + } + + var value = null; + switch (axis) { + case 'row': value = node.style.marginLeft; break; + case 'row-reverse': value = node.style.marginRight; break; + case 'column': value = node.style.marginTop; break; + case 'column-reverse': value = node.style.marginBottom; break; + } + + if (value != null) { + return value; + } + + if (node.style.margin != null) { + return node.style.margin; + } + + return 0; } function getTrailingMargin(node, axis) { - return getMargin(node, getTrailingLocations(axis)); - } + if (node.style.marginEnd != null && isRowDirection(axis)) { + return node.style.marginEnd; + } - function getPadding(node, locations) { - return getPositiveSpacing(node, 'padding', '', locations); + var value = null; + switch (axis) { + case 'row': value = node.style.marginRight; break; + case 'row-reverse': value = node.style.marginLeft; break; + case 'column': value = node.style.marginBottom; break; + case 'column-reverse': value = node.style.marginTop; break; + } + + if (value != null) { + return value; + } + + if (node.style.margin != null) { + return node.style.margin; + } + + return 0; } function getLeadingPadding(node, axis) { - return getPadding(node, getLeadingLocations(axis)); + if (node.style.paddingStart != null && node.style.paddingStart >= 0 + && isRowDirection(axis)) { + return node.style.paddingStart; + } + + var value = null; + switch (axis) { + case 'row': value = node.style.paddingLeft; break; + case 'row-reverse': value = node.style.paddingRight; break; + case 'column': value = node.style.paddingTop; break; + case 'column-reverse': value = node.style.paddingBottom; break; + } + + if (value != null && value >= 0) { + return value; + } + + if (node.style.padding != null && node.style.padding >= 0) { + return node.style.padding; + } + + return 0; } function getTrailingPadding(node, axis) { - return getPadding(node, getTrailingLocations(axis)); - } + if (node.style.paddingEnd != null && node.style.paddingEnd >= 0 + && isRowDirection(axis)) { + return node.style.paddingEnd; + } - function getBorder(node, locations) { - return getPositiveSpacing(node, 'border', 'Width', locations); + var value = null; + switch (axis) { + case 'row': value = node.style.paddingRight; break; + case 'row-reverse': value = node.style.paddingLeft; break; + case 'column': value = node.style.paddingBottom; break; + case 'column-reverse': value = node.style.paddingTop; break; + } + + if (value != null && value >= 0) { + return value; + } + + if (node.style.padding != null && node.style.padding >= 0) { + return node.style.padding; + } + + return 0; } function getLeadingBorder(node, axis) { - return getBorder(node, getLeadingLocations(axis)); + if (node.style.borderStartWidth != null && node.style.borderStartWidth >= 0 + && isRowDirection(axis)) { + return node.style.borderStartWidth; + } + + var value = null; + switch (axis) { + case 'row': value = node.style.borderLeftWidth; break; + case 'row-reverse': value = node.style.borderRightWidth; break; + case 'column': value = node.style.borderTopWidth; break; + case 'column-reverse': value = node.style.borderBottomWidth; break; + } + + if (value != null && value >= 0) { + return value; + } + + if (node.style.borderWidth != null && node.style.borderWidth >= 0) { + return node.style.borderWidth; + } + + return 0; } function getTrailingBorder(node, axis) { - return getBorder(node, getTrailingLocations(axis)); - } + if (node.style.borderEndWidth != null && node.style.borderEndWidth >= 0 + && isRowDirection(axis)) { + return node.style.borderEndWidth; + } + var value = null; + switch (axis) { + case 'row': value = node.style.borderRightWidth; break; + case 'row-reverse': value = node.style.borderLeftWidth; break; + case 'column': value = node.style.borderBottomWidth; break; + case 'column-reverse': value = node.style.borderTopWidth; break; + } + + if (value != null && value >= 0) { + return value; + } + + if (node.style.borderWidth != null && node.style.borderWidth >= 0) { + return node.style.borderWidth; + } + + return 0; + } + function getLeadingPaddingAndBorder(node, axis) { return getLeadingPadding(node, axis) + getLeadingBorder(node, axis); } From 0f5d3ae8f0c05e791699f266bb97341b59d43ef5 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Sat, 3 Oct 2015 23:13:33 -0700 Subject: [PATCH 2/3] Don't use the in operator --- src/Layout.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Layout.js b/src/Layout.js index d6256f3b..10745e33 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -269,24 +269,24 @@ var computeLayout = (function() { } function getJustifyContent(node) { - if ('justifyContent' in node.style) { + if (node.style.justifyContent) { return node.style.justifyContent; } return 'flex-start'; } function getAlignContent(node) { - if ('alignContent' in node.style) { + if (node.style.alignContent) { return node.style.alignContent; } return 'flex-start'; } function getAlignItem(node, child) { - if ('alignSelf' in child.style) { + if (child.style.alignSelf) { return child.style.alignSelf; } - if ('alignItems' in node.style) { + if (node.style.alignItems) { return node.style.alignItems; } return 'stretch'; @@ -306,7 +306,7 @@ var computeLayout = (function() { function resolveDirection(node, parentDirection) { var direction; - if ('direction' in node.style) { + if (node.style.direction) { direction = node.style.direction; } else { direction = CSS_DIRECTION_INHERIT; @@ -320,7 +320,7 @@ var computeLayout = (function() { } function getFlexDirection(node) { - if ('flexDirection' in node.style) { + if (node.style.flexDirection) { return node.style.flexDirection; } return CSS_FLEX_DIRECTION_COLUMN; @@ -335,7 +335,7 @@ var computeLayout = (function() { } function getPositionType(node) { - if ('position' in node.style) { + if (node.style.position) { return node.style.position; } return 'relative'; @@ -365,11 +365,11 @@ var computeLayout = (function() { } function isMeasureDefined(node) { - return 'measure' in node.style; + return node.style.measure != null; } function getPosition(node, pos) { - if (pos in node.style) { + if (node.style[pos] != null) { return node.style[pos]; } return 0; @@ -433,7 +433,7 @@ var computeLayout = (function() { // If both left and right are defined, then use left. Otherwise return // +left or -right depending on which is defined. function getRelativePosition(node, axis) { - if (leading[axis] in node.style) { + if (node.style[leading[axis]] != null) { return getPosition(node, leading[axis]); } return -getPosition(node, trailing[axis]); From 5af85c5ef6d311220d1e54a321a6b05721ecaa14 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Sat, 3 Oct 2015 23:14:04 -0700 Subject: [PATCH 3/3] Inline some isUndefined calls --- src/Layout.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Layout.js b/src/Layout.js index 10745e33..3b140373 100755 --- a/src/Layout.js +++ b/src/Layout.js @@ -357,11 +357,11 @@ var computeLayout = (function() { } function isDimDefined(node, axis) { - return !isUndefined(node.style[dim[axis]]) && node.style[dim[axis]] >= 0; + return node.style[dim[axis]] != null && node.style[dim[axis]] >= 0; } function isPosDefined(node, pos) { - return !isUndefined(node.style[pos]); + return node.style[pos] != null; } function isMeasureDefined(node) { @@ -391,10 +391,10 @@ var computeLayout = (function() { }[axis]; var boundValue = value; - if (!isUndefined(max) && max >= 0 && boundValue > max) { + if (max != null && max >= 0 && boundValue > max) { boundValue = max; } - if (!isUndefined(min) && min >= 0 && boundValue < min) { + if (min != null && min >= 0 && boundValue < min) { boundValue = min; } return boundValue; @@ -410,7 +410,7 @@ var computeLayout = (function() { // When the user specifically sets a value for width or height function setDimensionFromStyle(node, axis) { // The parent already computed us a width or height. We just skip it - if (!isUndefined(node.layout[dim[axis]])) { + if (node.layout[dim[axis]] != null) { return; } // We only run if there's a width or height defined