Slide 1

Slide 1 text

FaCSSt—CSS & Performance Harry Roberts – BCN WebPerf – January, 2016

Slide 2

Slide 2 text

Hello, Barcelona!

Slide 3

Slide 3 text

Who Am I?

Slide 4

Slide 4 text

Hello, Barcelona! Harry Roberts Consultant Front-end Architect. CSS, Performance, Scalability, Architecture. @csswizardry #faCSSt

Slide 5

Slide 5 text

CSS Performance ❤

Slide 6

Slide 6 text

What We Know Already

Slide 7

Slide 7 text

What We Know Already Styles at the top; scripts at the bottom. Styles block rendering; scripts block downloads. HTTP requests are expensive—minimise them. Minify, concatenate, and Gzip—reduce transfer count and size.

Slide 8

Slide 8 text

The Critical Path

Slide 9

Slide 9 text

The Critical Path Critical in our fight for performance. Journey between a user requesting a page and them seeing something. Most of it is spent on CSS. The Critical Path is dead time for your users. Make this journey as short and light as we possibly can.

Slide 10

Slide 10 text

We’ve started asking for a page. The HTML has made it over the wire (see ). Now we’re waiting for some CSS. You can see the Critical Path happening!

Slide 11

Slide 11 text

The Critical Path HTML and CSS are on the Critical Path. DOM and CSSOM are needed before anything can be rendered. Thus, they are render-blocking resources. Users see nothing until both are on the client. Get these over the wire as quickly as we possibly can. Everything else can load progressively (images, video, audio, even JS). CSS pretty much is the Critical Path.

Slide 12

Slide 12 text

The Critical Path Optimise the Critical Path. Make it as short as possible. Do not put anything unnecessary onto it. Don’t make the Critical Path carry too much.

Slide 13

Slide 13 text

CSS Is Your Biggest Performance Bottleneck*

Slide 14

Slide 14 text

CSS Bottleneck Browsers will not render anything until they have all the CSS for the current view/state. Browsers download all CSS: even CSS that doesn’t match the current media type/query.

Slide 15

Slide 15 text

Test Always needed. Needed right now. Only needed if we print. Never needed—it’s a nonsense media type.

Slide 16

Slide 16 text

But they all get downloaded?!

Slide 17

Slide 17 text

tl;dr: Get CSS onto the Client ASAP

Slide 18

Slide 18 text

Get CSS onto the Client ASAP Smaller file sizes are better. Keep things off of your Critical Path. Make the Critical Path as short as you possibly can. Just get CSS over the wire as fast as you possibly can. Prioritise CSS above all else for first render.

Slide 19

Slide 19 text

Things We Should Do

Slide 20

Slide 20 text

The Three Cs.

Slide 21

Slide 21 text

The Three Cs Concatenate CSS into as few files as possible to reduce HTTP requests. Compress transfer over the wire using Gzip to reduce file sizes. Cache stylesheets to prevent them being re-requested unnecessarily.

Slide 22

Slide 22 text

Remove Unused CSS

Slide 23

Slide 23 text

Remove Unused CSS CSS file sizes generally shouldn’t be that problematic. But still, waste is waste. If it’s not used, try get rid of it.

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

Remove Unused CSS DevTools » Audits » Web Page Performance » Audit Present State » Run UnCSS automates this (Grunt, Gulp, etc.).

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

Inline Critical/Above the Fold CSS

Slide 29

Slide 29 text

Inline Critical/Above the Fold CSS A huge performance boost. Send the (critical) CSS back with the first response. Cut out an entire round trip—fewer HTTP requests. CSS arrives with HTML, not after it. Begin rendering immediately. Lazy load the rest of the CSS when we get chance. More on this later—sort of.

Slide 30

Slide 30 text

Google don’t send any
 separate CSS files.

Slide 31

Slide 31 text

They inline it all.

Slide 32

Slide 32 text

Inline Critical/Above the Fold CSS Important to lazy load the rest of the CSS and then cache it. If it’s a single-page site then we don’t need to lazy load a CSS file. Send it over with the HTML every time.

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

Things We Should Avoid

Slide 36

Slide 36 text

Do Not @import Stylesheets

Slide 37

Slide 37 text

Do Not @import Stylesheets @import completely kills performance. Causes so much extra work. Adds more round trips. Delays downloads. Increases time to render dramatically.

Slide 38

Slide 38 text

URL index.html 01.css 01.css 02.css 02.css Browser Server

Slide 39

Slide 39 text

The @import Process Client asks for HTML. Server sends HTML back. HTML asks for CSS. Server sends CSS back. CSS asks for more CSS. Server sends more CSS back.

Slide 40

Slide 40 text

The @import Process Don’t let CSS request other CSS. All requests for CSS should be sent out at the same time. Basically, use multiple s.

Slide 41

Slide 41 text

Browser Server 01.css, 02.css 01.css, 02.css URL index.html

Slide 42

Slide 42 text

The Process Client asks for HTML. Server sends HTML back. HTML asks for CSS and more CSS. Server sends CSS and more CSS back.

Slide 43

Slide 43 text

@import on Sotheby’s Working on a Sotheby’s site with a client. Very complex mechanism for producing per-page CSS. Complex Sass dependencies (anything can import anything). Compiling Sass on the server as-per the CMS. All in the pursuit of performance. Then they were @importing a CSS file!

Slide 44

Slide 44 text

@import on Sotheby’s All the hard work of trying to create the tiniest possible CSS file… Was being completely undone by @importing their Google Fonts CSS.

Slide 45

Slide 45 text

@import at Sky Let me show you something crazy…

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

25kb? Nice!

Slide 48

Slide 48 text

Wait. What?
 More CSS?!

Slide 49

Slide 49 text

@import at Sky Why is that all the way down there? Either lazy-loaded via JS, or… It’s being @imported.

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

@import at Sky Whilst the browser was downloading, unpacking, parsing, and executing the first stylesheet, it had time to download 15 other assets. Then it was told to go off and get some more CSS. Which it had to download, unpack, parse, and execute. Then the browser could start rendering. @import kills performance by delaying everything.

Slide 52

Slide 52 text

@import at Sky Ideal fix: concatenate into one file*. Quick fix: serve via two elements**.

Slide 53

Slide 53 text

Avoid Base64 Encoding

Slide 54

Slide 54 text

Avoid Base64 Encoding We’re told Base64 reduces HTTP requests—a good thing. But it actually creates something much more expensive…

Slide 55

Slide 55 text

Avoid Base64 Encoding Base64 moves progressive assets onto your Critical Path. Things that could have loaded as they were ready are now forced to download immediately, and on the Critical Path. Made the journey longer. Making the browser do more work before it can render.

Slide 56

Slide 56 text

Avoid Base64 Encoding Don’t put non-essential assets onto your Critical Path. Pages can render without images. You’re making the CSS heavier for unnecessary assets—let images load in when ready. Never put fonts on the Critical Path—can add hundreds of KB. All just delays that first render.

Slide 57

Slide 57 text

Don’t Use an Asset Domain or CDN

Slide 58

Slide 58 text

Don’t Use an Asset Domain or CDN Adds more work onto the Critical Path. Makes the browser look up new DNS. Can add 120ms before the CSS even starts downloading. 120ms that we don’t need to spend at all.

Slide 59

Slide 59 text

Don’t Use an Asset Domain or CDN Always serve CSS from the host domain. Host domain’s DNS is already warmed up—zero extra cost. We can start sending CSS back immediately.

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

Asset Domains on m.skybet.com Started off with everything on host domain. More requests as site grew larger. Lack of parallelisation was costing us. Created a story for moving assets onto asset domains (stX.skybet.com). Can now download same amount of assets in less time, right?

Slide 62

Slide 62 text

Asset Domains on m.skybet.com Not quite. Nightly WebPage Test showed us that performance had gotten worse! Visually complete was almost ¼ second slower. How on earth had this happened?!

Slide 63

Slide 63 text

Asset Domains on m.skybet.com We’d started incurring new DNS lookups. The cost of going to a new domain was higher than the cost of lack of parallelisation. We moved our CSS back onto the host domain. Left other assets on asset domains. Performance was better than ever.

Slide 64

Slide 64 text

HTTP/2?

Slide 65

Slide 65 text

HTTP/2 Will Change Things HTTP/2 brings in new changes. Some will really help performance. Requests get cheaper. Preemptively send assets over the wire. Employ better caching strategies.

Slide 66

Slide 66 text

Multiplexing

Slide 67

Slide 67 text

Multiplexing HTTP/1.1 is like buying a single item at a grocery store, taking it back home, going back to the store for the next item you need, and repeating until your pantry is fully stocked. Multiplexing gives you a shopping cart so you can pick up everything you need in one trip. —cloudflare.com/http2/what-is-http2

Slide 68

Slide 68 text

Multiplexing HTTP requests become cheaper. More requests can be made per TCP connection. Concatenation and spriting become unnecessary! Practically, this means…

Slide 69

Slide 69 text

Better Caching Strategies

Slide 70

Slide 70 text

Better Caching Strategies We can now split CSS into many different files. Split them based on rate-of-change. Only need to invalidate cache for smaller parts of your UI. Send your reset/Normalize.css styles in one file: cache it forever. Send your app styles in another that can change more frequently. Per-page CSS becomes marginally easier.

Slide 71

Slide 71 text

Hardly ever changes. Send as one file and cache for a long time. Changes more frequently. Send as its own file and cache-bust it when needed. Only need this on the video page. Becomes cheap to send as an extra request.

Slide 72

Slide 72 text

Server Push

Slide 73

Slide 73 text

Server Push Oh, you asked for an HTML page? Take this CSS as well—you’re gonna need it!” Send assets to the browser before it’s even asked for them. Remove round trips completely. Like native inlined CSS (in a very roundabout way). “


Slide 74

Slide 74 text

Browser Server 01.css, 02.css 01.css, 02.css URL index.html

Slide 75

Slide 75 text

Browser Server URL index.html,
 01.css, 02.css

Slide 76

Slide 76 text

Server Push No longer waiting for the HTML to request the CSS. We can send the CSS back in anticipation. Saves us so much time—no need to go back to the server!

Slide 77

Slide 77 text

Lessons

Slide 78

Slide 78 text

Lessons CSS is expensive. Optimise your Critical Path. Understand where all your CSS is coming from. Avoid Base64. Don’t use @import. Avoid CDNs/asset domains for CSS.

Slide 79

Slide 79 text

Thank You

Slide 80

Slide 80 text

Thank You Harry Roberts [email protected] @csswizardry