4

KnockoutJS - if binding performance

 3 years ago
source link: https://www.codesd.com/item/knockoutjs-if-binding-performance.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

KnockoutJS - if binding performance

advertisements

I have an observable array with 50 items, rendered with a foreach binding.

I'm trying to understand why the template that each item renders is suffering so much from an if binding. Essentially, I'm showing or hiding a large chunk of my template based on a computed observable. This is hitting me with a 70-100% render time increase (compared to using a visible binding instead).

Ryan Niemeyer's great post on this topic indicates that binding a computed to an if binding will cause all of the content to re-render each time any part of the computed is updated. But my computed does not change value during the time that the observable array is being looped through.

this.filtersAvailable = ko.computed(function () {
   return this.searchInfo.searchType() != 'invites' && this.searchInfo.searchType() != 'requests'
}, this);

And just to make sure that it's not in fact changing, I added this:

this.filtersAvailable.subscribe(function(newVal) { alert("fa" + newVal); });
this.searchInfo.searchType.subscribe(function(newVal) { alert("st" + newVal); });

That said, this computed is defined at a higher level than the individual view models of my observable array, and is called repeatedly both at other places in my template, and of course by every other item in my observable array.

Will this repetitive calling of the computed observable cause things bound to it with an if binding to re-render?


Accessing the value of a computed observable again and again is not a problem, as you get the cached value back each time. Sounds like your subscriptions are not showing frequent updates?

With a computed this will even be if the value is the same. You can try throwing a ​<div data-bind="text: Date()"></div>​​​​​​​​​​​​​​​​​​​​​ in your if section and see if it looks like the dates are updated more frequently than you would expect.

If everything was getting re-rendered again and again the dates would likely be close to the same. For a case where the value is truthy, the if binding has slightly more overhead as it takes a copy of the child elements and then renders a copy as the template and binds against it. visible will just set the display style. Now, the if binding can give you better performance in cases where the initial value might be false and you have a lot of markup/bindings in the hidden section. if wouldn't even render them, while visible would still bind, but just hide.

You could try a named template too, where you have your if. If you are doing an if inside of a foreach, then KO has to copy the child elements as a template again and again inside of each foreach item. You can do <div data-bind="template: { name: 'subItemTmpl', 'if': myFlag, data: subData"></div>.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK