The
Hitchhiker's Guide
to the Front-End
Performance
The
Hitchhiker's Guide
to the Front-End
Performance 2018
EDITION
Slide 2
Slide 2 text
Who the hell am I?
Who the hell am I?
Slide 3
Slide 3 text
˜ @ythecombinator on the webs
˜ Engineering Leader, Front-End
@beakyn
˜ previously @Apple Developer
Academy and unemployed indie
developer software consultant
˜ addicted to emojis, memes and beer
˜ this (
) means #after
What do we know
about perf?
What do we know
about perf?
Slide 13
Slide 13 text
“Feijão com
Arroz” seal
˜ GZIP everything
˜ Minify both CSS and JS
˜ HTML must be compressed
˜ CSS goes on
˜ JS goes lastly on
˜ Optimize all the images (e.g. svgo)
Slide 14
Slide 14 text
Issues I was facing
Issues I was facing
Slide 15
Slide 15 text
˜ What I do at …
Slide 16
Slide 16 text
˜ What I do at …
Slide 17
Slide 17 text
No content
Slide 18
Slide 18 text
No content
Slide 19
Slide 19 text
˜ Perf ˜
Slide 20
Slide 20 text
˜ JavaScript ˜
Slide 21
Slide 21 text
"Write modern,
idiomatic JavaScript,
and let the JavaScript
engine worry about
making it fast."
- Mathias Bynens, BrazilJS 2018
Slide 22
Slide 22 text
˜ JavaScript ˜
Slide 23
Slide 23 text
Before version 5.9 of V8 came out, the engine used
two compilers:
˜ Full Codegen A simple and very fast compiler that
produced simple and relatively slow machine code
˜ Crankshaft A more complex (Just-In-Time)
optimizing compiler that produced highly-optimized
code
Slide 24
Slide 24 text
Optimization Killers
Slide 25
Slide 25 text
Optimization Killers
~ Generators and async functions
~ for-of and destructuring
~ try-catch and try-finally
~ Compound let or const assignment
~ Object literals that contain __proto__, or get or set declarations.
~ debugger or with statements
~ Literal calls to eval()
~ …
Slide 26
Slide 26 text
Performance cliffs in Crankshaft
(function good() {
const start = Date.now();
for (var i = 0; i < 1e8; i++) {}
console.log(Date.now() - start);
})();
˜80ms
(function bad() {
const start = Date.now();
for (var i = 0; i < 1e8; i++) {}
console.log(Date.now() - start);
const whatever = 1;
})();
˜230ms
Slide 27
Slide 27 text
Performance cliffs in Crankshaft
(function good() {
const start = Date.now();
for (var i = 0; i < 1e8; i++) {}
console.log(Date.now() - start);
})();
(function bad() {
const start = Date.now();
for (var i = 0; i < 1e8; i++) {}
console.log(Date.now() - start);
const whatever = 1;
})();
˜3x slowdown with Crankshaft
Slide 28
Slide 28 text
No content
Slide 29
Slide 29 text
The new execution pipeline is
built on top of Ignition, V8’s
interpreter, and TurboFan, V8’s
newest optimizing compiler.
Slide 30
Slide 30 text
Optimization Killers
~ Generators and async functions
~ for-of and destructuring
~ try-catch and try-finally
~ Compound let or const assignment
~ Object literals that contain __proto__, or get or set declarations.
~ debugger or with statements
~ Literal calls to eval()
~ …
Slide 31
Slide 31 text
60% faster web developer tools
http://v8project.blogspot.com/2017/11/web-tooling-benchmark.html
"Write modern,
idiomatic JavaScript,
and let the JavaScript
engine worry about
making it fast."
- Mathias Bynens, BrazilJS 2018
Slide 34
Slide 34 text
No content
Slide 35
Slide 35 text
˜ #1 ˜
Arrays
Slide 36
Slide 36 text
˜ What can %& do…
˜ Avoid pre-allocating large arrays
˜ Don’t delete elements in arrays
˜ What it does…
Sparse arrays which don’t have every element
inside them are a hash table. Elements in such
arrays are more expensive to access.
Slide 37
Slide 37 text
˜ #2 ˜
Properties
Slide 38
Slide 38 text
˜ What can %& do…
˜ Always instantiate your object properties in
the same order
˜ Assign all of an object’s properties in its
constructor
Slide 39
Slide 39 text
function Point(x, y) {
this.x = x;
this.y = y;
}
var p1 = new Point(1, 2);
Slide 40
Slide 40 text
function Point(x, y) {
this.x = x;
this.y = y;
}
var p1 = new Point(1, 2);
Point C0
Slide 41
Slide 41 text
function Point(x, y) {
this.x = x;
this.y = y;
}
var p1 = new Point(1, 2);
Point C1
For x, see
offset 0
C0
If x is added,
transition to C1
Slide 42
Slide 42 text
Point C2
function Point(x, y) {
this.x = x;
this.y = y;
}
var p1 = new Point(1, 2);
C1
For x, see
offset 0
If y is added,
transition to C2
For x, see
offset 0
For y, see
offset 1
C0
If x is added,
transition to C1
Slide 43
Slide 43 text
function Point(x, y) {
this.x = x;
this.y = y;
}
var p1 = new Point(1, 2);
p1.a = 5;
p1.b = 6;
var p2 = new Point(3, 4);
p2.b = 7;
p2.a = 8;
Slide 44
Slide 44 text
function Point(x, y) {
this.x = x;
this.y = y;
}
var p1 = new Point(1, 2);
p1.a = 5;
p1.b = 6;
var p2 = new Point(3, 4);
p2.b = 7;
p2.a = 8;
Slide 45
Slide 45 text
function Point(x, y) {
this.x = x;
this.y = y;
}
var p1 = new Point(1, 2);
p1.a = 5;
p1.b = 6;
var p2 = new Point(3, 4);
p2.b = 7;
p2.a = 8;
Slide 46
Slide 46 text
˜ Always instantiate your object properties in
the same order
˜ Assign all of an object’s properties in its
constructor
Slide 47
Slide 47 text
No content
Slide 48
Slide 48 text
˜ fixing perf issues be like ˜
Slide 49
Slide 49 text
˜ fixing perf issues be like ˜
Slide 50
Slide 50 text
˜ Problems ˜
Slide 51
Slide 51 text
˜ #1 ˜
Critical Resources Late Delivered
Slide 52
Slide 52 text
˜ Connecting to critical origins (preconnect)
˜ Asset for current page (preload)
˜ Asset for future navigation (prefetch)
Slide 53
Slide 53 text
˜ Connecting to critical origins (preconnect)
˜ Asset for current page (preload)
˜ Asset for future navigation (prefetch)
Slide 54
Slide 54 text
˜ What says…
˜ What can %& do…
Slide 55
Slide 55 text
˜ What it does…
Preconnect allows the browser to setup early connections
before an HTTP request is actually sent to the server. This
includes:
˜ DNS lookups
˜ TLS negotiations
˜ TCP handshakes
This in turn:
✔ Eliminates roundtrip latency
✔ Saves time for users
Slide 56
Slide 56 text
˜ Bring me the !
100MS 200MS 300MS 400MS 500MS 600MS 700MS
HTML
CSS
FONT 1
FONT 2
Fonts start loading Fonts rendered
Slide 57
Slide 57 text
˜ Bring me the !
100MS 200MS 300MS 400MS 500MS 600MS 700MS
HTML
CSS
FONT 1
FONT 2
Fonts start loading Fonts rendered
FONT 1
FONT 2
Slide 58
Slide 58 text
˜ Can I use?
Slide 59
Slide 59 text
˜ Connecting to critical origins (preconnect)
˜ Asset for current page (preload)
˜ Asset for future navigation (prefetch)
Slide 60
Slide 60 text
˜ What says…
˜ What can %& do…
Slide 61
Slide 61 text
˜ What it does…
Some of the benefits of the preload directive include:
✔ Gives the browser the ability to determine the resource
type (it can tell if the same resource can be reused in the
future)
✔ The browser can determine if the request is compliant
with the content security policy
✔ The browser can send the appropriate accept headers based
on resource type
Slide 62
Slide 62 text
˜ Can I use?
Slide 63
Slide 63 text
˜ Connecting to critical origins (preconnect)
˜ Asset for current page (preload)
˜ Asset for future navigation (prefetch)
Slide 64
Slide 64 text
˜ What it does…
✔ Fetch resources in the background (idle time)
✔ Store them in the browser’s cache
It can be:
Slide 65
Slide 65 text
Link Prefetching DNS Prefetching Prerendering
Slide 66
Slide 66 text
Link Prefetching DNS Prefetching Prerendering
˜ What it does…
Allows the browser to fetch resources, store them in cache,
assuming that the user will request them.
˜ What can %& do…
Slide 67
Slide 67 text
Link Prefetching DNS Prefetching Prerendering
˜ What it does…
Allows the browser to perform DNS lookups on a page in the
background while the user is browsing.
˜ What can %& do…
Slide 68
Slide 68 text
Link Prefetching DNS Prefetching Prerendering
˜ What it does…
Allows the browser to render the entire page in the
background, all the assets of a document.
˜ What can %& do…
Slide 69
Slide 69 text
Link Prefetching DNS Prefetching Prerendering
˜ What it does…
Allows the browser to render the entire page in the
background, all the assets of a document.
˜ What can %& do…
⚠ ❌ ❌ ⚠
Slide 70
Slide 70 text
Link Prefetching DNS Prefetching Prerendering
˜ What it does…
Allows the browser to render the entire page in the
background, all the assets of a document.
˜ What can %& do…
✘ You want to be more careful with prerendering
as it is resource heavy and can cause bandwidth
waste, especially on mobile devices
Slide 71
Slide 71 text
˜ Can I use?
Slide 72
Slide 72 text
˜ Can I use?
Slide 73
Slide 73 text
˜ Can I use?
Slide 74
Slide 74 text
https://wicg.github.io/priority-hints/
Slide 75
Slide 75 text
%%%& A script is to be loaded with critical importance as it is
necessary for the core user experience ''(
%%%& An image is to be loaded with high importance. It could be
important but not critical to the overall experience loading
up. ''(
<img src=foo importance=high>
%%%& It can be used to indicate low importance/non-blocking
style which isn't impacting the core experience. ''(
<link rel=stylesheet href=foo importance=low>
Slide 76
Slide 76 text
#$ First
import(/* webpackPrefetch: 3 */ "assets/images/foo.jpg");
#$ Second
import(/* webpackPrefetch: 2 */ "modules/foo");
#$ Last
import(/* webpackPrefetch: 1 */ “modules/bar");
Slide 77
Slide 77 text
Preloaded Chunk Prefetched Chunk
X
Slide 78
Slide 78 text
Preloaded Chunk Prefetched Chunk
X
˜ Starts loading in
parallel to the parent
chunk
˜ Focuses on current
navigation
˜ Fetches resources
with high-priority
˜ Is instantly
downloaded
˜ Starts after the
parent chunk finish
˜ Focuses on fetching
resources for the next
navigation
˜ Fetches resources
with low priority
˜ Is downloaded in
browser idle time
Slide 79
Slide 79 text
˜ Connecting to critical origins (preconnect)
˜ Asset for current page (preload)
˜ Asset for future navigation (prefetch)
Slide 80
Slide 80 text
˜ #2 ˜
Blocked First Paint
Slide 81
Slide 81 text
˜ Avoid invisible text while web fonts are
loading
˜ Reduce render blocking scripts and stylesheets
˜ Server-side render stuff
Slide 82
Slide 82 text
˜ Avoid invisible text while web fonts are
loading
˜ Reduce render blocking scripts and stylesheets
˜ Server-side render stuff
Slide 83
Slide 83 text
˜ What says…
˜ What can %& do…
@font-face {
font-family: "Open Sans Regular";
src: url(“./OpenSans-Regular-BasicLatin.woff2") format("woff2");
font-display: swap;
}
Slide 84
Slide 84 text
˜ What says…
˜ What can %& do…
@font-face {
font-family: "Open Sans Regular";
src: url(“./OpenSans-Regular-BasicLatin.woff2") format("woff2");
font-display: swap;
}
˜ What it does…
The initial font displayed is the first system font in the stack.
When the custom font has loaded, it will kick in and replace the
system font that was initially displayed.
Slide 85
Slide 85 text
˜ Avoid invisible text while web fonts are
loading
˜ Reduce render blocking scripts and stylesheets
˜ Server-side render stuff
Slide 86
Slide 86 text
˜ What says…
˜ What can %& do…
https://github.com/addyosmani/critical
Slide 87
Slide 87 text
˜ Avoid invisible text while web fonts are
loading
˜ Reduce render blocking scripts and stylesheets
˜ Server-side render stuff
✔ Static sites
✔ In control of your Apache or Nginx servers
✔ No budget for this
✘ Dynamic content / Rapidly changing websites
Slide 108
Slide 108 text
Among the 40+ optimisation filters available in
mod_pagespeed are:
✔ optimization, compression and resizing of images;
✔ concatenation, minification, and inlining of your
CSS and JavaScript;
✔ cache extension, domain sharding, and domain
rewriting;
✔ deferred loading of JavaScript and image resources
˜ Optimize images
˜ Use lighter formats
˜ Use responsive images
˜ Lazy-load offscreen images
Slide 140
Slide 140 text
https://github.com/aFarkas/lazysizes
Slide 141
Slide 141 text
˜ Optimize images
˜ Use lighter formats
˜ Use responsive images
˜ Lazy-load offscreen images
Slide 142
Slide 142 text
˜ #7 ˜
Wasted Renders
Slide 143
Slide 143 text
No content
Slide 144
Slide 144 text
˜ Use referentially equal stuff
˜ Use PureComponent/memo (when it makes sense)
˜ Take benefit from techniques like windowing
Slide 145
Slide 145 text
"In God we trust; all
others must bring
data."
- W. Edwards Deming
Slide 146
Slide 146 text
Things I’d fucking love
to experiment with
Things I’d fucking love
to experiment with
Slide 147
Slide 147 text
˜ #1 ˜
Slide 148
Slide 148 text
https://github.com/developit/stockroom
Slide 149
Slide 149 text
˜ #2 ˜
Slide 150
Slide 150 text
No content
Slide 151
Slide 151 text
˜ Progressive Web Apps (PWAs)
˜ Devops/Something-as-a-Service
˜ Blockchain
˜ Machine Learning/Deep Learning/
Neural Networks (& other Artificial
Intelligence slangs I’ve got no idea
of)
Slide 152
Slide 152 text
˜ Progressive Web Apps (PWAs)
˜ Devops/Something-as-a-Service
˜ Blockchain
˜ Machine Learning/Deep Learning/
Neural Networks (& other Artificial
Intelligence slangs I’ve got no idea
of)
Slide 153
Slide 153 text
No content
Slide 154
Slide 154 text
#$ Require GuessPlugin
const {GuessPlugin} = require('guess-webpack');
#$ Add it in the end of your webpack
#$ plugin configuration
GuessPlugin({ GA: 'GA_VIEW_ID' })
Slide 155
Slide 155 text
˜ GA Module fetches structured data from Google
Analytics
˜ Guess Parser parses an application in order to
create the mapping between routes and JavaScript
bundles
˜ Guess Webpack Plugin automates the process of
applying data-driven bundling & pre-fetching in
React & Angular apps
Slide 156
Slide 156 text
Its goal is to replace the manual decision
making with an automated data-driven approach.
Focusing on:
˜ Single-page applications
˜ Static content sites
˜ Framework-based static sites