From 153660fe7b8f476a9b9c277a1300e1379d6ca8c3 Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Mon, 20 Jul 2015 08:01:24 -0700 Subject: [PATCH] perf(dom): Only send values for existing properties to js interior Due to #3019 we have to check whether a property exists on a DOM element not before runtime of the application. Previously, we did this check in JavaScript, making all property values go through dart js interop. However, this is slow for complex objects. This commit changes this behavior to first check whether the property exists before sending the property value to the DOM element via js interop. Closes #3149 --- modules/angular2/src/dom/browser_adapter.dart | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/modules/angular2/src/dom/browser_adapter.dart b/modules/angular2/src/dom/browser_adapter.dart index 4d96efdeb5..0f4cc83298 100644 --- a/modules/angular2/src/dom/browser_adapter.dart +++ b/modules/angular2/src/dom/browser_adapter.dart @@ -98,9 +98,16 @@ final _keyCodeToKeyMap = const { class BrowserDomAdapter extends GenericBrowserDomAdapter { js.JsFunction _setProperty; js.JsFunction _getProperty; + js.JsFunction _hasProperty; + Map _hasPropertyCache; BrowserDomAdapter() { - _setProperty = js.context.callMethod('eval', ['(function(el, prop, value) { if (prop in el) el[prop] = value; })']); - _getProperty = js.context.callMethod('eval', ['(function(el, prop) { return el[prop]; })']); + _hasPropertyCache = new Map(); + _setProperty = js.context.callMethod( + 'eval', ['(function(el, prop, value) { el[prop] = value; })']); + _getProperty = js.context.callMethod( + 'eval', ['(function(el, prop) { return el[prop]; })']); + _hasProperty = js.context.callMethod( + 'eval', ['(function(el, prop) { return prop in el; })']); } static void makeCurrent() { setRootDomAdapter(new BrowserDomAdapter()); @@ -112,8 +119,17 @@ class BrowserDomAdapter extends GenericBrowserDomAdapter { return true; } - void setProperty(Element element, String name, Object value) => + void setProperty(Element element, String name, Object value) { + var cacheKey = "${element.tagName}.${name}"; + var hasProperty = this._hasPropertyCache[cacheKey]; + if (hasProperty == null) { + hasProperty = this._hasProperty.apply([element, name]); + this._hasPropertyCache[cacheKey] = hasProperty; + } + if (hasProperty) { _setProperty.apply([element, name, value]); + } + } getProperty(Element element, String name) => _getProperty.apply([element, name]);