Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Less memory use feature: add watchHash to ngModelOptions #11177

Open
litera opened this issue Feb 25, 2015 · 2 comments
Open

Less memory use feature: add watchHash to ngModelOptions #11177

litera opened this issue Feb 25, 2015 · 2 comments

Comments

@litera
Copy link

litera commented Feb 25, 2015

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 default watchHash would be false
  • if we're using ng-bind-html default would be true
@Narretz
Copy link
Contributor

Narretz commented Oct 12, 2015

Not caching the oldValue however means that you cannot access it in the watchAction fn. This might be an acceptable tradeoff if you want performance, but it's definitely a bit confusing.
That said, I think custom copy / compare functions might be the way to implement such a feature: 10096

@Narretz Narretz closed this as completed Oct 12, 2015
@Narretz Narretz reopened this Oct 12, 2015
@litera
Copy link
Author

litera commented Oct 13, 2015

That's true, but when you need this kind of functionality I suppose one's aware of it. I arguably also suspect that new value is mainly used so this shouldn't be a problem.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants