KnockoutJS: computed vs. pureComputed
Asked Answered
C

2

46

What's the difference between computed and pureComputed in KnockoutJS?

Can I use pureComputed instead of computed safely?

Continue answered 19/5, 2015 at 4:47 Comment(4)
have you read the docos: knockoutjs.com/documentation/computed-pure.htmlMohammadmohammed
@Mohammadmohammed I don't understand why shouldn't we use pureComputed when there's actions in the computed.Continue
You should read the docs, and then ask about parts of the docs you dont understand, as it is, you seem to be asking for people to read them for you and give you a tldrMohammadmohammed
In short until someone is requesting pure computed value in view or vm pureComputed will be in sleep mode it wont evaluate anytime. ex : jsfiddle.net/rahulrulez/jg0s1xhb/5/light you can see in fiddle until this <!--ko if: step() == 2--> condition satisfied pureComputed wont fire (what makes pureComputed fire then ? As mentioned former , html content inside the if condition is rendered and we having a element with data-bind requesting pureComputed value) #hopeThatHelpsSomeoneRimester
S
23

I agree with the @Jeroen and I would like to add a short example from J. Munro's book which helped me a lot so this might be helpful for others as well.

First of all, pureComputed observables are quite similar to the computed observables with several performance and memory improvements. The name is borrowed from the Pure function programming term and it means that any function which uses only local variable is potentially pure, whereas any function that uses a non-local variable is potentially impure.

The observables in Knockout.js are treated differently. Thus pureComputed observables are placed in a sleeping mode (Knockout inclines all dependencies and re-evaluates the content when after reading) and computed observables are placed into listening mode (Knockout constantly checks whether the value is up-to-date prior to first access).

Therefore, if you need to execute other code, then better to use a computed observables.

function ViewModel() {
     var self = this;

     self.firstName = ko.observable('Arshile');
     self.lastName = ko.observable('Gorky');
     self.pureComputedExecutions = 0;
     self.computedExecutions = 0;

     self.pureComputedFullName = ko.pureComputed(function() {
         // This is NOT recommended 
         self.pureComputedExecutions++;
         return 'Hello ' + self.firstName() + ' ' + self.lastName();
     });
     self.computedFullName = ko.computed(function() {
         self.computedExecutions++;

         return 'Hello ' + self.firstName() + ' ' + self.lastName();
     });
 };
 var viewModel = new ViewModel();
 ko.applyBindings(viewModel);

 alert('Pure computed executions: ' + viewModel.pureComputedExecutions);
 alert('Computed executions: ' + viewModel.computedExecutions);

When this code is run, two alert messages are displayed that show the number of times the pureComputed and computed functions are called. Since pureComputed is in sleeping mode then the function has never been accessed, and the counter wil display 0. In contrast to this, the computed function is automatically evaluated on data binding, causing the counter to increase the number and display 1.

Swabber answered 31/7, 2015 at 14:15 Comment(2)
What do you mean by "inclines all dependencies"?Grilse
stores dependencies and checks them laterSwabber
Z
36

They are very similar. The difference is that pureComputed has some performance optimizations, and tries to prevent memory leaks, by being smart about who's tracking its changes.

You can safely replace computed with pureComputed in a lot of cases. The function inside the computed should follow this:

1.Evaluating the computed observable should not cause any side effects.

2.The value of the computed observable shouldn’t vary based on the number of evaluations or other “hidden” information. Its value should be based solely on the values of other observables in the application, which for the pure function definition, are considered its parameters.

So as a rule of thumb, any computed observable that just plainly transforms some regular observable properties should be fine as a pureComputed, otherwise stick with computed.

The documentation has decent explanations of when/why you should not use pureComputed observables. Here's a relevant excerpt:

You should not use the pure feature for a computed observable that is meant to perform an action when its dependencies change.

The reason you shouldn’t use a pure computed if the evaluator has important side effects is simply that the evaluator will not run whenever the computed has no active subscribers (and so is sleeping). If it’s important for the evaluator to always run when dependencies change, use a regular computed instead.

Zara answered 19/5, 2015 at 6:5 Comment(5)
I don't understand why shouldn't we use pureComputed when there's actions in the computed.Continue
Don't think I can explain it much better than the documentation can. I've added some relevant quotes relating to the question in your comment, but for further questions/details I recommend you carefully read the documentation. If, after that you still have doubts, the actual source code as well as experimenting are probably more viable options than asking here.Zara
basically if you only need to update subscribers (other computed that depend on it, bindings, or event subscribers) then use purecomputed, if you need to do any other action like call an ajax request when the observables for that computed change then use normal computed as if you dont have active subscribers the computed wont refresh, how can a suscription becomes inactive, with an if binding for instanceMohammadmohammed
@Mohammadmohammed Thanks luis.... need more clear examples like you just provided, otherwise the internet is being way to abstract when it comes to computed vs purecomputedKnee
@Mohammadmohammed But it sounds like if you've got your computed directly bound to your page's DOM (or some situation where you've got a "permanent" subscriber), there's no practical difference between the two. Is that right?Bonnard
S
23

I agree with the @Jeroen and I would like to add a short example from J. Munro's book which helped me a lot so this might be helpful for others as well.

First of all, pureComputed observables are quite similar to the computed observables with several performance and memory improvements. The name is borrowed from the Pure function programming term and it means that any function which uses only local variable is potentially pure, whereas any function that uses a non-local variable is potentially impure.

The observables in Knockout.js are treated differently. Thus pureComputed observables are placed in a sleeping mode (Knockout inclines all dependencies and re-evaluates the content when after reading) and computed observables are placed into listening mode (Knockout constantly checks whether the value is up-to-date prior to first access).

Therefore, if you need to execute other code, then better to use a computed observables.

function ViewModel() {
     var self = this;

     self.firstName = ko.observable('Arshile');
     self.lastName = ko.observable('Gorky');
     self.pureComputedExecutions = 0;
     self.computedExecutions = 0;

     self.pureComputedFullName = ko.pureComputed(function() {
         // This is NOT recommended 
         self.pureComputedExecutions++;
         return 'Hello ' + self.firstName() + ' ' + self.lastName();
     });
     self.computedFullName = ko.computed(function() {
         self.computedExecutions++;

         return 'Hello ' + self.firstName() + ' ' + self.lastName();
     });
 };
 var viewModel = new ViewModel();
 ko.applyBindings(viewModel);

 alert('Pure computed executions: ' + viewModel.pureComputedExecutions);
 alert('Computed executions: ' + viewModel.computedExecutions);

When this code is run, two alert messages are displayed that show the number of times the pureComputed and computed functions are called. Since pureComputed is in sleeping mode then the function has never been accessed, and the counter wil display 0. In contrast to this, the computed function is automatically evaluated on data binding, causing the counter to increase the number and display 1.

Swabber answered 31/7, 2015 at 14:15 Comment(2)
What do you mean by "inclines all dependencies"?Grilse
stores dependencies and checks them laterSwabber

© 2022 - 2024 — McMap. All rights reserved.