Post on 21-Apr-2017
transcript
AngularPerformanceTuningfor large apps
What isa fastapp?
I clicked the button... and nothing ever happened!
— Random User
This spinner never stops, maybe I need to hit
reload...— Frustrated User
Scrolling the page feelsawkward, somehow...
— Enraged User
< 100Update the UI in less than 100ms to make it feel instant
loadingspinnersavoid them, preload data instead
> 60 fpsFor smooth scrolling, only rerender parts
Unfortunately [...] it is easy to build slow apps when you don't know what you are doing.
— Misko Hevery
DirtyCheckinga.k.a. The Magic™ behind angular.JS
Minimizenumber of registered watchers
Maximizeperformance of registered watchers
SimpleMeasures
Use ng-if instead of ng-show
<button ng-click="expanded = !expanded"> Show details</button>
<div ng-if="expanded"> <div ng-include="complex.html"></div></div>
docs.angularjs.org/api/ng/directive/ngIf
bind-once
<li bindonce ng-repeat="person in persons"> <span bo-text="person.name"></span></li>
// see bo-href, bo-src, bo-class, bo-html
github.com/Pasvaz/bindonce
Precalculate properties
// bad idea<li ng-repeat="person in persons"> {{person.expensiveComputation()}}</li>
// way better idea<li ng-repeat="person in persons"> {{person.preCalculatedResult}}</li>
AdvancedMeasures
Pagination
<li ng-repeat="person in persons"> {{person.name}}</li>
// better<li ng-repeat="person in persons | paginate:page"> {{person.name}}</li>
github.com/UnicodeSnowman/angular-paginate-filter
Infinite Scrolling
<div infinite-scroll="loadMore()"> <span ng-repeat="person in persons"> {{person.name}} </span></div>
$scope.loadMore = function() { var offset = $scope.persons.length; var more = $scope.allPersons.slice(offset, offet+20) $scope.persons = $scope.persons.concat(more);};// binarymuse.github.io/ngInfiniteScroll/
Cache calculated properties
function Collection(els, size) { /* ... */ }createDynamicProperties(Collection, { view: ['els', 'size', 'page', function () { var offset = this.page * this.size; return this.els.slice(offset, offset.this.size); }]});
<div ng-repeat="person in collection.view"> {{person.name}}</div>github.com/damienklinnert/angular-model
ExtremeMeasures
Scalyr Directives
<div sly-repeat="person in persons"> {{person.name}}</div>
// also see sly-evaluate-only-when,// sly-prevent-evaluation-when-hidden
github.com/scalyr/angular
Angular Fastscroll
<div fastscroll collection="user in users" item-height="40"> <div class="item">{{ user.name }}</div></div>
// github.com/damienklinnert/fastscroll-demo
Angular+React
<table ng-react-component="Repeater" data="data"></table>
var Repeater = React.createClass({ render: function () { var scope = this.props.scope; }});
// davidchang.github.io/ngReact/
Premature optimization is the root of all evil
— Donald Knuth
The performance tuning workflow
1. Set expectations
2. Measure
3. Find bottlenecks
4. Fix it
5. Repeat
Where to go from here? (Tooling)
— Chrome DevTools— Batarang Plugin— angular-instrumentsgithub.com/damienklinnert/angular-instruments
Where to go from here? (Reading)
— Databinding in AngularJS bit.ly/1lfMRhj
— AngularJS Performance Tuning for Long Lists bit.ly/1tNzbht
— Analysing Performance of AngularJS Screens bit.ly/QHRoOc
— Brian talks about angular with lots of data bit.ly/RUV6oA