Closed paulrosen closed 10 years ago
Can you try with the latest development version: https://raw.github.com/mbest/knockout-deferred-updates/master/knockout-deferred-updates.js
I did, and it didn't seem to help. I did notice this time that it appears to be changing some observables through the UI, which is triggering ajax updates and probably causing a loop during initialization.
(I don't doubt it is a problem with my architecture, but I have no idea what I've set up wrong. My symptoms before trying your library are slow initialization, and repeated and unnecessary calls to ko.computed functions.)
My general architecture is that I've got an array of parent objects that have some observables and some computeds. Then each one of those has a array of child objects that also have some observables and some computeds. There is also a "current parent object" that is put on the page, and a "current child object" that is also on the page.
So, when the user switches to a different child object, then 30 or so observables are set into the "current child object". I'd love to just turn off ko, set those values, then turn it back on so I just get one update. But your library seems like it should do the trick, too.
Anyway, thanks for the rapid response!
It's likely that you have some sort of recursive dependency within your computed observables.
Maybe the discussion in #17 can help.
I did read that issue before posting! I promise!
I'll try to figure out if I have a recursive dependency, but I'm not sure how to track that down. Thanks for your help!
Since you're interested only in speeding up a specific part of your code, you can try turning off deferred updates in general and only turning it on for the specific part of your code that needs it.
After including knockout-deferred-updates.js
:
<script>ko.computed.deferUpdates = false;</script>
Then in your code that needs to delay updates:
ko.computed.deferUpdates = true;
// update a bunch of observables
ko.processAllDeferredUpdates();
ko.computed.deferUpdates = false;
I tried putting ko.computed.deferUpdates = false;
in, but the browser still locks up on load. I put it in a couple places: in the script tag you suggested, and also at the top of js file that is loaded after yours.
I don't know if this matters, but I'm using the debug version of ko. The first line in the file is:
// Knockout JavaScript library v3.0.0
I'm also loading in knockout.validation.js and knockout.bindings.dataTables.js, and I'm running jQuery.
Can you try it with an earlier version of Deferred Updates? https://rawgithub.com/mbest/knockout-deferred-updates/acb19c5cbe47134e2c45943a0a5060a5e714b9de/knockout-deferred-updates.js
That version, along with setting deferUpdates to false, allows my page to load -- so that gets me a little farther.
Without the deferUpdates line I still get the infinite loop.
Do you know of any way to find a circular ko reference? I think I might need to comment out most of my program and slowly add functions back until it fails. That might take a while.
Without Deferred Updates included, add a breakpoint in knockout-3.0.0.debug.js
on line 1438. This will break whenever a computed observable is updated recursively. Some of these will be innocuous (they won't cause the infinite recursion), but obviously at least one is the culprit.
Thanks for the tip! That did give me a clue. I'll fix that, then try the newest version of this library again. I'll let you know if anything else goes wrong.
Thanks a lot for your time.
Can you share what you found? Thanks.
Well, I didn't get back to using your library. What I did was replace all the computed() items with my own method that has two changes:
1) The recalculation is called explicitly, so I can just decide when I am finished changing things. 2) I pass in the set of dependencies when first setting up the item, so I can easily see and change why a function is called.
So, I created a function on my model that looks like this:
calculated('variableName', [ 'dependency1', 'dependency2' ], function() { ... });
And that turns the variableName
into an observable()
that I set in a function called recalculate()
.
Sounds like a great approach.
I have a number of console messages, and it looks like it does a bit of initialization, then pauses (maybe for garbage collection?) then does more initialization. I can't tell, but it looks like it is looping on the same initialization over and over.
I'm using KO 3.0, I saw this on chrome, and it is during page load, where I'm loading all my stored data into the ko observables.
I'm not sure what other info is useful to you, but I'll expand this description however you like.
Thanks!