@ebidel @polymer #polymersummit
optimizing load & first paint
LOAD
optimization tips for minimizing in-app jank
RENDER
future APIs for performance
FUTURE
Slide 4
Slide 4 text
the extent to which an investment is
profitable, especially in relation to
other investments.
PERFORMANCE noun -
Slide 5
Slide 5 text
the extent to which an investment is
profitable, especially in relation to
other investments.
PERFORMANCE noun -
Slide 6
Slide 6 text
the extent to which an investment is
profitable, especially in relation to
other investments.
PERFORMANCE noun -
app
apps
usable
Slide 7
Slide 7 text
DELAY USER REACTION
0 - 100 ms Instant
100 - 300 ms Slight perceptable delay
300 - 1000 ms Task focus, perceptable delay
1000+ ms Mental context swtich
10,000+ ms I’ll come back later!
User perception-reaction times
http://goo.gl/7noSwL
Slide 8
Slide 8 text
No content
Slide 9
Slide 9 text
No content
Slide 10
Slide 10 text
0
150
300
450
600
Time
3x faster
CHROME
0
750
1500
2250
3000
Time
4x faster
iOS SAFARI
Slide 11
Slide 11 text
LOAD
optimizations
Slide 12
Slide 12 text
...
Slide 13
Slide 13 text
thistock.im
WE CAN
DO BETTER.
Slide 14
Slide 14 text
Slide 15
Slide 15 text
Slide 16
Slide 16 text
Slide 17
Slide 17 text
HTML Imports do not block
parsing but they do block
page rendering.
Slide 18
Slide 18 text
Slide 19
Slide 19 text
Make it async if you don’t
want to block rendering.
Slide 20
Slide 20 text
HTML IMPORTS
Slide 21
Slide 21 text
var foo = document.createElement(’x-foo‘);
foo.bar = {baz: true};
Why are HTML Imports not async by default?
Slide 22
Slide 22 text
Dynamically load an HTML Import
function importPage(url) {
return new Promise(function(resolve, reject) {
resolve(e.target.import);
}, reject);
});
};
Polymer.Base.importHref(url, function(e) {
importPage(‘/path/to/import.html’).then(doStuff);
Slide 23
Slide 23 text
Dynamically load an HTML Import
function
resolve
};
Dynamically creates and loads
Polymer.Base.importHref(url, function(e) {
importPage
Slide 24
Slide 24 text
Dynamically load an HTML Import
function importPage(url) {
return new Promise(function(resolve, reject) {
resolve(e.target.import);
}, reject);
});
};
Dynamically creates and loads
Polymer.Base.importHref(url, function(e) {
importPage(‘/path/to/import.html’).then(doStuff);
Slide 25
Slide 25 text
...
Declarative imports load faster
Slide 26
Slide 26 text
Declarative imports load faster
Slide 27
Slide 27 text
unresolved
Slide 28
Slide 28 text
Slide 29
Slide 29 text
...
Slide 30
Slide 30 text
...
“Fast load skeleton”
Async all the things. Control FOUC ourselves!
Slide 31
Slide 31 text
thistock.im
WE CAN
DO BETTER.
Slide 32
Slide 32 text
...
Slide 33
Slide 33 text
Slide 34
Slide 34 text
...
Slide 35
Slide 35 text
...
Slide 36
Slide 36 text
var webComponentsSupported = (
'registerElement' in document &&
'import' in document.createElement('link') &&
'content' in document.createElement('template'));
Lazy load the web component polyfills
Slide 37
Slide 37 text
var webComponentsSupported = (
'registerElement' in document &&
'import' in document.createElement('link') &&
'content' in document.createElement('template'));
if (!webComponentsSupported) {
var script = document.createElement('script');
script.async = true;
script.src = 'webcomponents-lite.min.js';
script.onload = finishLazyLoading;
document.head.appendChild(script);
} else {
finishLazyLoading();
}
Lazy load the web component polyfills
Slide 38
Slide 38 text
( DevTools emulation - Good 3G )
1430ms
first paint
230ms
first paint
6.2x
faster
OLD NEW
Stock Ticker App
Slide 39
Slide 39 text
( DevTools emulation - Good 3G )
1430ms
first paint
230ms
first paint
6.2x
faster
OLD NEW
Stock Ticker App
Slide 40
Slide 40 text
No content
Slide 41
Slide 41 text
No content
Slide 42
Slide 42 text
ASYNC
Slide 43
Slide 43 text
ASYNC
Slide 44
Slide 44 text
SYNC
Slide 45
Slide 45 text
SYNC
Slide 46
Slide 46 text
FOUC
thistock.im
f
Slide 47
Slide 47 text
...
Slide 48
Slide 48 text
...
Slide 49
Slide 49 text
CUSTOM ELEMENTS
PROGRESSIVELY ENHANCED MARKUP
ARE
ASIDE
Cable connection ( DESKTOP )
webpagetest.org results: https://goo.gl/LY0sxj
589ms
first paint
1s
total load
Slide 67
Slide 67 text
1144
speed index
Cable connection ( DESKTOP )
webpagetest.org results: https://goo.gl/LY0sxj
589ms
first paint
1s
total load
Slide 68
Slide 68 text
3G Fast connection ( MOTO G )
webpagetest.org results: https://goo.gl/LY0sxj
Slide 69
Slide 69 text
3G Fast connection ( MOTO G ) 1.66s
first paint
webpagetest.org results: https://goo.gl/LY0sxj
Slide 70
Slide 70 text
3G Fast connection ( MOTO G ) 1.66s
first paint
~ 7s
total load
webpagetest.org results: https://goo.gl/LY0sxj
Slide 71
Slide 71 text
3G Fast connection ( MOTO G )
5614
speed index
1.66s
first paint
~ 7s
total load
webpagetest.org results: https://goo.gl/LY0sxj
Slide 72
Slide 72 text
No content
Slide 73
Slide 73 text
No content
Slide 74
Slide 74 text
PolyMail poly-mail.appspot.com
Slide 75
Slide 75 text
PolyMail poly-mail.appspot.com
Slide 76
Slide 76 text
@ebidel @polymer #polymersummit
Changes for fast load
1.Make HTML Imports
2.Conditionally load the polyfills (or make
3.Manually control FOUC instead of using
4.Load critical “app shell”
Slide 77
Slide 77 text
RENDER
optimizations
Slide 78
Slide 78 text
QUICK TIPS for
Slide 79
Slide 79 text
window.Polymer = window.Polymer || {dom: ‘shadow'};
Use native shadow DOM ( it’s faster )
Slide 80
Slide 80 text
Use touch events instead of click events
Slide 81
Slide 81 text
Yo, don’t jank those ripples
Add a new feature
Polymer({
_navAfterRipple: function(e) {
e.preventDefault();
this._href = Polymer.dom(e).localTarget.href; // save reference
}
_doNav: function(e) {
var href = this._href;
if (href) {
this._href = null; // clear
location.href = href;
}
}
});
Ripple jank on page navigations
Slide 82
Slide 82 text
Yo, don’t jank those ripples
Add a new feature
Polymer({
_navAfterRipple: function(e) {
e.preventDefault();
this._href = Polymer.dom(e).localTarget.href; // save reference
}
_doNav: function(e) {
var href = this._href;
if (href) {
this._href = null; // clear
location.href = href;
}
}
});
Ripple jank on page navigations
@ebidel @polymer #polymersummit
Polydev Chrome extension
know the costs of your elements
goo.gl/pgPeCE
source: github.com/polymerlabs/polydev
Slide 110
Slide 110 text
@ebidel @polymer #polymersummit
Polymer perf bookmarklet
know your app’s metrics
‣ Time to first paint & page load
‣ HTML Import load times ( main page )
‣ # of custom element instances
‣ Element properties using
goo.gl/vkJHWm