Skip to content

Commit 153660f

Browse files
committed
perf(dom): Only send values for existing properties to js interior
Due to angular#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 angular#3149
1 parent 3dd05ef commit 153660f

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

modules/angular2/src/dom/browser_adapter.dart

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,16 @@ final _keyCodeToKeyMap = const {
9898
class BrowserDomAdapter extends GenericBrowserDomAdapter {
9999
js.JsFunction _setProperty;
100100
js.JsFunction _getProperty;
101+
js.JsFunction _hasProperty;
102+
Map<String, bool> _hasPropertyCache;
101103
BrowserDomAdapter() {
102-
_setProperty = js.context.callMethod('eval', ['(function(el, prop, value) { if (prop in el) el[prop] = value; })']);
103-
_getProperty = js.context.callMethod('eval', ['(function(el, prop) { return el[prop]; })']);
104+
_hasPropertyCache = new Map();
105+
_setProperty = js.context.callMethod(
106+
'eval', ['(function(el, prop, value) { el[prop] = value; })']);
107+
_getProperty = js.context.callMethod(
108+
'eval', ['(function(el, prop) { return el[prop]; })']);
109+
_hasProperty = js.context.callMethod(
110+
'eval', ['(function(el, prop) { return prop in el; })']);
104111
}
105112
static void makeCurrent() {
106113
setRootDomAdapter(new BrowserDomAdapter());
@@ -112,8 +119,17 @@ class BrowserDomAdapter extends GenericBrowserDomAdapter {
112119
return true;
113120
}
114121

115-
void setProperty(Element element, String name, Object value) =>
122+
void setProperty(Element element, String name, Object value) {
123+
var cacheKey = "${element.tagName}.${name}";
124+
var hasProperty = this._hasPropertyCache[cacheKey];
125+
if (hasProperty == null) {
126+
hasProperty = this._hasProperty.apply([element, name]);
127+
this._hasPropertyCache[cacheKey] = hasProperty;
128+
}
129+
if (hasProperty) {
116130
_setProperty.apply([element, name, value]);
131+
}
132+
}
117133

118134
getProperty(Element element, String name) =>
119135
_getProperty.apply([element, name]);

0 commit comments

Comments
 (0)