Slide 1

Slide 1 text

The Hitchhiker's Guide to the Front-End Performance The Hitchhiker's Guide to the Front-End Performance 2019 EDITION

Slide 2

Slide 2 text

˜ I’m from… ˜

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

!!!

Slide 7

Slide 7 text

What do we know about perf? What do we know about perf?

Slide 8

Slide 8 text

˜ 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 9

Slide 9 text

Issues I was facing Issues I was facing

Slide 10

Slide 10 text

˜ What I do at …

Slide 11

Slide 11 text

˜ JavaScript ˜

Slide 12

Slide 12 text

"Write modern, idiomatic JavaScript, and let the JavaScript engine worry about making it fast." - Mathias Bynens, BrazilJS 2018

Slide 13

Slide 13 text

˜ JavaScript ˜

Slide 14

Slide 14 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 15

Slide 15 text

Optimization Killers

Slide 16

Slide 16 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 17

Slide 17 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 18

Slide 18 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 19

Slide 19 text

No content

Slide 20

Slide 20 text

The new execution pipeline is built on top of Ignition, V8’s interpreter, and TurboFan, V8’s newest optimizing compiler.

Slide 21

Slide 21 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 22

Slide 22 text

60% faster web developer tools http://v8project.blogspot.com/2017/11/web-tooling-benchmark.html

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

"Write modern, idiomatic JavaScript, and let the JavaScript engine worry about making it fast." - Mathias Bynens, BrazilJS 2018

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

˜ fixing perf issues be like ˜

Slide 28

Slide 28 text

˜ fixing perf issues be like ˜

Slide 29

Slide 29 text

˜ Problems ˜

Slide 30

Slide 30 text

˜ #1 ˜ Critical Resources Late Delivered

Slide 31

Slide 31 text

˜ Connecting to critical origins (preconnect) ˜ Asset for current page (preload) ˜ Asset for future navigation (prefetch)

Slide 32

Slide 32 text

˜ Connecting to critical origins (preconnect) ˜ Asset for current page (preload) ˜ Asset for future navigation (prefetch)

Slide 33

Slide 33 text

˜ What says… ˜ What can $% do…

Slide 34

Slide 34 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 35

Slide 35 text

˜ Bring me the ! 100MS 200MS 300MS 400MS 500MS 600MS 700MS HTML CSS FONT 1 FONT 2 Fonts start loading Fonts rendered

Slide 36

Slide 36 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 37

Slide 37 text

˜ Connecting to critical origins (preconnect) ˜ Asset for current page (preload) ˜ Asset for future navigation (prefetch)

Slide 38

Slide 38 text

˜ What says… ˜ What can $% do…

Slide 39

Slide 39 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 40

Slide 40 text

˜ Connecting to critical origins (preconnect) ˜ Asset for current page (preload) ˜ Asset for future navigation (prefetch)

Slide 41

Slide 41 text

˜ What it does… ✔ Fetch resources in the background (idle time) ✔ Store them in the browser’s cache It can be:

Slide 42

Slide 42 text

Link Prefetching DNS Prefetching Prerendering

Slide 43

Slide 43 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 44

Slide 44 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 45

Slide 45 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 46

Slide 46 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 47

Slide 47 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 48

Slide 48 text

https://wicg.github.io/priority-hints/

Slide 49

Slide 49 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 50

Slide 50 text

#$ First import(/* webpackPrefetch: 3 */ "assets/images/foo.jpg"); #$ Second import(/* webpackPrefetch: 2 */ "modules/foo"); #$ Last import(/* webpackPrefetch: 1 */ “modules/bar");

Slide 51

Slide 51 text

Preloaded Chunk Prefetched Chunk X

Slide 52

Slide 52 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 53

Slide 53 text

˜ Connecting to critical origins (preconnect) ˜ Asset for current page (preload) ˜ Asset for future navigation (prefetch)

Slide 54

Slide 54 text

˜ #2 ˜ Blocked First Paint

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 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 58

Slide 58 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 59

Slide 59 text

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

Slide 60

Slide 60 text

˜ What says… ˜ What can $% do… https://github.com/addyosmani/critical

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

https://nextjs.org

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

˜ #3 ˜ Bloated Pages

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

Bundlephobia Import Cost for VSCode Webpack Bundle Analyzer

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

No content

Slide 75

Slide 75 text

No content

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

˜ #4 ˜ Unnecessary Resources

Slide 78

Slide 78 text

˜ Compress (gzip, brotli)

Slide 79

Slide 79 text

˜ -30%

Slide 80

Slide 80 text

No content

Slide 81

Slide 81 text

No content

Slide 82

Slide 82 text

⚠ ❌ ❌ ⚠

Slide 83

Slide 83 text

˜ Compress (gzip, brotli)

Slide 84

Slide 84 text

˜ #5 ˜ Unused Code

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

95% unused

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

https://github.com/purifycss/purifycss

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

(+ jest-image-snapshot)

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

˜ #6 ˜ Unoptimized Images

Slide 94

Slide 94 text

˜ Optimize images ˜ Use lighter formats ˜ Use responsive images

Slide 95

Slide 95 text

˜ Optimize images ˜ Use lighter formats ˜ Use responsive images

Slide 96

Slide 96 text

˜ What says…

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

˜ What it does…

Slide 100

Slide 100 text

˜ Optimize images ˜ Use lighter formats ˜ Use responsive images

Slide 101

Slide 101 text

7.3mb 1.3MB 960kb 80%+ savings

Slide 102

Slide 102 text

˜ Optimize images ˜ Use lighter formats ˜ Use responsive images

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

No content

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

˜ Optimize images ˜ Use lighter formats ˜ Use responsive images

Slide 109

Slide 109 text

˜ #7 ˜ Wasted Renders

Slide 110

Slide 110 text

No content

Slide 111

Slide 111 text

Virtualizing a list of items involves maintaining a window and moving that window around your list. "How does windowing work?" by Brian Vaughn

Slide 112

Slide 112 text

https://github.com/bvaughn/react-virtualized

Slide 113

Slide 113 text

10K items wo/ virtualization 10K items w/ virtualization X

Slide 114

Slide 114 text

w/ virtualization X wo/ virtualization "Rendering large lists with react-window" by Addy Osmani

Slide 115

Slide 115 text

w/ virtualization X wo/ virtualization "Rendering large lists with react-window" by Addy Osmani

Slide 116

Slide 116 text

w/ virtualization X wo/ virtualization ˜242.7ms ˜2.4ms "Rendering large lists with react-window" by Addy Osmani

Slide 117

Slide 117 text

˜ Use referentially equal stuff ˜ Use PureComponent/memo (when it makes sense) ˜ (In the future) Take benefit from time slicing ˜ Take benefit from techniques like windowing

Slide 118

Slide 118 text

"In God we trust; all others must bring data." - W. Edwards Deming

Slide 119

Slide 119 text

˜ Senior Software Engineer, Front- End @beakyn ˜ @ythecombinator on the webs ˜ addicted to emojis, memes and beer

Slide 120

Slide 120 text

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

Slide 121

Slide 121 text

No content

Slide 122

Slide 122 text

Thanks Thanks