I have a knockout application with hundreds of computedObservables. If I turn off deferUpdates, updates are slow but manageable (+- 1sec on my machine). However, if I turn on deferUpdates, this turns into 68 seconds, during which chrome is unresponsive.
At first I thought that the page was stuck in an infinite loop, as the stack trace kept repeating when I paused script execution. This fragment was repeated dozens of times:
self._limitChange (knockout-3.5.0.debug.js:1452)
_evalDelayed (knockout-3.5.0.debug.js:2376)
markDirty (knockout-3.5.0.debug.js:2177)
notifySubscribers (knockout-3.5.0.debug.js:1398)
limitNotifySubscribers (knockout-3.5.0.debug.js:1353)
(anonymous) (knockout-3.5.0.debug.js:1254)
self._limitChange (knockout-3.5.0.debug.js:1452)`
Eventually I found out that every stackframe of _limitChange had a different computable observable in it. It seems as if knockout recursively goes through the entire computedObservable-tree.
My questions are as follows:
- Why is it so slow with ko.options.deferUpdates = true, while without it KO also needs to recompute the entire tree?
- Does anyone else have experience with this problem and how did you solve it?
- Why does ko need to go through the entire tree to call markDirty on everything?
Any insights are much appreciated.