-
Notifications
You must be signed in to change notification settings - Fork 421
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dirty Checking #1214
Comments
Value, Object, and Array APIsWe should be able to use dirty checking relatively transparently with current CanJS APIs. The var foo = {bar: 'hi', baz: 'bye'};
// returns a can.compute that dirty checks the bar
// property of foo and includes normal compute
// bindings
var dirtyBar = can.compute.watch(foo, 'bar');
// returns a can.Map that dirty checks the entire foo object
// and fires all change events available with a can.Map
var dirtyFoo = can.Map.watch(foo);
var fooArray = [0, 2, 3, 4]
// returns a can.compute that dirty checks the first
// item in the array
can.compute.watch(fooArray, '0');
// returns a can.List that dirty checks the entire fooArray
// and fires all change events available with a can.List
can.List.watch(fooArray) Secondary APIcan.watch(value [, property_string]) // where value is a primitive, array, or object
The pseudo-code for can.watch = function(value, property) {
if (alreadyObservable(value)) {
return observable;
}
if (property) {
return can.compute.watch(value, property);
}
if (can.isArray(value)) {
return can.List.watch(observable);
}
if (can.isObject(value)) {
return can.Map.watch(observable);
}
return can.compute.watch(value);
} TemplateTemplate can automatically convert a primitive object into a For example: <script id='template' type='text/mustache'>
<h1>Welcome {{user}}</h1>
<p>You have {{messages}} messages.</p>
</script> var data = {
user: 'Tina Fey',
messages: 0
};
var template = can.view('#template', data);
document.body.appendChild(template); In the above example ChallengesMany browsers do not have support for PerformanceSince Second, |
I like this API a lot, specially I also think it's good to have can.view automatically dirty check -- and I would argue that's one of the more important parts of all this, since so much of our object observation is for the sake of template rendering. As far as template rendering goes, it might be nice to have an event hook into rendering completion. CanJS is currently synchronous, and folks might still expect that. Perhaps telling users to call Finally, observe-js supports several kinds of object observation. How are we handling those different kinds? Some of them are fairly interesting (such as the path observers). |
👎 I'd encourage you to read the Change Detection document describing how change detection is going to be refactored in AngularJS 2.0 just to come to grips with the expense and the effort involved in trying to keep a handle on the performance. |
Read it when it was first released. can.Map will still be around for the foreseeable future. Sent from my iPhone
|
Instead of returning a can.Map or a can.List and trying to keep them up to date (expensive), I think this should just return a "shim" object with a bind method like var listLike = can.observe(["a",1]);
listLike.bind("add", function(ev, added, index){}) Q: What to do if someone listens to change? |
This one hasn't been mentioned yet: Object.prototype.watch Its polyfill uses |
@stevenvachon As for (I wonder how big a percentage of the web developer community just takes jsPerf tests at face value, rather than having a look for themselves if tests are correctly implemented to begin with.) Also, the watch polyfill cited on MDN is essentially flawed in that it does not work when the property in question is already a getter/setter property. It clobbers the existing property without providing a proper inherited call chain into the original getter/setter pair. |
Running a loop more than 1000 times is not necessary with benchmark.js (what jsperf runs on) as it already runs each test upwards of 100,000 times. Defining a getter/setter is part of the dirty checking process per object, so testing its performance is still valid. Here is the same jsperf with construction time excluded: |
With construction time excluded and purely checking usage, you find out that anything not running on Blink & the V8 JS engine is up to 270 times slower in using a getter/setter property than a normal |
Yes, as stated before, dirty checking is currently a bad practice. However, it's likely the future technique with |
Closing. We're moving to |
VOTE HERE
Dirty checking enables observation of plain old JavaScript objects. In CanJS, this will allow the creation of observable data from any source, bypassing the need to wrap data with a
can.compute
,can.Map
, orcan.List
from the beginning.By using existing observable interfaces and bindings, dirty checking will allow non-observable objects to be used anywhere a CanJS Observable would be used. This will make development more straightforward, lower the barrier to entry for new CanJS developers, and provide out-of-the-box compatibility with libraries that don't provide their own observable interfaces.
The text was updated successfully, but these errors were encountered: