SteveSanderson/knockout — Issue #330: issues and ideas regarding "throttling"
Author: mbest
Created: 2012-02-15 22:59:06+00:00
State: open

Knockout 2.0 introduced the ability to have computed observables update asynchronously using a `throttle` extender. I recently took a look at the code and tried it for a few things. It's a great idea, but I think it needs some improvements.

1. The throttle extender does something that's not included in the information published in the documentation: it wraps the observable in a computed observable with a delayed write function. I'm not sure why someone would want this feature, but if so, it should be in a separate extender. As it is now, it adds unnecessary extra weight to the basic throttle function.
2. Throttling only makes sense for computed observables. Thus it should be a method of computed objects only and not be an extender. For compatibility, both methods should be supported for some time.
3. Even if a computed observable is being throttled, reading its value should always return the latest, correct value. Currently, if you read the computed value before the throttle timer has passed, you will get the old, stale, value.
4. If a lot of computed observables are throttled (if, for example, one makes it the default behavior), it will have a negative affect on response time. That's because each computed observable will be updated through a separate `setTimeout` call. All browsers impose a minimum timeout value of between 4 and 10 ms. A long chain of computed observables (A -> B -> C -> D...) could take a while to update.
5. The documentation on the web site about `throttle` has a misleading statement: "You can add an arbitrarily short but nonzero throttle timeout (e.g., 1 millisecond)..." Actually the throttle timeout can be 0 (zero).
6. I don't like the term "throttle" in this context. It's often a negative word: to *throttle* someone is to choke them; to *throttle* bandwidth is to make the connection slower. I'd prefer a name more focused on the scheduling aspect, such as *defer* or *asynchronous*, or the increase in efficiency, such as *optimize*.