$30 off During Our Annual Pro Sale. View Details »

VelocityConf: Rendering Performance Case Studies

VelocityConf: Rendering Performance Case Studies

Jank-free rendering performance has been shown to positively affect user engagement and user experience in a number large sites, yet remains an area many developers are unaware of how to diagnose or optimize for.

To highlight how widespread rendering is a performance issue, we’re going to walk through case studies of Flickr, Pinterest, Google+, Twitter Bootstrap and more.

Learn about common paint issues in modern sites, caused by fixed-backgrounds, heavy CSS, doing too much in your onscroll handlers, compositing and more. We’ll also look at changes Pinterest made to get up to a 40% improvement in rendering times.

By the end if this session you’ll be equipped with the knowledge to use the performance profiling tools in Chrome DevTools to find and fix rendering issues in your own sites.

To learn more about rendering performance, checkout jankfree.org.

Also, anything on Chrome rendering by Paul Lewis, Paul Irish and Jake Archibald is generally pretty reliable :)

Addy Osmani

November 13, 2013
Tweet

More Decks by Addy Osmani

Other Decks in Programming

Transcript

  1. Our agenda for today... 1. DOM to pixels on the

    screen 2. Rendering performance tooling 3. Real-world case studies Flickr Bootstrap Pitchfork Pinterest Google+
  2. Mobile web performance goals 1. Connectivity - Show above the

    fold content in < 1s - Serve critical path CSS in first 14KB 2. Max of 200ms server response time 3. 60fps scrolling, 60fps transitions 4. Speed index under 1000* * average time visual parts of the page display per WebPageTest
  3. Today we’ll focus on this. 1. Connectivity - Show above

    the fold content in < 1s - Serve critical path CSS in first 14KB 2. Max of 200ms server response time 3. 60fps scrolling, 60fps transitions 4. Speed index under 1000
  4. "In an A/B test, we slowed down scrolling from 60fps

    down to 30fps. Engagement collapsed" ~ Shane O'Sullivan * in their native app, fluctuating between 30 to 45fps. * Consistent 30fps performed second best
  5. "We tested pre-fetching JS in search results, which caused jank

    in our pages. All business metrics got worse" ~ Jonathan Klein
  6. <!DOCTYPE html> <html class="no-js"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <title>MA RESPONSE</title> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="css/main.css"> </head> <body> <section> <h1>HTML wizaaaaard</h1> <p>I am teh HTML masterz.</p> </section> </body> </html> Get a response
  7. <!DOCTYPE html> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title MA RESPONSE</title>

    <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="css/main.css"> </head> HTML wizaaaaard</h1> I am teh HTML masterz.</p> </section> </body> </html> Parse HTML Get a response <html> <head> <title> <link> <body> <section> <h1> <p>
  8. <html> <body> <section> <h1> <img> Styling the DOM section h1:after

    { content: "<333 pseudo elemz" } <h1:after>
  9. html, body { marg: 0; width: 300px; height: 700px; background:

    white; color: white; } body { background: #888; } section { display: block; margin-top:30%; padding-top:60px; width:100%; background:#444; } section h1:after{ content: '<3 pseudo'; height: 40px; margin-top: 10px; display: block; } img { margin: 30px; border-radius: 4px; border: 3px solid white; box-shadow: 0 2px 2px rgba(0,0,0,3); } Layout Laying out the document
  10. DOM to pixels on the screen Recalc styles Calc styles

    that apply to elements Layout Generate geometry for each element Paint Fill pixels for each element into layers (Paint) Composite layers Draw layers out to the screen
  11. Frame budget At 60fps, you have 16.7ms budget for Logic

    processing Compute processing Rendering
  12. Frame budget It’s more like 8-10ms budget because - Browser,

    JS engine, renderer processes - Margin for slower devices like mobile.
  13. Drop-shadows Blurs Linear-gradients Fixed background images Heavy styles can cause

    jank* *Correct as of November, 2013. Likely to change!
  14. Recalculate style triggered when styles are computed or changed. Heavy

    use of JS to rearrange the page (e.g onscroll) is bad
  15. Scrolling Correct as of November, 2013. Watch out for: Unnecessary

    paints: position:fixed overflow:scroll hover effects touch listeners Long paints: Complex CSS Image decodes Large empty layers
  16. Position transform: translate(npx, npx); Scale transform: scale(n); Rotation transform: rotate(ndeg);

    Opacity opacity: 0....1; 4 things a browser can animate cheaply Move all your visual effects to these things. Transition at your own risk. translateZ(0) or translate3D() may be required
  17. Layers & Compositing Hardware compositing uses the GPU to help

    build the page Elements are broken out to a bunch of layers Those layers are uploaded to the GPU as textures The GPU composites those textures together
  18. Useful Settings red shaded rectangles around repainted regions orange borders

    around composited layers yellow border around touch handler listeners
  19. Layer promotion hacks -webkit-transform: translateZ(0); -webkit-transform: translate3d(0,0,0); 1 -webkit-transform: translate3d(0,0,0)

    Use with caution!! Blink/Webkit iOS -webkit-perspective: 1000; -webkit-backface-visibility: hidden; 1 -webkit-transform: translate3d(0,0,0)
  20. The slow way while (i--) { var greenBlockWidth = sizer.offsetWidth;

    ps[i].style.width = greenBlockWidth + 'px'; }
  21. The right way var greenBlockWidth = sizer.offsetWidth; while (i--) {

    ps[i].style.width = greenBlockWidth + 'px'; }
  22. Writes to the DOM invalidate layout Browser wants to wait

    until the end of the current frame to reflow.
  23. For each Y pixels of vertical axis scrolling, move an

    absolutely positioned image in the same direction.
  24. For each Y pixels of vertical axis scrolling, move an

    absolutely positioned image in the same direction. window.onscroll() backgroundPosition marginTop or el
  25. Elements can be promoted to a layer using translateZ() or

    translate3D() Avoid expensive paints Reminder
  26. window.onscroll = function(e) { var parallax = document.getElementById('parallax-background'); parallax.style.transform =

    'translate3d(0px,' + (window.scrollY/2) + 'px, 0px)'; } Optimized parallax example
  27. BS3 much more viable for sites that need to work

    well on under-powered mobile and tablet devices
  28. BS3 much more viable for sites that need to work

    well on under-powered mobile and tablet devices
  29. Sub-optimal position:fixed use causing unnecessarily large repaints Slow scrolling due

    to excessive use of styles (currently) expensive to paint Doing a lot during hover on scroll Main issues
  30. Caveats of translateZ - more layers = more time compositing

    layers - text anti-aliasing requires an opaque background within the layer - triggers Safari positioning bugs inside iframes
  31. Measuring the DOM depends on the layout If previously invalidated,

    this forces synchronous layout (since execution cannot continue until the correct value is obtained). alert(element.offsetHeight); // Layout forced.
  32. G+ reduced synchronous layouts cards.forEach(function(card){ appendHTML(card); measure(card); }); write read

    write read.. cards.forEach(function(card){ appendHTML(card); }); cards.forEach(function(card){ measure(card); }); write write read read.. They reduced them from O(n) to O(1) by refactoring a loop
  33. Forced Synchronous Layouts Timeline shows where your code is causing

    synchronous layouts Remember to scroll down for the second stack trace.
  34. There’s now lots of tooling to improve the responsiveness of

    your UIs. BROWSER SUPPORT CATS HAVE BEEN LISTENING