Last active
August 29, 2015 14:06
-
-
Save thebenedict/a281de5298ea430625ba to your computer and use it in GitHub Desktop.
Lesson learned: when they say "data binding", they're not kidding.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
TLDR: I bound expensive filtering to the template and it | |
was run too often. After moving filtering to the controller | |
it's much faster. | |
*/ | |
/* | |
So what happened with those slow filters? | |
I started with debounce like we discussed, but this gave only | |
a slight performance improvement: | |
*/ | |
$scope.$watch("queryWord", _.debounce(function (id) { | |
$scope.$apply(function(){ applyQuery(); }) | |
}, 300)); | |
var applyQuery = function() { | |
$scope.textQuery.word = $scope.queryWord; | |
} | |
/* | |
here `queryWord` is the ng-model for the search input field, | |
and `$scope.textQuery.word` is passed to the filter. I realized | |
that the above code only debounces the input, while in my | |
template I have lines like: | |
*/ | |
<span class="nav-counter">{{countWith($parent.prefilteredExceptCharacteristics, 'stove_characteristics', chstic.slug)}}</span> | |
/* | |
Anything inside double curly braces is refreshed with every | |
digest cycle, so `countWith` was being called with each | |
keypress (and other events!). By interpolating a filter in the | |
template I was re-filtering my data 10^4 times or more for | |
each event. | |
I moved the filtering into the controller (see SO link below), | |
storing the output of each filter on the scope. Binding the | |
stored output to the scope, the line above becomes: | |
*/ | |
<span class="nav-counter">{{chstic.filterCount}}</span> | |
/* | |
With a `$scope.$watch()` on the search text | |
input and checkbox filters, each `filterCount` | |
is only updated when the search critera change. | |
Here's the result: http://catalog.cleancookstoves.org/#/stoves | |
(I know the load speed is still too slow, but that's a | |
separate issue) | |
It's fast enough now that debounce isn't necessary, but I | |
left in a 250ms delay on the text input because I think | |
it feels better. There's no delay on the check boxes. | |
Assorted posts I found helpful: | |
http://www.aaron-gray.com/delaying-the-digest-cycle-in-angularjs/ (front page of Hacker News 9/18/14!) | |
http://www.sitepoint.com/understanding-angulars-apply-digest/ | |
http://stackoverflow.com/questions/17656397/angular-js-scaling-performance | |
http://stackoverflow.com/questions/21088845/can-i-debounce-or-throttle-a-watched-input-in-angularjs-using-lodash | |
http://tech.small-improvements.com/2013/09/10/angularjs-performance-with-large-lists/ | |
http://stackoverflow.com/questions/14302267/how-to-use-a-filter-in-a-controller | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment