From 7bf4b155a777ae20958c8a45395a7e3fc4ea9e94 Mon Sep 17 00:00:00 2001 From: Kevin Ngo Date: Tue, 16 Oct 2018 04:40:59 -0700 Subject: [PATCH] remove object allocation in update of single property of multi-prop component --- src/core/a-entity.js | 91 ++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/src/core/a-entity.js b/src/core/a-entity.js index d0b0997cf9d..37361a200a4 100644 --- a/src/core/a-entity.js +++ b/src/core/a-entity.js @@ -622,52 +622,59 @@ var proto = Object.create(ANode.prototype, { * it is a boolean indicating whether to clobber previous values (defaults to false). */ setAttribute: { - value: function (attrName, arg1, arg2) { - var newAttrValue; - var clobber; - var componentName; - var delimiterIndex; - var isDebugMode; - - delimiterIndex = attrName.indexOf(MULTIPLE_COMPONENT_DELIMITER); - componentName = delimiterIndex > 0 ? attrName.substring(0, delimiterIndex) : attrName; - - // Not a component. Normal set attribute. - if (!COMPONENTS[componentName]) { - if (attrName === 'mixin') { this.mixinUpdate(arg1); } - ANode.prototype.setAttribute.call(this, attrName, arg1); - return; - } + value: (function () { + var singlePropUpdate = {}; + + return function (attrName, arg1, arg2) { + var newAttrValue; + var clobber; + var componentName; + var delimiterIndex; + var isDebugMode; + var key; + + delimiterIndex = attrName.indexOf(MULTIPLE_COMPONENT_DELIMITER); + componentName = delimiterIndex > 0 ? attrName.substring(0, delimiterIndex) : attrName; + + // Not a component. Normal set attribute. + if (!COMPONENTS[componentName]) { + if (attrName === 'mixin') { this.mixinUpdate(arg1); } + ANode.prototype.setAttribute.call(this, attrName, arg1); + return; + } - // Initialize component first if not yet initialized. - if (!this.components[attrName] && this.hasAttribute(attrName)) { - this.updateComponent(attrName, - window.HTMLElement.prototype.getAttribute.call(this, attrName)); - } + // Initialize component first if not yet initialized. + if (!this.components[attrName] && this.hasAttribute(attrName)) { + this.updateComponent( + attrName, + window.HTMLElement.prototype.getAttribute.call(this, attrName)); + } - // Determine new attributes from the arguments - if (typeof arg2 !== 'undefined' && - typeof arg1 === 'string' && - arg1.length > 0 && - typeof utils.styleParser.parse(arg1) === 'string') { - // Update a single property of a multi-property component - newAttrValue = {}; - newAttrValue[arg1] = arg2; - clobber = false; - } else { - // Update with a value, object, or CSS-style property string, with the possiblity - // of clobbering previous values. - newAttrValue = arg1; - clobber = (arg2 === true); - } + // Determine new attributes from the arguments + if (typeof arg2 !== 'undefined' && + typeof arg1 === 'string' && + arg1.length > 0 && + typeof utils.styleParser.parse(arg1) === 'string') { + // Update a single property of a multi-property component + for (key in singlePropUpdate) { delete singlePropUpdate[key]; } + newAttrValue = singlePropUpdate; + newAttrValue[arg1] = arg2; + clobber = false; + } else { + // Update with a value, object, or CSS-style property string, with the possiblity + // of clobbering previous values. + newAttrValue = arg1; + clobber = (arg2 === true); + } - // Update component - this.updateComponent(attrName, newAttrValue, clobber); + // Update component + this.updateComponent(attrName, newAttrValue, clobber); - // In debug mode, write component data up to the DOM. - isDebugMode = this.sceneEl && this.sceneEl.getAttribute('debug'); - if (isDebugMode) { this.components[attrName].flushToDOM(); } - }, + // In debug mode, write component data up to the DOM. + isDebugMode = this.sceneEl && this.sceneEl.getAttribute('debug'); + if (isDebugMode) { this.components[attrName].flushToDOM(); } + }; + })(), writable: window.debug },