snappy means happy: performance in ember apps
DESCRIPTION
Ember is fast. Ember Core is working hard to make Ember even faster. So why does your app drag? The performance of a single-page app is impacted by the performance characteristics of its foundational parts: Network, Rendering, and JavaScript. Ember provides tools to manage these cornerstones, but with the tradeoff of introducing its own characteristics. In this talk, we will use the source of real, shipped Ember apps (and of Ember itself) to diagnose, understand, and improve slow interactions. The Chrome developer tools will help us understand slow code paths and identify opportunities for improvement. Along the way, we will learn how parts of Ember work at the macro and micro level and learn how the framework helps us manage performance challenges in a browser environment.TRANSCRIPT
Jakob Nielsen sez
100 ms
1 second
10 seconds
instant
uninterrupted work
the limit of attention
www.nngroup.com/articles/response-times-3-important-limits/
Ilya Grigorik sez
0 - 100ms
100 - 300ms
300 - 1000ms
1 second +
10 seconds +
Instant
slight perceptible delay
perceptible delay
mental context switch
“I’ll come back later”youtu.be/7ubJzEi3HuA?t=4m25s
Network
Render
NetworkRender
JavaScript
uni.madhatted.com/emberconf/github-list/index.html
Animation, < 16ms
Javascript renDer
Snappy, less than 300 ms
Javascript renDerNetwork
One second and beyond
JavascriptNetwork
Speeding up emberjs.com on a phone
ember.js website, why so slow?
Analyze using a latency emulator & Chrome devtools “Network” tab
Charles - www.charlesproxy.com
Slowy - slowyapp.com
Network Link Conditioner - developer.apple.com/...
#1 reproduce mobile latency reliably
#2 create a clean browser environment
No extensions, private window
support.google.com/chrome/answer/2364824?hl=en
#3 measurement & analysis
developers.google.com/chrome-developer-tools/docs/network
✦ Script at the bottom
✦ script async/defer
✦ explicitly load webfont in HTML (via script or link tag)
#4 Solutions
#5 confirm the theory
https://github.com/emberjs/website/pull/1337
www.amazon.com/High-Performance-Browser-Networking-performance/dp/1449344763
Making an animation smooth
Janky animation
Using continuous paint, composited borders, Chrome devtools “Timeline”
#2 Measure
Summary
developers.google.com/chrome-developer-tools/docs/timeline
Better summary
Frames
#2 Measure
developers.google.com/chrome-developer-tools/docs/timeline#frames_mode
JavaScript
#2 Measure
developers.google.com/chrome-developer-tools/docs/timeline#frames_mode
Paint
#2 Measure
developers.google.com/chrome-developer-tools/docs/timeline#frames_mode
Upload to GPU,Compositing
#2 Measure
developers.google.com/chrome-developer-tools/docs/timeline#frames_mode
Open a render console
Special render options
#2 Measure
developers.google.com/chrome-developer-tools/docs/timeline#frames_mode
Live coding OMG.
debugging a janky animation
uni.madhatted.com/emberconf/animation-initial/index.html
uni.madhatted.com/emberconf/animation/index.html
uni.madhatted.com/emberconf/animation-second/index.html
screencast.com/t/TqtMmnvhiQg screencast.com/t/Hl6krsx3lN
1 var person = Ember.Object.extend({ 2 name: 'rick' 3 logNameChange: function(){ 4 console.log('observing name!'); 5 }.observes('name') 6 }); 7 8 person.set('name', 'bob'); 9 console.log('after name!');
#1 understanding observers
1 var person = Ember.Object.extend({ 2 name: 'rick' 3 logNameChange: function(){ 4 console.log('observing name!'); 5 }.observes('name') 6 }); 7 8 person.set('name', 'bob'); 9 console.log('after name!');
Logs first
observers are synchronous
1 var person = Ember.Object.extend({ 2 name: 'rick' 3 somethingExpensive: function(){ 4 // Something really heavy 5 }.observes('name', 'age', 'shoeSize') 6 }); 7 8 person.set('name', 'bob'); 9 person.set('age', 25); 10 person.set('shoeSize', 11);
somethingExpensive, x3
observers are synchronous
1 var person = Ember.Object.extend({ 2 name: 'rick' 3 scheduleSomethingExpensive: function(){ 4 Ember.run.once(this, this.somethingExpensive); 5 }.observes('name', 'age', 'shoeSize'), 6 somethingExpensive: function(){ 7 // Something really heavy 8 } 9 }); 10 11 person.set('name', 'bob'); 12 person.set('age', 25); 13 person.set('shoeSize', 11);
somethingExpensive, once
observers are synchronous
#2 profiler
Processing
Memory
developers.google.com/chrome-developer-tools/docs/cpu-profiling
#2 profiler
Modesdevelopers.google.com/chrome-developer-tools/docs/cpu-profiling#flame-chart
#2 profiler
Runloop
jQuery
View Event
developers.google.com/chrome-developer-tools/docs/cpu-profiling#flame-chart
#2 profiler
developers.google.com/chrome-developer-tools/docs/cpu-profiling#flame-chart
#2 profiler
Ember.run(function
developers.google.com/chrome-developer-tools/docs/cpu-profiling#flame-chart
#2 profiler
Queues
developers.google.com/chrome-developer-tools/docs/cpu-profiling#flame-chart
Live coding OMG.
debugging a slow list render
uni.madhatted.com/emberconf/push-into-array/index.html
uni.madhatted.com/emberconf/push-into-array-optimized/index.html
screencast.com/t/GMIHB4q4xyr screencast.com/t/xEagiQzyz
Thanks!
@mixonic
httP://madhatted.com