improve dom caching

- don't call appendChild if not needed
- don't overwrite style all the time
- don't overwrite function if it has same source
This commit is contained in:
Leo Horie 2014-04-03 09:00:47 -04:00
parent e34cc1fc4a
commit efae454bd4
5 changed files with 33 additions and 18 deletions

View file

@ -73,7 +73,7 @@ new function(window) {
setAttributes(node, data.attrs, cached.attrs) setAttributes(node, data.attrs, cached.attrs)
cached.children = build(node, data.children, cached.children) cached.children = build(node, data.children, cached.children)
cached.nodes.intact = true cached.nodes.intact = true
parent.appendChild(node) if (node.parentNode !== parent) parent.appendChild(node)
} }
if (type.call(data.attrs["config"]) == "[object Function]") data.attrs["config"](node, !isNew) if (type.call(data.attrs["config"]) == "[object Function]") data.attrs["config"](node, !isNew)
} }
@ -120,13 +120,20 @@ new function(window) {
function setAttributes(node, dataAttrs, cachedAttrs) { function setAttributes(node, dataAttrs, cachedAttrs) {
for (var attrName in dataAttrs) { for (var attrName in dataAttrs) {
var dataAttr = dataAttrs[attrName] var dataAttr = dataAttrs[attrName]
if (!(attrName in cachedAttrs) || (cachedAttrs[attrName] !== dataAttr) || node === window.document.activeElement) { var cachedAttr = cachedAttrs[attrName]
cachedAttrs[attrName] = dataAttr if (!(attrName in cachedAttrs) || (cachedAttr !== dataAttr) || node === window.document.activeElement) {
if (attrName == "config") continue if (attrName === "config") continue
if (attrName.indexOf("on") == 0 && typeof dataAttr == "function") dataAttr = autoredraw(dataAttr, node) else if (typeof dataAttr == "function" && attrName.indexOf("on") == 0) {
if (attrName == "style") for (var rule in dataAttr) node.style[rule] = dataAttr[rule] if (String(dataAttr) !== String(cachedAttr)) node[attrName] = autoredraw(dataAttr, node)
}
else if (attrName === "style") {
for (var rule in dataAttr) {
if (cachedAttr === undefined || cachedAttr[rule] !== dataAttr[rule]) node.style[rule] = dataAttr[rule]
}
}
else if (attrName in node) node[attrName] = dataAttr else if (attrName in node) node[attrName] = dataAttr
else node.setAttribute(attrName, dataAttr) else node.setAttribute(attrName, dataAttr)
cachedAttrs[attrName] = dataAttr
} }
} }
return cachedAttrs return cachedAttrs
@ -141,9 +148,9 @@ new function(window) {
return result return result
} }
function autoredraw(callback, object) { function autoredraw(callback, object) {
return function() { return function(e) {
m.startComputation() m.startComputation()
var output = callback.apply(object || window, arguments) var output = callback.call(object, e)
m.endComputation() m.endComputation()
return output return output
} }
@ -460,6 +467,7 @@ mock.window = new function() {
getAttribute: function(name, value) { getAttribute: function(name, value) {
return this[name] return this[name]
}, },
style: {}
} }
} }
window.document.createTextNode = function(text) { window.document.createTextNode = function(text) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -73,7 +73,7 @@ new function(window) {
setAttributes(node, data.attrs, cached.attrs) setAttributes(node, data.attrs, cached.attrs)
cached.children = build(node, data.children, cached.children) cached.children = build(node, data.children, cached.children)
cached.nodes.intact = true cached.nodes.intact = true
parent.appendChild(node) if (node.parentNode !== parent) parent.appendChild(node)
} }
if (type.call(data.attrs["config"]) == "[object Function]") data.attrs["config"](node, !isNew) if (type.call(data.attrs["config"]) == "[object Function]") data.attrs["config"](node, !isNew)
} }
@ -120,13 +120,20 @@ new function(window) {
function setAttributes(node, dataAttrs, cachedAttrs) { function setAttributes(node, dataAttrs, cachedAttrs) {
for (var attrName in dataAttrs) { for (var attrName in dataAttrs) {
var dataAttr = dataAttrs[attrName] var dataAttr = dataAttrs[attrName]
if (!(attrName in cachedAttrs) || (cachedAttrs[attrName] !== dataAttr) || node === window.document.activeElement) { var cachedAttr = cachedAttrs[attrName]
cachedAttrs[attrName] = dataAttr if (!(attrName in cachedAttrs) || (cachedAttr !== dataAttr) || node === window.document.activeElement) {
if (attrName == "config") continue if (attrName === "config") continue
if (attrName.indexOf("on") == 0 && typeof dataAttr == "function") dataAttr = autoredraw(dataAttr, node) else if (typeof dataAttr == "function" && attrName.indexOf("on") == 0) {
if (attrName == "style") for (var rule in dataAttr) node.style[rule] = dataAttr[rule] if (String(dataAttr) !== String(cachedAttr)) node[attrName] = autoredraw(dataAttr, node)
}
else if (attrName === "style") {
for (var rule in dataAttr) {
if (cachedAttr === undefined || cachedAttr[rule] !== dataAttr[rule]) node.style[rule] = dataAttr[rule]
}
}
else if (attrName in node) node[attrName] = dataAttr else if (attrName in node) node[attrName] = dataAttr
else node.setAttribute(attrName, dataAttr) else node.setAttribute(attrName, dataAttr)
cachedAttrs[attrName] = dataAttr
} }
} }
return cachedAttrs return cachedAttrs
@ -141,9 +148,9 @@ new function(window) {
return result return result
} }
function autoredraw(callback, object) { function autoredraw(callback, object) {
return function() { return function(e) {
m.startComputation() m.startComputation()
var output = callback.apply(object || window, arguments) var output = callback.call(object, e)
m.endComputation() m.endComputation()
return output return output
} }