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

perf(ngmodel/compile): improve ngmodel and general compile/controller performance (#9609) #9772

Closed
wants to merge 4 commits into from

Conversation

jbedard
Copy link
Collaborator

@jbedard jbedard commented Oct 24, 2014

This was mainly focused around #9609 - bringing 1.3 up to speed with 1.2 with an ng-repeated ng-model, at least when not using jQuery.

Overall these changes make the added benchmark (and the jsfiddle in #9609) 2-3x faster and seem to be faster then 1.2 now.

The last 3 commits (refactoring controller stuff in $compile) can probably be squashed but I left them separate for now for nicer diffs.

The only functional change (that I know of) is that the NgModelController $name is now initialized by the directive (pre-link) instead of within the controller. I'm not sure if this an issue or considered breaking? This was already the case for the $options field...

@caitp
Copy link
Contributor

caitp commented Oct 24, 2014

So, we need the tree to be green (so make sure you make jshint/jscs happy) --- I want you to try and avoid observable changes to behaviour when refactoring, it's a big deal that we don't break people more than we already have in releasing 1.3. It's very hard to avoid observable changes with javascript, the language has really lent itself towards breaking applications with very seemingly harmless changes. Lets put in tests for all of the cases that have been mentioned, more tests is always good.

Otherwise, LGTM

@jbedard
Copy link
Collaborator Author

jbedard commented Oct 24, 2014

I'll try to make some updates tonight based on the comments. And fix the build error (appears to be from the new jscs rules).

@realityking good to know. I thought some browsers still required it. I'll make that change as well.

@jbedard jbedard force-pushed the 9609-ngmodel-perf branch 7 times, most recently from 5e0919b to 9085099 Compare October 25, 2014 05:29
@jbedard
Copy link
Collaborator Author

jbedard commented Oct 25, 2014

Updated to address most of the issues mentioned and rebased.

@realityking removing the useCapture arg causes some tests to fail because of how some browsers default to false and other to undefined. Maybe the tests could be written to handle that but I gave up for now.

If we don't want 5183eeb at this time I can move it to a different PR.

@@ -1974,6 +1968,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
}

function invokeEach(funcs) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why make this a separate helper when it's only used once?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mainly just to group all the controller initialization into a single call when debugging/profiling. I'd be fine removing it though...

@jeffbcross
Copy link
Contributor

@IgorMinar is going to take a look at this now. Assigning to him now.

@jeffbcross
Copy link
Contributor

Sorry, he's going to take a look at it "today" not "now"

@jeffbcross jeffbcross assigned IgorMinar and unassigned caitp Oct 29, 2014
@jbedard
Copy link
Collaborator Author

jbedard commented Oct 29, 2014

Note that if we don't want 5183eeb (which can be considered a breaking change) then we can still improve most use cases by simply avoiding $interpolate when ngmodel is used without a name attribute (basically jbedard@05fac02 - which is currently in a different WIP branch with similar avoid-$interpolate changes).

@googlebot
Copy link

Thanks for your pull request.

It looks like this may be your first contribution to a Google open source project, in which case you'll need to sign a Contributor License Agreement (CLA) at https://cla.developers.google.com/.

If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check the information on your CLA or see this help article on setting the email on your git commits.

Once you've done that, please reply here to let us know. If you signed the CLA as a corporation, please let us know the company's name.

@@ -283,7 +283,7 @@ describe('form', function() {
submitted = true;
};

addEventListenerFn(doc[0], 'submit', assertPreventDefaultListener);
doc[0].addEventListener('submit', assertPreventDefaultListener);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 3rd argument is missing in this file.
(Not sure if it is needed, but if not we could/should remove it from the other files as well.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I'd rather be consistent...

@gkalpak
Copy link
Member

gkalpak commented Nov 28, 2014

I wonder what is the purpose of removing jqLite's add/removeChangeListener().

If we can get rid of the useCapture argument, then it is fine (I guess).
But if not, then having to add it "manually" every time is error-prone.
(Besides, there shouldn't be any real performance penalty in using a helper function, right ?)

Is there any other reason I might not be aware of ?

@realityking
Copy link
Contributor

useCapture defaults to false in all modern browser (see MDN) so that should be fine. I'd remove it everywhere for consistency.

@jbedard
Copy link
Collaborator Author

jbedard commented Nov 28, 2014

See my comment above. Tests break because different browsers have different defaults for useCapture (false vs undefined). I'm tempted to just drop that commit for now though...

@googlebot
Copy link

CLAs look good, thanks!

@jbedard
Copy link
Collaborator Author

jbedard commented Jan 26, 2015

I've rebased this and removed some out of date and debatable commits (see https://github.com/jbedard/angular.js/tree/9609-ngmodel-perf-ORIG for all the originals). Maybe I should create a new PR? This PR no longer has the form/ngmodel change (sort of breaking) or controller change (bf6a79c was good enough) or more minor ones.

What's remaining is only the benchmark and controller methods in $compile:

  • fix a TODO to merge elementControllers/controllers (7a1edda)
  • avoid forEach at link time and only call .data once when setting up controllers (0196730)
  • move the refactored code into a method (e2ed092)

This improves the added benchmark ~20% and seems to reduce memory a lot (I haven't looked into why or verified this, but running the benchmark it is about half the memory during the create step!?). I really think this is worth merging...

@jbedard
Copy link
Collaborator Author

jbedard commented Feb 1, 2015

Rebased again. Previous results still hold (ngmodel benchmark being ~20% faster and half the memory usage).

@petebacondarwin is this on anyone's radar anymore? Should I create a new PR since half the commits were removed/done elsewhere?

@lgalfaso
Copy link
Contributor

@jbedard can you close this PR and move the remaining parts into new PRs?

@jbedard
Copy link
Collaborator Author

jbedard commented Feb 17, 2015

Sounds good, closing this one...

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

Successfully merging this pull request may close these issues.

9 participants