-
Notifications
You must be signed in to change notification settings - Fork 27.4k
perf(ngAnimate): avoid repeated calls to addClass/removeClass when an… #16613
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
'use strict'; | ||
|
||
/** @this */ | ||
var $$AnimateCacheProvider = function() { | ||
|
||
var KEY = '$$ngAnimateParentKey'; | ||
var parentCounter = 0; | ||
var cache = Object.create(null); | ||
|
||
this.$get = [function() { | ||
return { | ||
cacheKey: function(node, method, addClass, removeClass) { | ||
var parentNode = node.parentNode; | ||
var parentID = parentNode[KEY] || (parentNode[KEY] = ++parentCounter); | ||
var parts = [parentID, method, node.getAttribute('class')]; | ||
if (addClass) { | ||
parts.push(addClass); | ||
} | ||
if (removeClass) { | ||
parts.push(removeClass); | ||
} | ||
return parts.join(' '); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it a concerns that adding/removing the same class can result in the same key? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you try to remove a class, the cacheKey will contain the class to remove twice: once because the class is on the element, once for removeClass. |
||
}, | ||
|
||
containsCachedAnimationWithoutDuration: function(key) { | ||
var entry = cache[key]; | ||
|
||
// nothing cached, so go ahead and animate | ||
// otherwise it should be a valid animation | ||
return (entry && !entry.isValid) || false; | ||
}, | ||
|
||
flush: function() { | ||
cache = Object.create(null); | ||
}, | ||
|
||
count: function(key) { | ||
var entry = cache[key]; | ||
return entry ? entry.total : 0; | ||
}, | ||
|
||
get: function(key) { | ||
var entry = cache[key]; | ||
return entry && entry.value; | ||
}, | ||
|
||
put: function(key, value, isValid) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens when you can There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think a different isValid value is possible for the same cacheKey in one and the same animation run. The cacheKey is based on the classes on the element, and the classes define if there's an animation with duration on the element. Since a cacheKey is unique per class combination, it should not be possible to have different validity per cacheKey. |
||
if (!cache[key]) { | ||
cache[key] = { total: 1, value: value, isValid: isValid }; | ||
} else { | ||
cache[key].total++; | ||
cache[key].value = value; | ||
} | ||
} | ||
}; | ||
}]; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it possible for
node.parentNode
to be undefined?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question! You cannot animate elements that are not attached to the document / rootElement, and even an html element has a parentNode, so with this in mind, it's fine.