-
Notifications
You must be signed in to change notification settings - Fork 51
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
Simplifies shouldComponentUpdate (open discussion) #78
Conversation
17a7db2
to
446ed40
Compare
if (currentCursorsKeys.length !== nextCursorsKeys.length) { | ||
if (debug) debug.call(this, 'shouldComponentUpdate => true (number of cursors differ)'); | ||
if (nextProps !== this.props) { | ||
if (debug) debug.call(this, 'shouldComponentUpdate => true (equal input)'); |
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.
*unequal? 😄
1d36b75
to
d9541ef
Compare
Faster/easier should component update 👍 ! Though, I think for something like this we need some hard numbers on comparison speeds before and after these changes. |
I'm working on a benchmark. Copied Immutable.js' benchmark and trying to run it now. It compares previous dist file with current uncommitted dist. |
var isNextImmutable = _isImmutable(next); | ||
|
||
if (isCurrentImmutable && isNextImmutable) { | ||
return current.equals(next); |
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.
While I kind of like the idea of an interface for saying you want component args to trigger renders or not when changed, I'm still not conviced Immutable.js .equals() is the way to go.
7972811
to
fec0172
Compare
if (debug) debug.call(this, 'shouldComponentUpdate => true (cursors have changed)'); | ||
return true; | ||
} | ||
var isNotIgnorable = not(or(isStatics, isChildren)); |
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.
Move this outside of shouldComponentUpdate
for caching. No need to reconstruct this higher-order function on every render.
👍 Awesome! @mikaelbr Looking forward to see the benchmarks. I wonder if @Gozala Do you agree that there's a compromise where one can override |
} | ||
var isNotIgnorable = not(or(isStatics, isChildren)); | ||
var nextProps = filter(nextProps, isNotIgnorable), | ||
currentProps = filter(this.props, isNotIgnorable); |
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.
Move this below _isEqualState
block for better placement:
var nextProps = filter(nextProps, isNotIgnorable),
currentProps = filter(this.props, isNotIgnorable);
Reasoning is that it could be a pointless computation if !_isEqualState(this.state, nextState) === true
.
Thanks for good feedback. I haven't gotten the benchmark to work as I want yet, and haven't had the time to work on it too much, but it'll get there. |
@@ -236,6 +184,22 @@ function factory (methods) { | |||
} | |||
} | |||
|
|||
function compare (current, next, comparator, equalCheck) { |
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.
Just a nitpick. I think comparator
is the wrong name.
Maybe rename to typecheck
or similar.
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.
I had a hard time choosing a name. I agree. Fixing
New changes looks good to me. 😄 |
if (hasChangedCursors(currentCursors, nextCursors)) { | ||
if (debug) debug.call(this, 'shouldComponentUpdate => true (cursors have changed)'); | ||
return true; | ||
if (nextProps === this.props) { |
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 if assert(nextProps === this.props && nextState !== this.state)
?
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.
You're right.
Here's the initial relative benchmarks for the current dist and this dist:
Haven't looked too much into this, so these numbers might be wrong, but they seem reasonable. I didn't get cursors to work, but immutable structures should works just as good. The tests can be found here: https://gist.github.com/mikaelbr/b4760464013fe636186f |
Tests for SCU quick exit for #78
Here are my results with
|
As a joke, I added a minor improvement: dashed@74e91b6 |
The benchmark was flawed. Immutable structures weren't actually created at all! Here is why: /~https://github.com/Dashed/omniscient/blob/c31930e70023d5d524d23ffc48919c8460cc97b3/perf/tests.js#L5-L11 I augmented the benchmarks with two working cursor benchmarks: My results: /~https://github.com/Dashed/omniscient/blob/c31930e70023d5d524d23ffc48919c8460cc97b3/bench/results.txt @mikaelbr Feel free to add more cursor tests. |
a reasonable assumption would be omniscient folks use more props than state - should we move the props check before the state check? |
I made the same assumption, but a different conclusion. As state is rarely used, it's most likely smaller than props and thus if they differ the check will be cheaper. Also, if it is empty (as it is 98% of the time) the check is also cheap as you don't have to do a lot of iterations. Might add som benchmarks to see the actual numbers - when we get confident benchmarks. |
Maybe we can make the component smarter to adjust priority in checks based on previous re-renders? |
Tradeoff is that a new |
We can utilize this to decide whether to run http://www.loper-os.org/bad-at-entropy/manmach.html We can modify this so that when the Machine It isn't a heavyweight predictive modeler, but decent enough 😄 |
This would be a consideration for a separate PR once this PR simmers. |
Simplifies shouldComponentUpdate (open discussion)
Used a variation of immutable.js benchmarks: https://gist.github.com/mikaelbr/c7e37f5865c494a6e0fa |
I am not sure what the context of this question is. In principal having a control over each one sounds right though. As of my personal take I don't use omniscient for components with a local state, those in my code are usually shims that I use react API directly. |
Simplifications to
shouldComponentUpdate
now as we have_.isEqual
.Started implementation based on some comments from #76 - and this is a continuation of the discussion. Not yet implemented "rebase" support. As that may be a separate change.
Nor is comparable implemented. As there are some discussion if we need to do deep equal on immutable structures that has been said to not be equal through reference checks.