-
Notifications
You must be signed in to change notification settings - Fork 18
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
Reuse updated nodes and contexts. #46
base: master
Are you sure you want to change the base?
Conversation
Hello @AllSeeingEye, thank you for your work. At first glance the idea seems to be good, however I have some worries, basically two. First, I don't know if it's supported to change an existing Second, reusing the active nodes of a previous
The key here is the The problem is not only and not exactly with the So basically while I like this idea, I think it's suitable only for simple cases, where one uses a constant node set as the |
@cervengoc Yep, behaviour when modifying The nested re-use is definitely an issue, so I would definitely consider this an optional parameter (defaulting to The That said, the performance improvement is pretty spectacular, so if it can be done - even for optional simple cases that would make some people's lives great. If we go down the optional flag path, what would be a good name for the flag? |
An alternative, (that may or may not be) worth considering, is forking fast-foreach and creating another binding for simple cases, that extends the |
I like the fork idea, I was thinking about that too, following the pattern of the already discussed If |
The I think |
@@ -421,7 +421,7 @@ describe("observable array changes", function () { | |||
arr[i].num = i; | |||
} | |||
assert.equal(div.children().length, itemNumber) | |||
assert.equal(div.children().filter(function() { return this.testprop == 10; }).length, itemNumber) | |||
//assert.equal(div.children().filter(function() { return this.testprop == 10; }).length, itemNumber) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the issue here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is strange. I think that test script doesn't catch up with the rendering speed (?), as I get different assertion results every time - it is in the range of 97-100. Gimme a bit of time to look into this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test passes if I wrap the 2nd part of the script (everything after console.timeEnd("with move");
) with a setTimeout(function() { ... }, 1)
. What do you think of this?
@@ -571,7 +571,7 @@ describe("observable array changes", function () { | |||
}) | |||
|
|||
describe('afterAdd', function () { | |||
it("emits on changes to an observable array", function () { | |||
it.skip("emits on changes to an observable array", function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll want to re-enable this before merging (unless there's a compelling reason to disable it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The very last assertion in this test:
assert.equal(nodes, 4, 'n4')
needs to be rewritten as:
assert.equal(nodes, 3, 'n4')
This fixes the test.
@cervengoc: thank you for your comment; I felt that handling the binding context(s) the way I did was dangerous - I just wanted to get an input on this. I've moved to a safer code in my latest commits. I need to think more on your comment on binding update/cleanup, thanks for the heads up. |
Thanks, that solved my flickering problem. |
This is the initial attempt to avoid costly add/remove DOM operations by reusing DOM nodes and the respective context(s), as discussed in #37.
This patch still relies on the arrayChange; script now detects add/delete sequence on the same index and replaces it with a single 'update' operation. This, however, causes issues with some tests that rely on DOM node identity - please see my changes to spec\knockout-fast-foreach-spec.js (I wasn't able to fix all the test issues, unfortunately).
In the React/Angular/Knockout/raw test:
https://brianmhunt.github.io/chrisharrington-performance.html
this new version is about 9 times faster (for the update operation, not for the initial array deployment; 5000 elements) than the current master branch code.
Future work: we should probably reuse all the possible nodes, only adding/removing the tail ones as necessary (and caching nodes, maybe?).