SlideShare a Scribd company logo
Optimizing a Large
AngularJS Application
Karl Seamon
Senior Software Engineer, Google
Occasional contributor to AngularJS
Topics
● The Problems
● Basics and Best Practices
● Diagnosing performance problems
● Improving performance within AngularJS
The Problems: What can make an
Angular app slow?
● Anything that could affect a normal JS app
o Slow DOM
o Single-threaded
o etc
● Inefficient directives
o link vs compile
o $parse vs $eval vs interpolation
● Dirty checking
o Lots of watchers
o Slow watchers
o Too many calls to $apply
What does slow mean?
● $apply > 25ms
● Click handler > 100ms
● Show a new page > 1s
o > 10s -> users will give up
o 200ms or less is ideal
Directives: compile, link, and
constructor
● When a directive appears inside of a
repeater
o compile is called only once
o link and the constructor are called once per iteration
● When creating directives, try to get as much
work done as possible in the compile step
(or even earlier, in the factory)
● Example
o https://github.com/angular/angular.js/commit/f3a796
e522afdbd3b640d14426edb2fbfab463c5
Directives: Transclusion
● For directives that wrap other content
● Allows your directive to $digest its own
scope without causing dirty checks on
bindings in the user-provided contents
$digest and $apply
● Angular’s documentation favors $apply
o Simpler to use $apply all the time
o $apply has special error handling that $digest lacks
● So what’s $digest for?
o $apply = $rootScope.$digest + some other stuff
o If you update a child scope s, you can call
s.$digest to dirty-check only that s and its
descendants
Watchers
scope.$watch(valueExpression,
changeExpression, ...)
valueExpression will be executed many times -
Make sure it is fast! Avoid touching the dom
(_.debounce can help).
$watch and $watchCollection, con’t
● $watch has two comparison modes
o referential (default) - quick, shallow comparison
o deep - slow, recurses through objects for a deep
comparison; also makes a deep copy of the watched
value each time it changes
● Avoid deep $watch whenever possible
$watchCollection
● new in 1.2, used by ng-repeat
● Goes one level deep into the watched array
or object
● A nice alternative to deep $watch in many
cases
● $interpolate: returns function that evals “a
string {{like}} this”
● $parse: returns function that evals
“an.expression”
● $scope.$eval: evaluates “an.expression”
(using $parse)
$eval, $parse, and $interpolate
var parsedExp = $parse(‘exp’);
for (var i = 0; i < 99999; i++) {
parsedExp($scope);
}
$eval, $parse, and $interpolate, con’t
● Better to call $parse once and save the function than to call $eval many times
● $parse is much faster than $interpolate, prefer it when possible
for (var i = 0; i < 99999; i++) {
$scope.$eval(‘exp’);
}
Putting it together
myApp.directive(function($parse) {
return {
compile: function(elem, attr) {
var fooExp = $parse(attr.foo),
listExp = $parse(attr.list);
return function link(s, elem) {
s.foo = fooExp(s);
scope.$watchCollection(listExp,
function(list) {
// do something
});
};}};});
myApp.directive(function() {
return {
link: function(s, elem, attr) {
s.foo = scope.$eval(attr.foo);
scope.$watch(attr.list,
function(list) {
// do something
}, true);
}};});
$watch only what is needed
Sometimes a deep $watch is needed, but not
for the entire object.
By stripping out irrelevant data, we can make
the comparison much faster.
$scope.$watch(‘listOfBigObjects’,
myHandler, true);
$scope.$watch(function($scope) {
return $scope.listOfBigObjects.
map(function(bigObject) {
return bigObject.foo.
fieldICareAbout;
});
}, myHandler, true);
$watch before transforming, not
after
When applying expensive transformations to
input, watch the input itself for changes rather
than the output of the transformation.
Example:
https://github.com/angular/angular.js/commit/e2
068ad426075ac34c06c12e2fac5f594cc81969
ng-repeat - track by $index
By default, ng-repeat creates a dom node for
each item and destroys that dom node when
the item is removed.
With track by $index, it will reuse dom nodes.
<div ng-repeat=”item in array”>
I live and die by {{item}}.
<div>
<div ng-repeat=”item in array track by
$index”>
I live until {{array.length}} is
less than {{$index}}.
<div>
ng-if vs ng-show
● ng-show hides elements and bindings using
css
● ng-if goes a step further and does not even
create them
o Fewer bindings
o Fewer linkers called at startup
● ng-switch is like ng-if in this respect
Not really a Best Practice:
$$postDigest
● $$ means private to Angular, so be aware
that the interface is not stable
● Fires a callback after the current $digest
cycle completes
● Great for updating the dom once after dirty
checking is over
Avoiding dirty checking altogether
● Sometimes an expression’s output never
changes, but we dirty check it constantly
● Custom directives to the rescue!
o Bind once at link and ignore digest cycles
o Bind at link and dirty check only on certain events
o https://github.com/kseamon/fast-bind/tree/master/
 Implements bind
 class, href, if, switch, etc left as an exercise to
the reader
● Or maybe an optional module in 1.3?
Diagnosing performance problems:
Tools
● AngularJS Batarang
o Great for identifying which $watchers are causing
problems
● Chrome profiler
o Offers a broader view, but harder to read
● performance.now()
o Provides microsecond resolution for measurements
Using AngularJS Batarang
Looks like I should check
out canInlineEditItem.
Using the profiler
PS: Disable minification or you will be sad
Now use
performance.now()
t = 0; c = 0;
var myFunc = function() {
var d = performance.now();
c++;
// some code
// some more code
t += performance.now() - d;
};
Interpreting profiler output: My
function
Interpreting profiler output:
angular.copy & angular.equals
● If you see these in your profile, you probably have some deep $watches
that need to slim down (See Slide 7 and Slide 13)
● Tracking these down is bit tricky - we have to dive into angular.js
window.slowest = 0;
function copy(source, destination, recurse){
if (!recurse) var d = performance.now(), d2;
… copy(source, [], true); …
if (!recurse &&
(d2 = performance.now()) - d > slowest) {
slowest = d2 - d;
console.log(toJson(source), slowest);
console.trace();
}
return destination;
}
An incomplete list of recent
improvements to AngularJS
● 1.2.7 emoji-clairvoyance (2014-01-03)
o Scope: limit propagation of $broadcast to scopes that have listeners
for the event (80e7a455)
● 1.2.6 taco-salsafication (2013-12-19)
o compile: add class 'ng-scope' before cloning and other micro-
optimizations (f3a796e5)
o $parse: use a faster path when the number of path parts is low
(f4462319)
● 1.2.5 singularity-expansion (2013-12-13)
o $resource: use shallow copy instead of angular.copy (fcd2a813)
o jqLite: implement and use the empty method in place of html(‘’)
(3410f65e)
● 1.2.4 wormhole-blaster (2013-12-06)
o Scope: short-circuit after dirty-checking last dirty watcher (d070450c)
Future improvements AngularJS
● 1.3
o Coalesce asynchronous calls to $apply (#5297)
o Built-in bind-once
● Further future (maybe hopefully)
o $postDigestWatch - A public watcher based on $$postDigest for dom
updates (Also update ng-bind, ng-class, et al to use it) (#5828)
o Watcher deduplication (#5829)
o $apply isolation - Set regions (such as dialogs) for which $apply calls
do not affect the whole page (#5830)
o Your ideas - File a ticket! Write a pull request!
Thanks!

More Related Content

What's hot

Map kit light
Map kit lightMap kit light
Map kit light
CocoaHeads France
 
Angularjs Performance
Angularjs PerformanceAngularjs Performance
Angularjs Performance
Steven Lambert
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
ExoLeaders.com
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
Chris Saylor
 
Talk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe ConversetTalk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe Converset
CocoaHeads France
 
Intro to React
Intro to ReactIntro to React
Intro to React
Troy Miles
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
Kacper Gunia
 
JavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineJavaScript Unit Testing with Jasmine
JavaScript Unit Testing with Jasmine
Raimonds Simanovskis
 
Avoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promisesAvoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promises
Ankit Agarwal
 
Realm.io par Clement Sauvage
Realm.io par Clement SauvageRealm.io par Clement Sauvage
Realm.io par Clement Sauvage
CocoaHeads France
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
cacois
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
Visual Engineering
 
Unit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and NodeUnit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and Node
Josh Mock
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
Ignacio Martín
 
Practical JavaScript Promises
Practical JavaScript PromisesPractical JavaScript Promises
Practical JavaScript Promises
Asa Kusuma
 
AngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile ServicesAngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile Services
Rainer Stropek
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
jnewmanux
 
Promises, Promises
Promises, PromisesPromises, Promises
Promises, Promises
Domenic Denicola
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
Domenic Denicola
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
Visual Engineering
 

What's hot (20)

Map kit light
Map kit lightMap kit light
Map kit light
 
Angularjs Performance
Angularjs PerformanceAngularjs Performance
Angularjs Performance
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
 
Talk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe ConversetTalk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe Converset
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
 
JavaScript Unit Testing with Jasmine
JavaScript Unit Testing with JasmineJavaScript Unit Testing with Jasmine
JavaScript Unit Testing with Jasmine
 
Avoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promisesAvoiding callback hell in Node js using promises
Avoiding callback hell in Node js using promises
 
Realm.io par Clement Sauvage
Realm.io par Clement SauvageRealm.io par Clement Sauvage
Realm.io par Clement Sauvage
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
 
Unit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and NodeUnit testing JavaScript using Mocha and Node
Unit testing JavaScript using Mocha and Node
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
 
Practical JavaScript Promises
Practical JavaScript PromisesPractical JavaScript Promises
Practical JavaScript Promises
 
AngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile ServicesAngularJS with TypeScript and Windows Azure Mobile Services
AngularJS with TypeScript and Windows Azure Mobile Services
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
 
Promises, Promises
Promises, PromisesPromises, Promises
Promises, Promises
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 

Similar to Optimizing a large angular application (ng conf)

Gradle - time for another build
Gradle - time for another buildGradle - time for another build
Gradle - time for another build
Igor Khotin
 
AngularJS (1.x) as fast as a lightning
AngularJS (1.x)as fast as a lightningAngularJS (1.x)as fast as a lightning
AngularJS (1.x) as fast as a lightning
Bartłomiej Narożnik
 
AngularJS Best Practices
AngularJS Best PracticesAngularJS Best Practices
AngularJS Best Practices
Narek Mamikonyan
 
Angularjs Anti-patterns
Angularjs Anti-patternsAngularjs Anti-patterns
Angularjs Anti-patterns
Steven Lambert
 
A brief guide to android gradle
A brief guide to android gradleA brief guide to android gradle
A brief guide to android gradle
Leonardo YongUk Kim
 
Angular js meetup
Angular js meetupAngular js meetup
Angular js meetup
Pierre-Yves Gicquel
 
angularjsmeetup-150303044616-conversion-gate01
angularjsmeetup-150303044616-conversion-gate01angularjsmeetup-150303044616-conversion-gate01
angularjsmeetup-150303044616-conversion-gate01
Teo E
 
2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop
Wolfram Arnold
 
AngularJs Crash Course
AngularJs Crash CourseAngularJs Crash Course
AngularJs Crash Course
Keith Bloomfield
 
Dive into Angular, part 3: Performance
Dive into Angular, part 3: PerformanceDive into Angular, part 3: Performance
Dive into Angular, part 3: Performance
Oleksii Prohonnyi
 
Advanced JavaScript Development
Advanced JavaScript DevelopmentAdvanced JavaScript Development
Advanced JavaScript Development
Jussi Pohjolainen
 
GDayX - Advanced Angular.JS
GDayX - Advanced Angular.JSGDayX - Advanced Angular.JS
GDayX - Advanced Angular.JS
Nicolas Embleton
 
Optimizing AngularJS Application
Optimizing AngularJS ApplicationOptimizing AngularJS Application
Optimizing AngularJS Application
Md. Ziaul Haq
 
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletongDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
George Nguyen
 
The Peanut Butter Cup of Web-dev: Plack and single page web apps
The Peanut Butter Cup of Web-dev: Plack and single page web appsThe Peanut Butter Cup of Web-dev: Plack and single page web apps
The Peanut Butter Cup of Web-dev: Plack and single page web apps
John Anderson
 
Dart the Better JavaScript
Dart the Better JavaScriptDart the Better JavaScript
Dart the Better JavaScript
Jorg Janke
 
AngularJS and SPA
AngularJS and SPAAngularJS and SPA
AngularJS and SPA
Lorenzo Dematté
 
PHP Performance Trivia
PHP Performance TriviaPHP Performance Trivia
PHP Performance Trivia
Nikita Popov
 
gDayX - Advanced angularjs
gDayX - Advanced angularjsgDayX - Advanced angularjs
gDayX - Advanced angularjs
gdgvietnam
 
Get your teeth into Plack
Get your teeth into PlackGet your teeth into Plack
Get your teeth into Plack
Workhorse Computing
 

Similar to Optimizing a large angular application (ng conf) (20)

Gradle - time for another build
Gradle - time for another buildGradle - time for another build
Gradle - time for another build
 
AngularJS (1.x) as fast as a lightning
AngularJS (1.x)as fast as a lightningAngularJS (1.x)as fast as a lightning
AngularJS (1.x) as fast as a lightning
 
AngularJS Best Practices
AngularJS Best PracticesAngularJS Best Practices
AngularJS Best Practices
 
Angularjs Anti-patterns
Angularjs Anti-patternsAngularjs Anti-patterns
Angularjs Anti-patterns
 
A brief guide to android gradle
A brief guide to android gradleA brief guide to android gradle
A brief guide to android gradle
 
Angular js meetup
Angular js meetupAngular js meetup
Angular js meetup
 
angularjsmeetup-150303044616-conversion-gate01
angularjsmeetup-150303044616-conversion-gate01angularjsmeetup-150303044616-conversion-gate01
angularjsmeetup-150303044616-conversion-gate01
 
2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop
 
AngularJs Crash Course
AngularJs Crash CourseAngularJs Crash Course
AngularJs Crash Course
 
Dive into Angular, part 3: Performance
Dive into Angular, part 3: PerformanceDive into Angular, part 3: Performance
Dive into Angular, part 3: Performance
 
Advanced JavaScript Development
Advanced JavaScript DevelopmentAdvanced JavaScript Development
Advanced JavaScript Development
 
GDayX - Advanced Angular.JS
GDayX - Advanced Angular.JSGDayX - Advanced Angular.JS
GDayX - Advanced Angular.JS
 
Optimizing AngularJS Application
Optimizing AngularJS ApplicationOptimizing AngularJS Application
Optimizing AngularJS Application
 
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas EmbletongDayX 2013 - Advanced AngularJS - Nicolas Embleton
gDayX 2013 - Advanced AngularJS - Nicolas Embleton
 
The Peanut Butter Cup of Web-dev: Plack and single page web apps
The Peanut Butter Cup of Web-dev: Plack and single page web appsThe Peanut Butter Cup of Web-dev: Plack and single page web apps
The Peanut Butter Cup of Web-dev: Plack and single page web apps
 
Dart the Better JavaScript
Dart the Better JavaScriptDart the Better JavaScript
Dart the Better JavaScript
 
AngularJS and SPA
AngularJS and SPAAngularJS and SPA
AngularJS and SPA
 
PHP Performance Trivia
PHP Performance TriviaPHP Performance Trivia
PHP Performance Trivia
 
gDayX - Advanced angularjs
gDayX - Advanced angularjsgDayX - Advanced angularjs
gDayX - Advanced angularjs
 
Get your teeth into Plack
Get your teeth into PlackGet your teeth into Plack
Get your teeth into Plack
 

Recently uploaded

DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSISDECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
Tier1 app
 
一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理
一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理
一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理
kgyxske
 
Quarter 3 SLRP grade 9.. gshajsbhhaheabh
Quarter 3 SLRP grade 9.. gshajsbhhaheabhQuarter 3 SLRP grade 9.. gshajsbhhaheabh
Quarter 3 SLRP grade 9.. gshajsbhhaheabh
aisafed42
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
Alina Yurenko
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CDKuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
rodomar2
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
Sven Peters
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
Green Software Development
 
14 th Edition of International conference on computer vision
14 th Edition of International conference on computer vision14 th Edition of International conference on computer vision
14 th Edition of International conference on computer vision
ShulagnaSarkar2
 
一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理
dakas1
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
Hornet Dynamics
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Julian Hyde
 
Malibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed RoundMalibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed Round
sjcobrien
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
Quickdice ERP
 
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
safelyiotech
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
Remote DBA Services
 
INTRODUCTION TO AI CLASSICAL THEORY TARGETED EXAMPLES
INTRODUCTION TO AI CLASSICAL THEORY TARGETED EXAMPLESINTRODUCTION TO AI CLASSICAL THEORY TARGETED EXAMPLES
INTRODUCTION TO AI CLASSICAL THEORY TARGETED EXAMPLES
anfaltahir1010
 
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
kalichargn70th171
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
Grant Fritchey
 

Recently uploaded (20)

DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSISDECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
DECODING JAVA THREAD DUMPS: MASTER THE ART OF ANALYSIS
 
一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理
一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理
一比一原版(sdsu毕业证书)圣地亚哥州立大学毕业证如何办理
 
Quarter 3 SLRP grade 9.. gshajsbhhaheabh
Quarter 3 SLRP grade 9.. gshajsbhhaheabhQuarter 3 SLRP grade 9.. gshajsbhhaheabh
Quarter 3 SLRP grade 9.. gshajsbhhaheabh
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
All you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVMAll you need to know about Spring Boot and GraalVM
All you need to know about Spring Boot and GraalVM
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CDKuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
 
Microservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we workMicroservice Teams - How the cloud changes the way we work
Microservice Teams - How the cloud changes the way we work
 
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, FactsALGIT - Assembly Line for Green IT - Numbers, Data, Facts
ALGIT - Assembly Line for Green IT - Numbers, Data, Facts
 
14 th Edition of International conference on computer vision
14 th Edition of International conference on computer vision14 th Edition of International conference on computer vision
14 th Edition of International conference on computer vision
 
一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理一比一原版(USF毕业证)旧金山大学毕业证如何办理
一比一原版(USF毕业证)旧金山大学毕业证如何办理
 
E-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet DynamicsE-commerce Development Services- Hornet Dynamics
E-commerce Development Services- Hornet Dynamics
 
Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)Measures in SQL (SIGMOD 2024, Santiago, Chile)
Measures in SQL (SIGMOD 2024, Santiago, Chile)
 
Malibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed RoundMalibou Pitch Deck For Its €3M Seed Round
Malibou Pitch Deck For Its €3M Seed Round
 
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian CompaniesE-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
E-Invoicing Implementation: A Step-by-Step Guide for Saudi Arabian Companies
 
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
Safelyio Toolbox Talk Softwate & App (How To Digitize Safety Meetings)
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
 
INTRODUCTION TO AI CLASSICAL THEORY TARGETED EXAMPLES
INTRODUCTION TO AI CLASSICAL THEORY TARGETED EXAMPLESINTRODUCTION TO AI CLASSICAL THEORY TARGETED EXAMPLES
INTRODUCTION TO AI CLASSICAL THEORY TARGETED EXAMPLES
 
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
A Comprehensive Guide on Implementing Real-World Mobile Testing Strategies fo...
 
Using Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query PerformanceUsing Query Store in Azure PostgreSQL to Understand Query Performance
Using Query Store in Azure PostgreSQL to Understand Query Performance
 

Optimizing a large angular application (ng conf)

  • 1. Optimizing a Large AngularJS Application Karl Seamon Senior Software Engineer, Google Occasional contributor to AngularJS
  • 2. Topics ● The Problems ● Basics and Best Practices ● Diagnosing performance problems ● Improving performance within AngularJS
  • 3. The Problems: What can make an Angular app slow? ● Anything that could affect a normal JS app o Slow DOM o Single-threaded o etc ● Inefficient directives o link vs compile o $parse vs $eval vs interpolation ● Dirty checking o Lots of watchers o Slow watchers o Too many calls to $apply
  • 4. What does slow mean? ● $apply > 25ms ● Click handler > 100ms ● Show a new page > 1s o > 10s -> users will give up o 200ms or less is ideal
  • 5. Directives: compile, link, and constructor ● When a directive appears inside of a repeater o compile is called only once o link and the constructor are called once per iteration ● When creating directives, try to get as much work done as possible in the compile step (or even earlier, in the factory) ● Example o https://github.com/angular/angular.js/commit/f3a796 e522afdbd3b640d14426edb2fbfab463c5
  • 6. Directives: Transclusion ● For directives that wrap other content ● Allows your directive to $digest its own scope without causing dirty checks on bindings in the user-provided contents
  • 7. $digest and $apply ● Angular’s documentation favors $apply o Simpler to use $apply all the time o $apply has special error handling that $digest lacks ● So what’s $digest for? o $apply = $rootScope.$digest + some other stuff o If you update a child scope s, you can call s.$digest to dirty-check only that s and its descendants
  • 8. Watchers scope.$watch(valueExpression, changeExpression, ...) valueExpression will be executed many times - Make sure it is fast! Avoid touching the dom (_.debounce can help).
  • 9. $watch and $watchCollection, con’t ● $watch has two comparison modes o referential (default) - quick, shallow comparison o deep - slow, recurses through objects for a deep comparison; also makes a deep copy of the watched value each time it changes ● Avoid deep $watch whenever possible
  • 10. $watchCollection ● new in 1.2, used by ng-repeat ● Goes one level deep into the watched array or object ● A nice alternative to deep $watch in many cases
  • 11. ● $interpolate: returns function that evals “a string {{like}} this” ● $parse: returns function that evals “an.expression” ● $scope.$eval: evaluates “an.expression” (using $parse) $eval, $parse, and $interpolate
  • 12. var parsedExp = $parse(‘exp’); for (var i = 0; i < 99999; i++) { parsedExp($scope); } $eval, $parse, and $interpolate, con’t ● Better to call $parse once and save the function than to call $eval many times ● $parse is much faster than $interpolate, prefer it when possible for (var i = 0; i < 99999; i++) { $scope.$eval(‘exp’); }
  • 13. Putting it together myApp.directive(function($parse) { return { compile: function(elem, attr) { var fooExp = $parse(attr.foo), listExp = $parse(attr.list); return function link(s, elem) { s.foo = fooExp(s); scope.$watchCollection(listExp, function(list) { // do something }); };}};}); myApp.directive(function() { return { link: function(s, elem, attr) { s.foo = scope.$eval(attr.foo); scope.$watch(attr.list, function(list) { // do something }, true); }};});
  • 14. $watch only what is needed Sometimes a deep $watch is needed, but not for the entire object. By stripping out irrelevant data, we can make the comparison much faster. $scope.$watch(‘listOfBigObjects’, myHandler, true); $scope.$watch(function($scope) { return $scope.listOfBigObjects. map(function(bigObject) { return bigObject.foo. fieldICareAbout; }); }, myHandler, true);
  • 15. $watch before transforming, not after When applying expensive transformations to input, watch the input itself for changes rather than the output of the transformation. Example: https://github.com/angular/angular.js/commit/e2 068ad426075ac34c06c12e2fac5f594cc81969
  • 16. ng-repeat - track by $index By default, ng-repeat creates a dom node for each item and destroys that dom node when the item is removed. With track by $index, it will reuse dom nodes. <div ng-repeat=”item in array”> I live and die by {{item}}. <div> <div ng-repeat=”item in array track by $index”> I live until {{array.length}} is less than {{$index}}. <div>
  • 17. ng-if vs ng-show ● ng-show hides elements and bindings using css ● ng-if goes a step further and does not even create them o Fewer bindings o Fewer linkers called at startup ● ng-switch is like ng-if in this respect
  • 18. Not really a Best Practice: $$postDigest ● $$ means private to Angular, so be aware that the interface is not stable ● Fires a callback after the current $digest cycle completes ● Great for updating the dom once after dirty checking is over
  • 19. Avoiding dirty checking altogether ● Sometimes an expression’s output never changes, but we dirty check it constantly ● Custom directives to the rescue! o Bind once at link and ignore digest cycles o Bind at link and dirty check only on certain events o https://github.com/kseamon/fast-bind/tree/master/  Implements bind  class, href, if, switch, etc left as an exercise to the reader ● Or maybe an optional module in 1.3?
  • 20. Diagnosing performance problems: Tools ● AngularJS Batarang o Great for identifying which $watchers are causing problems ● Chrome profiler o Offers a broader view, but harder to read ● performance.now() o Provides microsecond resolution for measurements
  • 21. Using AngularJS Batarang Looks like I should check out canInlineEditItem.
  • 22. Using the profiler PS: Disable minification or you will be sad
  • 23. Now use performance.now() t = 0; c = 0; var myFunc = function() { var d = performance.now(); c++; // some code // some more code t += performance.now() - d; }; Interpreting profiler output: My function
  • 24. Interpreting profiler output: angular.copy & angular.equals ● If you see these in your profile, you probably have some deep $watches that need to slim down (See Slide 7 and Slide 13) ● Tracking these down is bit tricky - we have to dive into angular.js window.slowest = 0; function copy(source, destination, recurse){ if (!recurse) var d = performance.now(), d2; … copy(source, [], true); … if (!recurse && (d2 = performance.now()) - d > slowest) { slowest = d2 - d; console.log(toJson(source), slowest); console.trace(); } return destination; }
  • 25. An incomplete list of recent improvements to AngularJS ● 1.2.7 emoji-clairvoyance (2014-01-03) o Scope: limit propagation of $broadcast to scopes that have listeners for the event (80e7a455) ● 1.2.6 taco-salsafication (2013-12-19) o compile: add class 'ng-scope' before cloning and other micro- optimizations (f3a796e5) o $parse: use a faster path when the number of path parts is low (f4462319) ● 1.2.5 singularity-expansion (2013-12-13) o $resource: use shallow copy instead of angular.copy (fcd2a813) o jqLite: implement and use the empty method in place of html(‘’) (3410f65e) ● 1.2.4 wormhole-blaster (2013-12-06) o Scope: short-circuit after dirty-checking last dirty watcher (d070450c)
  • 26. Future improvements AngularJS ● 1.3 o Coalesce asynchronous calls to $apply (#5297) o Built-in bind-once ● Further future (maybe hopefully) o $postDigestWatch - A public watcher based on $$postDigest for dom updates (Also update ng-bind, ng-class, et al to use it) (#5828) o Watcher deduplication (#5829) o $apply isolation - Set regions (such as dialogs) for which $apply calls do not affect the whole page (#5830) o Your ideas - File a ticket! Write a pull request!

Editor's Notes

  1. Angular Working Group too, seemingly.
  2. For show a new page, it does not have to be fully loaded at that point, just ready enough to show some content. Showing feedback helps mitigate delays.
  3. Deep watch is enabled by passing true as the third argument to $watch.
  4. This advice is at odds with the previous slide - take it on a case by case basis.
  5. But it will still remove them if the array shrinks.
  6. The dom will still be compiled at startup, so if that is too much, you’ll need to employ a custom directive.
  7. We’ve developed a number of these directives in-house. We hoped to get them open-sourced in time for the conference, but it did not happen. So I made a toy implementation to show off the idea.
  8. The profiler is a good for getting an idea of where your problems lie. I prefer the top-down tree view with measured time rather than percentages. Just sort by total time and dig your way down.
  9. So the profiler shows you that one of your functions is slow. Now you can use performance.now() to get more info. You can move these lines around in your function to figure out which part(s) are the culprit.
  10. The output you see from this will vary depending on your data
  11. This list is not comprehensive, see the changelog for more