Slide 1

Slide 1 text

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

Slide 4

Slide 4 text

˜ And I’m from… ˜

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

http://time.com/3490758/ hitchhikers-guide-galaxy/

Slide 10

Slide 10 text

˜ Sounds good.

Slide 11

Slide 11 text

https://speakerdeck.com/ ythecombinator/the-hitchhiker-s-guide-to-the-front-end-performance

Slide 12

Slide 12 text

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

Slide 32

Slide 32 text

https://twitter.com/popeindustries/status/895575424406867968

Slide 33

Slide 33 text

"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

Slide 88

Slide 88 text

https://rauchg.com/2014/7-principles-of-rich-web-applications

Slide 89

Slide 89 text

https://nextjs.org

Slide 90

Slide 90 text

˜ Avoid invisible text while web fonts are loading ˜ Reduce render blocking scripts and stylesheets ˜ Server-side render stuff

Slide 91

Slide 91 text

˜ #3 ˜ Bloated Pages

Slide 92

Slide 92 text

˜ Audit your assets regularly ˜ Code Split (Routes, Components, Vendor bundles) + Dynamic Import stuff ˜ Remove unused library code + Tree Shake

Slide 93

Slide 93 text

˜ Audit your assets regularly ˜ Code Split (Routes, Components, Vendor bundles) + Dynamic Import stuff ˜ Remove unused library code + Tree Shake

Slide 94

Slide 94 text

Bundlephobia Import Cost for VSCode Webpack Bundle Analyzer

Slide 95

Slide 95 text

˜ Audit your assets regularly ˜ Code Split (Routes, Components, Vendor bundles) + Dynamic Import stuff ˜ Remove unused library code + Tree Shake

Slide 96

Slide 96 text

1.8s bootup 0.78s bootup ˜ What says… ˜ What can %& do…

Slide 97

Slide 97 text

1.8s bootup 0.78s bootup ˜ What says… ˜ What can %& do… 56% faster

Slide 98

Slide 98 text

˜ Audit your assets regularly ˜ Code Split (Routes, Components, Vendor bundles) + Dynamic Import stuff ˜ Remove unused library code + Tree Shake

Slide 99

Slide 99 text

https://github.com/GoogleChromeLabs/webpack-libs-optimizations

Slide 100

Slide 100 text

No content

Slide 101

Slide 101 text

Webpack is still spanked by tree shaking (and from 4 on) If using TS, target ES6

Slide 102

Slide 102 text

˜ Audit your assets regularly ˜ Code Split (Routes, Components, Vendor bundles) + Dynamic Import stuff ˜ Remove unused library code + Tree Shake

Slide 103

Slide 103 text

˜ #4 ˜ Unnecessary Resources

Slide 104

Slide 104 text

˜ Automate minification (UglifyJS, Cloudfare, mod_pagespeed) ˜ Compress (gzip, brotli)

Slide 105

Slide 105 text

˜ Automate minification (UglifyJS, Cloudfare, mod_pagespeed) ˜ Compress (gzip, brotli)

Slide 106

Slide 106 text

https://www.modpagespeed.com/

Slide 107

Slide 107 text

✔ 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

Slide 109

Slide 109 text

˜ Automate minification (UglifyJS, Cloudfare, mod_pagespeed) ˜ Compress (gzip, brotli)

Slide 110

Slide 110 text

˜ -30%

Slide 111

Slide 111 text

No content

Slide 112

Slide 112 text

No content

Slide 113

Slide 113 text

⚠ ❌ ❌ ⚠

Slide 114

Slide 114 text

˜ Automate minification (UglifyJS, Cloudfare, mod_pagespeed) ˜ Compress (gzip, brotli)

Slide 115

Slide 115 text

˜ #5 ˜ Unused Code

Slide 116

Slide 116 text

˜ Code coverage in DevTools (Page load, runtime) ˜ Lighthouse Coverage Audit ˜ Remove unused code to improve load time ˜ Write regression tests

Slide 117

Slide 117 text

˜ Code coverage in DevTools (Page load, runtime) ˜ Lighthouse Coverage Audit ˜ Remove unused code to improve load time ˜ Write regression tests

Slide 118

Slide 118 text

95% unused

Slide 119

Slide 119 text

˜ Code coverage in DevTools (Page load, runtime) ˜ Lighthouse Coverage Audit ˜ Remove unused code to improve load time ˜ Write regression tests

Slide 120

Slide 120 text

https://github.com/purifycss/purifycss

Slide 121

Slide 121 text

˜ Code coverage in DevTools (Page load, runtime) ˜ Lighthouse Coverage Audit ˜ Remove unused code to improve load time ˜ Write regression tests

Slide 122

Slide 122 text

(+ jest-image-snapshot)

Slide 123

Slide 123 text

˜ Code coverage in DevTools (Page load, runtime) ˜ Lighthouse Coverage Audit ˜ Remove unused code to improve load time ˜ Write regression tests

Slide 124

Slide 124 text

˜ #6 ˜ Unoptimized Images

Slide 125

Slide 125 text

˜ Optimize images ˜ Use lighter formats ˜ Use responsive images ˜ Lazy-load offscreen images

Slide 126

Slide 126 text

˜ Optimize images ˜ Use lighter formats ˜ Use responsive images ˜ Lazy-load offscreen images

Slide 127

Slide 127 text

˜ What says…

Slide 128

Slide 128 text

˜ GUI ˜ ImageOptmin (Mac) XNConvert (Cross-platform) ˜ Build ˜ imagemin libvips ˜ CDN ˜ Cloudinary Imgix Fastly Akamai ˜ CDN ˜ (self-hosted) Thumbor ImageFlow ˜ What can %& do…

Slide 129

Slide 129 text

˜ GUI ˜ ImageOptmin (Mac) XNConvert (Cross-platform) ˜ Build ˜ imagemin libvips ˜ CDN ˜ Cloudinary Imgix Fastly Akamai ˜ CDN ˜ (self-hosted) Thumbor ImageFlow

Slide 130

Slide 130 text

˜ What it does…

Slide 131

Slide 131 text

˜ Optimize images ˜ Use lighter formats ˜ Use responsive images ˜ Lazy-load offscreen images

Slide 132

Slide 132 text

7.3mb 1.3MB 960kb 80%+ savings

Slide 133

Slide 133 text

˜ Optimize images ˜ Use lighter formats ˜ Use responsive images ˜ Lazy-load offscreen images

Slide 134

Slide 134 text

https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType

Slide 135

Slide 135 text

https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType

Slide 136

Slide 136 text

https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType

Slide 137

Slide 137 text

No content

Slide 138

Slide 138 text

4G+ (Video) ˜1mb 2G-3G (Static Image) ˜30kb

Slide 139

Slide 139 text

˜ 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

Slide 157

Slide 157 text

No content

Slide 158

Slide 158 text

https://github.com/addyosmani/predictive-fetching

Slide 159

Slide 159 text

https://bit.ly/2u2fUzW

Slide 160

Slide 160 text

https://www.youtube.com/watch?v=L5tPWCB7jX0

Slide 161

Slide 161 text

No content

Slide 162

Slide 162 text

Thanks Thanks