Determine when a DOM update has completed as a result of live binding?

I have an app that works fine but I would like to enhance the interface slightly to re-assure my users (:slight_smile:
At the mom I ajax for a shed load (technical term) of json to describe several thousands entries in a somewhat complex database.
The json groups into 4x categories which I render through a 4x tabbed interface showing whichever default tab is appropriate
Clicking a tab will append the relevent json object(s) to an existing observable and the live binging magic will display everything.
It can take a few seconds though.
That is to say that the live binding auto magical rendering can take a few seconds (ajaxing for the json is not a time problem) and I want to re-assure users that their page is still alive and also (probably) capture and dispose of any wild clicking around.

so :slight_smile

$el.html(can.view(myTemplate.stache, obs))
ā€¦ click a tab ā€¦
ā€¦ add some thousands of new objects into obs ā€¦ (objects are already ajaxed into memory)
ā€¦ dum de dum ā€¦ (for a few seconds)
OK rendered !

I would like to know what event to listen for to determine that DOM has now been updated, or indeed, any other appropriate apporach.

Iā€™m sure Iā€™ve seen something about this but canā€™t find it.

??

Regards

Ron Yuen

so your site is freezed while updating the DOM?

my thoughts are:

  1. reduce the amount of observable in your DefineMap. do you really need observables? you can use the http://v3.canjs.com/doc/can-define.types.html any to specify what should not converted into a observable.
  2. maybe you can create a webworker to render the stache template and then put it into the DOM

Hi @ron.yuen,

Changes to an observable are immediately reflected in the DOM, so when you append the objects to your existing observable, the DOM is ā€œinstantlyā€ changed (instantly in quotes because if you have thousands of items, it might take a bit). There isnā€™t really an event to listen to because as soon as you call .attr() to update the observable, the DOM changes are made.

Question for you: does your UI lock up, freeze, or become unresponsive when switching tabs? If it doesnā€™t, then you might not have any issues. You can also measure the time in your code to see how long the updates are taking:

console.time('Observable update');// Start a timer
yourMap.attr('attribute', newData);// Whatever code you have that updates the observable
console.timeEnd('Observable update');// End the timer and display it in your browserā€™s console

Some more food for thought, if it is slow and causing the UI to freeze:

  • Do you need the live binding features? If not, you could create a helper to insert the data into the DOM without using stache.
  • Can you batch the observable updates into groups? In other words, when you update the observable, can you first only change a couple hundreds items, then wait for requestAnimationFrame to fire before changing the next couple hundred?

Thanks for these thoughts.

I have of course timed things, actually in exactly the way that pYr0x is suggesting. At the mom it can take several (single digit) seconds for the observable updates to be reflected, somewhat depends on the userā€™s desktop horsepower.

I am aware that I could at least in principle reduce the ā€˜loadā€™ on the observable but Iā€™m not sure itā€™s worth the effort.

What I was trying to get to was a re-assurance for the user that they are still alive and as it were ask them to be patient for a few seconds. The interface is not freezing or locking out itā€™s just those several seconds during which the user is likely to start clicking about and if they hit any of the other tabs they are adding even more load ā€¦

Itā€™s not that big a deal ā€¦

Regards

Ron Yuen

I would add some sort of infinite scroll load. Render only what the user can see, then on scroll add more items. That way you are not rendering thousands of items. Most of which will never be seen.