Less memory use feature: add watchHash to ngModelOptions #11177
Description
Watchers check watched expression value differences and for this to work they save previous value. The problem is that this can have a major impact on resources as sometimes our model values are pretty large (i.e. users editing HTML content or textareas where users enter large amounts of text).
As these watched model values may be large it would be great if Angular had an additional ngModelOption
called watchHash
that would rather calculate hash of the model value and compare that. This hash calculation can be extremely simple to aid performance.
Here's a JSPerf example of various checksum/hash algorithms comparison.
The simplest checksum calculation can simply do the
checksum += value.charCodeAt(i) * (i + 1);
where resulting calculated value becomes larger with longer inputs. This may not be desired and we'd like to have a more evenly distributed value calculation (more like a real hash/checksum). Hence I'm currently using following watch string input calculation that's also quite fast. not as fast as simple summation, but still pretty fast.
function checksum(value) {
// prime and factor used to ensure larger input does not imply larger checksum
var prime = 0x56ca7561;
var factor = 0x0123456b;
// return 0 if string is empty or null
if (!value) return 0;
for (var i = 0, l = value.length, result = factor; i < l; i++)
{
result += value.charCodeAt(i) * factor;
result &= 0x7FFFFFFF; // convert to 32-bit positive integer
result ^= prime;
}
return result;
}
So whenever we'd know that our model value will be large, we can add this model option to instruct Angular to calculate hashes instead comparing whole values in watcher.
<textarea ng-model="someValue" ng-model-options="{ watchHash: true }" />
Default could also depend on bind type we're doing in our code:
- if we're using
ng-bind
or interpolation then defaultwatchHash
would befalse
- if we're using
ng-bind-html
default would betrue