When JavaScript Bytes

A presentation at performance.now() in November 2019 in Amsterdam, Netherlands by Tim Kadlec

Slide 1

Slide 1

WHEN JAVASCRIPT BYTES Tim Kadlec @tkadlec #perfnow

Slide 2

Slide 2

Slide 3

Slide 3

Slide 4

Slide 4

Slide 5

Slide 5

Slide 6

Slide 6

Slide 7

Slide 7

Slide 8

Slide 8

4kb RAM 74kb ROM

Slide 9

Slide 9

.1%

Slide 10

Slide 10

Slide 11

Slide 11

Slide 12

Slide 12

<1.7mb

Slide 13

Slide 13

<1.7mb 1.8mb

Slide 14

Slide 14

B M 2 . 4

Slide 15

Slide 15

Slide 16

Slide 16

Network

Slide 17

Slide 17

Desktop Mobile 96.2kb 84.4kb p10 204.5kb 180.2kb p25 412.6kb 378.6kb p50 753.6kb 694.8kb p75 1,180.5kb 1,099.0kb p90 0 300 600 900 Kilobytes of JavaScript 1200

Slide 18

Slide 18

@KenjiBaheux

Slide 19

Slide 19

@KenjiBaheux

Slide 20

Slide 20

16% Brotli 17% Uncompressed 67% GZip

Slide 21

Slide 21

Slide 22

Slide 22

Slide 23

Slide 23

Slide 24

Slide 24

16% Brotli 17% Uncompressed 67% GZip

Slide 25

Slide 25

Slide 26

Slide 26

npm install compression-webpack-plugin —save-dev //webpack config file new CompressionPlugin({ test: /.js(?.)?$/i, algorithm: ‘brotliCompress’, filename: ‘[file].br’, compressionOptions: { level: 11 }, minRatio: 1, }), new CompressionPlugin({ test: /.js(?.)?$/i, filename: ‘[file].gz’, minRatio: 1, })

Slide 27

Slide 27

Brotli provides ~20% improvement over GZip But…

Slide 28

Slide 28

“We tried it in prod with our @nuxt_js project and our response times went from 300ms to over 12 seconds! Scaling exploded.” Josh Deltener, @hecktarzuli https://twitter.com/hecktarzuli/status/1163887824514539522

Slide 29

Slide 29

10-20% Fewer bytes 20% Fewer bytes ~3.6% Page load 0% Page load

Slide 30

Slide 30

On Device

Slide 31

Slide 31

Desktop Mobile 96.2kb 84.4kb p10 204.5kb 180.2kb p25 412.6kb 378.6kb p50 753.6kb 694.8kb p75 1,180.5kb 1,099.0kb p90 0 300 600 900 Kilobytes of JavaScript 1200

Slide 32

Slide 32

Desktop Mobile 481.0kb 421.9kb p10 1,022.3kb 901.2kb p25 2,063.0kb 1,892.5kb p50 3,768.0kb 3,474.1kb p75 5,902.5kb 5,495.1kb p90 0 1500 3000 4500 Kilobytes of JavaScript 6000

Slide 33

Slide 33

Desktop Mobile 144ms 466ms 365ms 1,372ms 918ms p10 p25 p50 3,437ms 2,015ms p75 7,757ms 3,848ms p90 14,705ms 0 4000 8000 12000 Mainthread Processing Time 16000

Slide 34

Slide 34

466ms 843ms 1,515ms 3,489ms p10 All Vue jQuery React 3,437ms 3,824ms 5,726ms p50 11,634ms 14,705ms 14,879ms p90 18,259ms 28,027ms 0 7500 15000 22500 Mainthread Processing Time 30000

Slide 35

Slide 35

Slide 36

Slide 36

var observer = new PerformanceObserver(function(list) { var perfEntries = list.getEntries(); for (var i = 0; i < perfEntries.length; i++) { //queue it up to be sent back for tracking } }); observer.observe({entryTypes:[‘longtask’]});

Slide 37

Slide 37

200ms 20ms 40ms 150ms 300ms 15ms 100ms

Slide 38

Slide 38

Number of Long Tasks 200ms 1 20ms 40ms 150ms 2 300ms 3 15ms 100ms 4

Slide 39

Slide 39

Longest Long Task 200ms 20ms 40ms 150ms 300ms 300ms 15ms 100ms

Slide 40

Slide 40

Long Tasks Time 200ms 20ms 40ms JS CPU Time 150ms 300ms 15ms 100ms 200+150+300+100 = 750

Slide 41

Slide 41

Total Blocking Time 200ms 20ms 40ms 150ms 300ms 15ms 100ms 150+100+250+50 = 550

Slide 42

Slide 42

Slide 43

Slide 43

Slide 44

Slide 44

19S 65S PIXEL 2 ALCATEL 1X

Slide 45

Slide 45

HOW MUCH IS TOO MUCH?

Slide 46

Slide 46

32 MONTHS

Slide 47

Slide 47

$214

Slide 48

Slide 48

85%

Slide 49

Slide 49

ANDROID > 1 YEAR OLD < $200

Slide 50

Slide 50

Slide 51

Slide 51

Slide 52

Slide 52

ANDROID > 1 YEAR OLD < $200 SLOW 3G 400MS RTT 4000KBPS TRANSFER @slightlylate

Slide 53

Slide 53

130-170KB CRITICAL PATH RESOURCES @slightlylate

Slide 54

Slide 54

~100KB

Slide 55

Slide 55

HTML

Slide 56

Slide 56

HTML a.js

Slide 57

Slide 57

HTML Parse/Compile a.js a.js Execute a.js

Slide 58

Slide 58

HTML Parse/Compile a.js a.js Execute a.js

Slide 59

Slide 59

HTML Execute a.js a.js Parse/Compile a.js

Slide 60

Slide 60

HTML Execute a.js a.js (200kb) Parse/Compile a.js

Slide 61

Slide 61

HTML Execute a.js a.js (200kb) Parse/Compile a.js

Slide 62

Slide 62

HTML Execute a.js a.js (200kb) Parse/Compile a.js B K 0 3

Slide 63

Slide 63

HTML Execute a.js a.js (200kb) Parse

Slide 64

Slide 64

HTML Execute a.js a.js (200kb) Parse

Slide 65

Slide 65

HTML Execute a.js a.js Parse b.js Parse Execute b.js

Slide 66

Slide 66

HTML Execute a.js a.js Parse b.js Parse Execute b.js

Slide 67

Slide 67

50-100KB PER BUNDLE

Slide 68

Slide 68

50-100KB ~100KB PER BUNDLE TOTAL

Slide 69

Slide 69

Slide 70

Slide 70

487kb (2.6MB)

Slide 71

Slide 71

Slide 72

Slide 72

import { config, CognitoIdentityServiceProvider } from ‘aws-sdk’;

Slide 73

Slide 73

const CognitoIdentityServiceProvider = require(‘aws-sdk/clients/ cognitoidentityserviceprovider’);

Slide 74

Slide 74

Slide 75

Slide 75

<1.65MB

Slide 76

Slide 76

Slide 77

Slide 77

Slide 78

Slide 78

external: [‘apollo-client’, ‘apollo-link’, ‘graphql-tag’],

Slide 79

Slide 79

Slide 80

Slide 80

<15KB

Slide 81

Slide 81

Slide 82

Slide 82

Slide 83

Slide 83

resolve: { alias: { “core-js”: path.resolve(__dirname, ‘node_modules/core-js’) }, },

Slide 84

Slide 84

Slide 85

Slide 85

externals : [ { “vue-swiper-js”: “vue-swiper-js”, “vuelidate”: “vuelidate”, “vuelidate/lib/validators”: “vuelidate/lib/validators”, } ],

Slide 86

Slide 86

<59.5KB

Slide 87

Slide 87

2.6MB 898.3KB 66% reduction

Slide 88

Slide 88

MAINTAIN & ITERATE

Slide 89

Slide 89

Warned or blocked on install Warned or blocked in code editor Blocked on PR Blocked on deploy Tracked on deploy

Slide 90

Slide 90

Slide 91

Slide 91

Slide 92

Slide 92

Slide 93

Slide 93

Slide 94

Slide 94

Slide 95

Slide 95

Slide 96

Slide 96

Slide 97

Slide 97

Slide 98

Slide 98

DEFAULT STANCE MATTERS

Slide 99

Slide 99

WE’VE BUILT A WEB THAT LARGELY DISMISSES AFFORDABLE, TYPICAL SMARTPHONES AND THE PEOPLE THAT USE THEM.

Slide 100

Slide 100

BECAUSE WE CAN

Slide 101

Slide 101

Slide 102

Slide 102

THANK YOU! Tim Kadlec @tkadlec #perfnow