Slide 1

Slide 1 text

WPO for SPAs The epic battle against loading indicators

Slide 2

Slide 2 text

Stefan Baumgartner Internet Batman Larry Urbano Senior Sales Engineer Monitoring redefined

Slide 3

Slide 3 text

Agenda 1. Some theory 2.We meet our Single Page Application 3.Performance optimisation techniques 4.Some live coding and lots of demos

Slide 4

Slide 4 text

Title Text Breaks

Slide 5

Slide 5 text

Subheadline

Slide 6

Slide 6 text

Why have we moved to SPAs?

Slide 7

Slide 7 text

Client Client Initial request HTML payload Form POST HTML payload Traditional

Slide 8

Slide 8 text

Client Client Initial request HTML payload AJAX call via JS HTML Diff SPA

Slide 9

Slide 9 text

Single Page Applications are awesome … ▪ They provide better UX once loaded ▪ Communication is reduced to deltas ▪ This results in fewer requests and smaller payload ▪ Should your Network die, you still have some content available ▪ They’re super-easy to deploy

Slide 10

Slide 10 text

Single Page Applications are hard… ▪ The client is in control… but the client starts when everything has been transferred ▪ The client side app has to take care of all the errors and has to be a lot lot smarter ▪ Flaky networks harm the UX ▪ Fallbacks are hard ▪ Bad practices are more seductive ▪ States are hard to share

Slide 11

Slide 11 text

Client Client Initial request non-content HTML AJAX call via JS content diff SPAs Resource request JavaScript payload Initial AJAX call via JS content payload

Slide 12

Slide 12 text

Client Client Initial request non-content HTML AJAX call via JS content diff SPAs Resource request JavaScript payload Initial AJAX call via JS content payload What is going on here?

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

Subheadline

Slide 15

Slide 15 text

initial HTML request angular.js main.js data/from/backend

Slide 16

Slide 16 text

All of them?

Slide 17

Slide 17 text

prompt for unload redirect DNS TCP Request Response Processing onLoad navigationStart redirectStart redirectEnd domainLookupStart domainLookupEnd connectStart connectEnd requestStart responseStart responseEnd domLoading domInteractive domContentLoaded domComplete loadEventStart loadEventEnd

Slide 18

Slide 18 text

prompt for unload redirect DNS TCP Request Response Processing onLoad navigationStart redirectStart redirectEnd domainLookupStart domainLookupEnd connectStart connectEnd requestStart responseStart responseEnd domLoading domInteractive domContentLoaded domComplete loadEventStart loadEventEnd

Slide 19

Slide 19 text

domLoading domInteractive domContentLoaded domComplete

Slide 20

Slide 20 text

domLoading domInteractive domContentLoaded domComplete The DOM is getting parsed DOM is parsed and ready to work on The document is loaded (wo stylesheets, images) All sub resources are loaded

Slide 21

Slide 21 text

Let’s check our SPA Demo-time

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

cd /app/twitterwall-server npm start service nginx start

Slide 24

Slide 24 text

cd /app/twitterwall-client-webpack (commands to follow)

Slide 25

Slide 25 text

replace contents of /app/twitterwall-server/public with /app/twitterwall-client-webpack/dist

Slide 26

Slide 26 text

npm stop npm start

Slide 27

Slide 27 text

Step 1: Production builds Put back your development pride

Slide 28

Slide 28 text

CSS JS

Slide 29

Slide 29 text

CSS JS

Slide 30

Slide 30 text

CSS JS VENDOR

Slide 31

Slide 31 text

CSS JS VENDOR

Slide 32

Slide 32 text

Step 2: Tree shaking It’s not as funny as it sounds. But equally cool

Slide 33

Slide 33 text

ESnext module syntax ▪ EcmaScript finally has a module syntax (and probably a module loading strategy soon as well!) ▪ Tooling allows us to use this new syntax already import { createServer } from ‘http’; import * as path from ‘path’; export function cube(x) { return x*x*x; } export default { … } const createServer = require(‘http’).createServer; const path = require(‘path’); module.exports = { cube: function(x) { return x*x*x} }

Slide 34

Slide 34 text

Tree Shaking ▪ This new syntax allows tools to do a static code analysis based on the JavaScript AST. ▪ With that, we can exclude functions we simply do not need, reducing our bundle size even more.

Slide 35

Slide 35 text

Angular Ahead of Time compilation ▪ Faster rendering: With AOT, the browser downloads a pre-compiled version of the application. The browser loads executable code so it can render the application immediately, without waiting to compile the app first. ▪ Fewer asynchronous requests: The compiler inlines external html templates and css style sheets within the application JavaScript, eliminating separate ajax requests for those source files.

Slide 36

Slide 36 text

Angular Ahead of Time compilation ▪ Smaller Angular framework download size: There’s no need to download the Angular compiler if the app is already compiled. The compiler is roughly half of Angular itself, so omitting it dramatically reduces the application payload. ▪ Detect template errors earlier: The AOT compiler detects and reports template binding errors during the build step before users can see them. ▪ Better security: AOT compiles HTML templates and components into JavaScript files long before they are served to the client. With no templates to read and no risky client-side HTML or JavaScript evaluation, there are fewer opportunities for injection attacks

Slide 37

Slide 37 text

Step 3: SSR Putting the server back into the equation

Slide 38

Slide 38 text

initial HTML request angular.js main.js data/from/backend Start render

Slide 39

Slide 39 text

initial HTML request angular.js main.js data/from/backend Start render?

Slide 40

Slide 40 text

The network is a bottle-neck

Slide 41

Slide 41 text

So make every request count!

Slide 42

Slide 42 text

Client Client Initial request non-content HTML AJAX call via JS content diff Resource request JavaScript payload Initial AJAX call via JS content payload App

Slide 43

Slide 43 text

Client Client Initial request Initial Render HTML AJAX call via JS content diff Resource request JavaScript payload Initial AJAX call via JS content payload App App

Slide 44

Slide 44 text

Important content first Everything else is an enhancement

Slide 45

Slide 45 text

Server side rendering for SPAs ▪ Thanks to a little technology called Node.js, we are able to render JS on the client and the server ▪ As long as you have valid routes (= URLs), you have the ability to render the state on the server ▪ The first requests bring the rendered state ▪ Then the JavaScript framework kicks in

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

But I can’t move all by backend to Node.js

Slide 50

Slide 50 text

You don’t have to!

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

Bonus round! Lazy loaded routes

Slide 53

Slide 53 text

Bundling … ▪ Why bundle everything, when we just need a few things to start? ▪ Routes deep down in the navigation might not be used at all… ▪ Bundle by routes, split away code that you don’t need at first…

Slide 54

Slide 54 text

Bonus round! Responsive images

Slide 55

Slide 55 text

”Super

Slide 56

Slide 56 text

”Super A low-res fallback image for browsers that don’t know srcset These sources are available. For each “width unit” there’s a reduced version of our original screenshot The sizes define which source to choose from. Retina screens are also checked

Slide 57

Slide 57 text

s Subheadline Speed Index

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

∫ 1 - visuallycomplete/100 0 end

Slide 61

Slide 61 text

What does this mean?

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

No content

Slide 66

Slide 66 text

Visually complete (%) 0 25 50 75 100 Time in Seconds 0s 1s 2s 3s 4s 5s 6s 7s 8s

Slide 67

Slide 67 text

Visually complete (%) 0 25 50 75 100 Time in Seconds 0s 1s 2s 3s 4s 5s 6s 7s 8s

Slide 68

Slide 68 text

Visually complete (%) 0 25 50 75 100 Time in Seconds 0s 1s 2s 3s 4s 5s 6s 7s 8s

Slide 69

Slide 69 text

s Subheadline Thoughts about HTTP2

Slide 70

Slide 70 text

Server Client HTTP/2 Getting stuff … GET image1 image1 header image1 payload image1 payload image2 header image2 payload image1 payload image2 payload GET image2

Slide 71

Slide 71 text

HTTP 1.1 index.html a.js b.js c.js d.js

Slide 72

Slide 72 text

HTTP 2 index.html a.js b.js c.js d.js

Slide 73

Slide 73 text

HTTP 2 index.html a.js b.js c.js d.js

Slide 74

Slide 74 text

HTTP 2 index.html a.js b.js c.js d.js

Slide 75

Slide 75 text

No content

Slide 76

Slide 76 text

Desktop HTTP/2 ~1.8s HTTP1.1 ~2.6s

Slide 77

Slide 77 text

mobile connections HTTP1.1 ~3.37s HTTP2 ~1.72

Slide 78

Slide 78 text

A slow website on HTTP1.1 will still be a slow website on HTTP2

Slide 79

Slide 79 text

Frequency of change Libraries Utilities Module Module Module Module rigid high frequency some frequency

Slide 80

Slide 80 text

Optimised utility layer Libraries Utilities Module Module Module rigid high frequency some frequency

Slide 81

Slide 81 text

Extending the utility layer Libraries Utilities Module Module Module rigid high frequency some frequency

Slide 82

Slide 82 text

Files to change Libraries Utilities Module Module Module rigid high frequency some frequency

Slide 83

Slide 83 text

Frequency of change Libraries Module Module Module rigid high frequency Module

Slide 84

Slide 84 text

What to do with your application?

Slide 85

Slide 85 text

The best request is a request not being made

Slide 86

Slide 86 text

Create independent, exchangeable components

Slide 87

Slide 87 text

Create small, detached bundles

Slide 88

Slide 88 text

Code duplication and weight is okay if the file can stay longer

Slide 89

Slide 89 text

Think about long lasting applications and frequency of change

Slide 90

Slide 90 text

Thank you.