Upgrade to Pro — share decks privately, control downloads, hide ads and more …

FaCSSt—CSS & Performance

Harry Roberts
January 21, 2016

FaCSSt—CSS & Performance

How CSS can improve (or harm) performance.

Harry Roberts

January 21, 2016
Tweet

More Decks by Harry Roberts

Other Decks in Design

Transcript

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

    View full-size slide

  2. Hello, Barcelona!

    View full-size slide

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

    View full-size slide

  4. CSS Performance

    View full-size slide

  5. What We Know Already

    View full-size slide

  6. 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.

    View full-size slide

  7. The Critical Path

    View full-size slide

  8. 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.

    View full-size slide

  9. 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!

    View full-size slide

  10. 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.

    View full-size slide

  11. 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.

    View full-size slide

  12. CSS Is Your Biggest Performance
    Bottleneck*

    View full-size slide

  13. 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.

    View full-size slide






  14. Test





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

    View full-size slide

  15. But they all
    get downloaded?!

    View full-size slide

  16. tl;dr: Get CSS onto the Client ASAP

    View full-size slide

  17. 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.

    View full-size slide

  18. Things We Should Do

    View full-size slide

  19. The Three Cs.

    View full-size slide

  20. 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.

    View full-size slide

  21. Remove Unused CSS

    View full-size slide

  22. 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.

    View full-size slide

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

    View full-size slide

  24. Inline Critical/Above the Fold CSS

    View full-size slide

  25. 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.

    View full-size slide

  26. Google don’t send any

    separate CSS files.

    View full-size slide

  27. They inline it all.

    View full-size slide

  28. 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.

    View full-size slide

  29. Things We Should Avoid

    View full-size slide

  30. Do Not @import Stylesheets

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  33. 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.

    View full-size slide

  34. 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.

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  37. @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!

    View full-size slide

  38. @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.

    View full-size slide

  39. @import at Sky
    Let me show you something crazy…

    View full-size slide

  40. Wait. What?

    More CSS?!

    View full-size slide

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

    View full-size slide

  42. @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.

    View full-size slide

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

    View full-size slide

  44. Avoid Base64 Encoding

    View full-size slide

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

    View full-size slide

  46. 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.

    View full-size slide

  47. 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.

    View full-size slide

  48. Don’t Use an Asset Domain or CDN

    View full-size slide

  49. 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.

    View full-size slide

  50. 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.

    View full-size slide

  51. 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?

    View full-size slide

  52. 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?!

    View full-size slide

  53. 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.

    View full-size slide

  54. 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.

    View full-size slide

  55. Multiplexing

    View full-size slide

  56. 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

    View full-size slide

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

    View full-size slide

  58. Better Caching Strategies

    View full-size slide

  59. 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.

    View full-size slide




  60. 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.

    View full-size slide

  61. 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).
    “


    View full-size slide

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

    View full-size slide

  63. Browser Server
    URL
    index.html,

    01.css, 02.css

    View full-size slide

  64. 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!

    View full-size slide

  65. 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.

    View full-size slide

  66. Thank You
    Harry Roberts
    [email protected]
    @csswizardry

    View full-size slide