looking for
the holy grail of
MOBILE WEB PERFORMANCE
Adam Bar
performance
The biggest mistake we made as a company was betting too much on HTML5 instead of native
source: statcounter
june 2017 in poland
63%
looking for
the holy grail of
MOBILE WEB PERFORMANCE
Adam Bar
source: soasta
source: soasta
-
network throughput & latency
performance is...
-
server-side throughput
-
page load & render time, including script execution time
-
animations & interactions smoothness
-
PErceived performance (UX)
-
network throughput & latency
performance is...
-
server-side throughput
-
page load & render time, including script execution time
-
animations & interactions smoothness
-
PErceived performance (UX)
network
load & render
runtime
Case study: before
FP: 7.04 s
FMP: 9.76 s
network throughput
& latency
network
load & render
runtime
http/2
network
load & render
runtime
www.http2demo.io
network
load & render
runtime
Case study: with http/2
Before:
FP: 7.04 s
FMP: 9.76 s
after:
FP: 6.84 s
FMP: 9.53 s
http/2 Server push
index.html
index.html
style.css
script.js
network
load & render
runtime
Preload & prefetch
<link rel="preload" as="font" crossorigin="anonymous"
type="font/woff2" href="..." />
<link rel="preload" as="image"
type="image/png" href="..." />
<link rel="prefetch" href="next.html" />
network
load & render
runtime
Case study: with preload
before:
FP: 6.84 s
FMP: 9.53 s
after:
F(M)P: 8.04 s
dns-prefetch
<link rel="dns-prefetch" href="//example.com" />
preconnect
<link rel="preconnect" href="https://example.com" />
prerender
<link rel="prerender" href="https://example.com" />
network
load & render
runtime
content delivery networks
network
load & render
runtime
Plain old http caching
Cache-Control: public, max-age=31536000
// for immutable content
Cache-Control: no-cache
// for mutable content
service worker
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
});
network
load & render
runtime
Case study: with cache
No cache:
F(M)P: 8.04 s
with cache:
F(M)P: 2.62 s
Case study: with SW
No cache:
F(M)P: 8.04 s
with cache:
F(M)P: 2.62 s
with sw:
F(M)P: 0.67 s
critical rendering path
network
load & render
runtime
critical rendering path
index.html
styles.css
nasty_ads.js
download
network
load & render
runtime
critical rendering path
index.html
styles.css
nasty_ads.js
rendering
?
network
load & render
runtime
critical rendering path
index.html
styles.css
nasty_ads.js
rendering
css blocks rendering
network
load & render
runtime
critical rendering path
index.html
styles.css
nasty_ads.js
scripting
?
network
load & render
runtime
critical rendering path
index.html
styles.css
nasty_ads.js
scripting
css blocks scripting
!
network
load & render
runtime
critical rendering path
index.html
styles.css
nasty_ads.js
parsing
?
network
load & render
runtime
critical rendering path
index.html
styles.css
nasty_ads.js
parsing
JS download blocks parsing
!
network
load & render
runtime
critical rendering path
index.html
styles.css
nasty_ads.js
parsing
JS download blocks parsing
...unless async
<script src="nasty_ads.js" async></script>
network
load & render
runtime
critical rendering path
index.html
styles.css
nasty_ads.js
parsing
JS execution blocks parsing
network
load & render
runtime
critical rendering path
index.html
styles.css
nasty_ads.js
parsing
JS execution blocks parsing
...unless defer
<script src="nasty_ads.js" defer></script>
network
load & render
runtime
use streamed html parsing
inline above-the-fold css
network
load & render
runtime
defer loading rest of css
website obesity crisis
http://idlewords.com/talks/website_obesity.htm
network
load & render
runtime
cost-of-modules.herokuapp.com
network
load & render
runtime
network
load & render
runtime
network
load & render
runtime
https://aerotwist.com/blog/the-cost-of-frameworks/
load
parse
compile
execute
react on iphone 5s:
118 ms
network
load & render
runtime
network
load & render
runtime
https://whatdoesmysitecost.com
-
tree-shaking
-
code splitting
-
critical thinking & common sense
network
load & render
runtime
Case study: unbloated
Before:
CSS: 46 kB
JS: 137 kB
after:
CSS: 11 kB
JS: 78 kB
FP: 5.25 s
FMP: 5.98 s
F(M)P: 8.04 s
26% faster!
image optimization
-
format & compression
-
responsiveness via srcset attribute or <picture> element
<img src="small.jpg" srcset="medium.jpg 1000w, large.jpg 2000w">
network
load & render
runtime
runtime performance
network
load & render
runtime
pixel pipeline
1 s / 60 frames = ~16 ms/frame
60 fps
style
layout
paint
composite
HTML/JS
network
load & render
runtime
https://csstriggers.com
.moving-element {
will-change: transform;
}
network
load & render
runtime
beware of scroll event
~16 ms
style
layout
paint
composite
JavaScript
network
load & render
runtime
beware of scroll event
network
load & render
runtime
...and wheel events
...and touch events
document.addEventListener(
'touchstart', handler, {passive: true});
requestAnimationFrame
function animationStep() {
// animate
requestAnimationFrame(animationStep);
}
requestAnimationFrame(animationStep);
requestIdleCallback
function heavyComputation() { /* ... */ }
requestIdleCallback(heavyComputation);
network
load & render
runtime
look for easy wins
prioritize performance
ship less code
look for easy wins
prioritize performance
ship less code
https://slides.com/adambar/mobilewebperf
Adam Bar
@NOtherDev
Looking for the Holy Grail of Mobile Web Performance - DevConf
By Adam Bar
Looking for the Holy Grail of Mobile Web Performance - DevConf
- 1,729