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
This commit is contained in:
Tobias Bosch 2015-07-20 08:01:24 -07:00
parent 3dd05ef7db
commit 153660fe7b
1 changed files with 19 additions and 3 deletions

View File

@ -98,9 +98,16 @@ final _keyCodeToKeyMap = const {
class BrowserDomAdapter extends GenericBrowserDomAdapter {
js.JsFunction _setProperty;
js.JsFunction _getProperty;
js.JsFunction _hasProperty;
Map<String, bool> _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]);